using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
class Program
{
    static void Main(string[] args)
    {
            // 入力
            string[] sS = System.Console.ReadLine().Trim().Split(' ');
            int iH = int.Parse(sS[0]);
            int iW = int.Parse(sS[1]);
            List<List<int>> lstMez = new List<List<int>>();
            for (int i = 0; i < iH; i++)
            {
                List<int> lstRow = new List<int>();
                for (int j = 0; j < iW; j++) { lstRow.Add(-1); }
                lstMez.Add(lstRow);
            }
            for (int i = 0; i < iH; i++)
            {
                string s2 = System.Console.ReadLine().Trim();
                s2 = s2.Replace("#", "1").Replace(".", "0");
                for (int j = 0; j < s2.Length; j++) { lstMez[i][j] = - int.Parse(s2.Substring(j, 1)) - 1; }
            }

            System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
            sw.Start();

            // 解析
            //DispDebug(lstMez);
            List<int> lstOut = new List<int>();
            for (int i = 0; i < lstMez.Count; i++)
            {
                for (int j = 0; j < lstMez[i].Count; j++)
                {
                    GetSearchRoute(lstOut, lstMez, i, j);
                }
            }
            lstOut.Sort();
            lstOut.Reverse();

            // 出力
            System.Console.WriteLine("{0}", lstOut[0].ToString().Trim());

            sw.Stop();
#if DEBUG
            Console.WriteLine();
            Console.WriteLine("{0}", sw.Elapsed.ToString());
            Console.WriteLine("続行するには何かキーを押してください．．．");
            Console.ReadKey();
#endif
    }

        // debug
        private static void DispDebug(List<List<int>> lstMez)
        {
            Console.WriteLine();
            for (int i = 0; i < lstMez.Count; i++)
            {
                string sOut = "";
                for (int j = 0; j < lstMez[i].Count; j++)
                {
                    sOut += lstMez[i][j].ToString();
                }
                Console.WriteLine("{0}", sOut.ToString().Trim());
            }
        }

        // 迷路を指定点から走破 一度走破した箇所に到達移動距離をintで書込 始点を0 未走破点は-1 壁は-2とする
        private static void GetSearchRoute(List<int> lstOut, List<List<int>> lstMez, int iY, int iX)
        {
            List<List<int>> lstDst = new List<List<int>>();
            CopyList(lstMez, lstDst);
            int iNow = 0;                                                       // 現在探索位置
            int iYmx = lstDst.Count;                                            // H最大値
            int iXmx = lstDst[0].Count;                                         // W最大値
            if (lstDst[iY][iX] == - 1) { lstDst[iY][iX] = 0; }                  // Start
            while (true)
            {
                Boolean bNext = false;
                for (int i = 0; i < lstDst.Count; i++)
                {
                    for (int j = 0; j < lstDst[i].Count; j++)
                    {
                        if (lstDst[i][j] == iNow)                               // 探査位置
                        {
                            if (i - 1 >= 000 && lstDst[i - 1][j + 0] == -1) { lstDst[i - 1][j + 0] = iNow + 1; bNext = true; }    // 次位置 上 移動距離で上書
                            if (i + 1 < iYmx && lstDst[i + 1][j + 0] == -1) { lstDst[i + 1][j + 0] = iNow + 1; bNext = true; }    // 次位置 下 移動距離で上書
                            if (j - 1 >= 000 && lstDst[i + 0][j - 1] == -1) { lstDst[i + 0][j - 1] = iNow + 1; bNext = true; }    // 次位置 左 移動距離で上書
                            if (j + 1 < iXmx && lstDst[i + 0][j + 1] == -1) { lstDst[i + 0][j + 1] = iNow + 1; bNext = true; }    // 次位置 右 移動距離で上書
                        }
                    }
                }
                if (!bNext) { break; }
                iNow += 1;
            }
            lstOut.Add(iNow);
            //DispDebug(lstDst);
        }

        // List<List<>> のコピー
        private static void CopyList(List<List<int>> lstSrc, List<List<int>> lstDst)
        {
            for (int i = 0; i < lstSrc.Count; i++)
            {
                List<int> lstRow = new List<int>();
                lstRow.AddRange(lstSrc[i]);
                lstDst.Add(lstRow);
            }
        }

}


Measured memory_bytes: 15572