using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp15
{
    class Class103
    {
        static int[] dx = new int[4] { 1, 0, -1, 0 };
        static int[] dy = new int[4] { 0, 1, 0, -1 };
        static char[,] map = new char[20, 20];
        static bool[,] Frag = new bool[20, 20];
        static int[] HW = new int[2];
        static void Main()
        {
            HW = Console.ReadLine().Split().Select(int.Parse).ToArray();
            for(int i = 0; i < HW[0]; i++)
            {
                var r = Console.ReadLine();
                for (int j = 0; j < HW[1]; j++)
                    map[i, j] = r[j];
            }
            int ans = 0;
            for(int i = 0; i < HW[0]; i++)
            {
                for(int j = 0; j < HW[1]; j++)
                {
                    if (map[i, j] != '#'&&!Frag[i,j])
                        ans = Math.Max(ans, BFS(i, j));
                }
            }
            Console.WriteLine(ans);
        }

        static int BFS(int y,int x)
        {
            Queue<Tuple<int, int, int>> que = new Queue<Tuple<int, int, int>>();
            que.Enqueue(Tuple.Create(y, x, 0));
            bool[,] frag = new bool[20,20];
            Tuple<int, int, int> start = new Tuple<int, int, int>(y, x, 0);
            while (que.Count > 0)
            {
                var p = que.Dequeue();
                frag[p.Item1, p.Item2] = true;
                for(int i = 0; i < 4; i++)
                {
                    var t = Tuple.Create(p.Item1 + dy[i], p.Item2 + dx[i], p.Item3 + 1);
                    if(0<=t.Item1&&t.Item1<HW[0]&&0<=t.Item2&&t.Item2<HW[1])
                        if(map[t.Item1,t.Item2] != '#' && !frag[t.Item1, t.Item2])
                        {
                            que.Enqueue(t);
                            
                        }
                }
                if (que.Count == 0) start = p;
            }
            que.Enqueue(Tuple.Create(start.Item1,start.Item2,0));
            frag = new bool[20, 20];

            int ret = -1;
            while (que.Count > 0)
            {
                var p = que.Dequeue();
                frag[p.Item1, p.Item2] = true;
                Frag[p.Item1, p.Item2] = true;
                for (int i = 0; i < 4; i++)
                {
                    var t = Tuple.Create(p.Item1 + dy[i], p.Item2 + dx[i], p.Item3 + 1);
                    if (0 <= t.Item1 && t.Item1 < HW[0] && 0 <= t.Item2 && t.Item2 < HW[1])
                        if (map[t.Item1, t.Item2] != '#' && !frag[t.Item1, t.Item2])
                        {
                            que.Enqueue(t);

                        }
                }
                if (que.Count == 0) ret = p.Item3;
            }
            return ret;
        }
    }
}
