using System;
using System.Linq;
using System.Collections.Generic;
using static System.Console;
using System.Text;
using System.IO;
using static System.Math;
namespace AtCoder
{
    class Program
    {
        static public long[] Sarray() { return ReadLine().Split().Select(long.Parse).ToArray(); }
        static public List<long> Slist() { return ReadLine().Split().Select(long.Parse).ToList(); }

        static long Mod = (long)1e9 + 7;
        static long[] dirw = new long[] { -1, 0, 1, 0 };
        static long[] dirh = new long[] { 0, 1, 0, -1 };
        static string[] Sij;

        static void Main(string[] args)
        {
            //SetOut(new StreamWriter(OpenStandardOutput()) { AutoFlush = false });
            var HW = Sarray();
            var H = HW[0];
            var W = HW[1];
            Sij = new string[H + 2];
            Sij[0] = new string('#', (int)W + 2);
            for (var i = 1; i <= H; ++i)
                Sij[i] = "#" + ReadLine() + "#";
            Sij[H + 1] = Sij[0];
            var max = 0L;
            for (var h = 1L; h <= H; ++h)
            {
                for (var w = 1L; w < W; ++w)
                {
                    if (Sij[h][(int)w] == '#') continue;
                    var cmp = new bool[H + 2, W + 2];
                    var q = new Queue<Tuple<long, long, long>>();//h,w,dst
                    q.Enqueue(Tuple.Create(h, w, 0L));
                    while (q.Count != 0)
                    {
                        var npos = q.Dequeue();
                        var nowh = npos.Item1;
                        var noww = npos.Item2;
                        var nowdst = npos.Item3;
                        if (cmp[nowh, noww]) continue;
                        cmp[npos.Item1, npos.Item2] = true;
                        if (Sij[nowh][(int)noww] == '#') continue;
                        max = Max(max, nowdst);
                        for (var i = 0; i < 4; ++i)
                        {
                            var nexth = nowh + dirh[i];
                            var nextw = noww+ dirw[i];
                            q.Enqueue(Tuple.Create(nexth, nextw, nowdst + 1));
                        }
                    }
                }
            }
            WriteLine(max);
            //Out.Flush();
        }
    }
}
