using System;
using System.Linq;
using System.Collections.Generic;

namespace ConsoleApp2
{
    public class Program
    {
        public static void Main(string[] args)
        {
            int[] HW = Read(Console.ReadLine());
            int H = HW[0];
            int W = HW[1];

            int[][] map = new int[H][];

            List<int[]> road = new List<int[]>();

            for (int i = 0; i < H; i++)
            {
                Char[] r = Console.ReadLine().ToArray();
                int[] ri = new int[W];
                for (int j = 0; j < W; j++)
                {
                    if (r[j] == '.')
                    {
                        ri[j] = 1;
                        road.Add(new int[2] { i, j });
                    }
                    else
                    {
                        ri[j] = 2;
                    }
                }
                map[i] = ri;
            }

            int max = 0;

            for (int s = 0; s < road.Count-1; s++)
            {
                for (int g = s+1; g < road.Count; g++)
                {
                    BFSClass bfs = new BFSClass(map);
                    int count = bfs.BFS(road[s], road[g]);
                    max = Math.Max(count,max);
                    //Console.WriteLine(count);
                }
            }



            Console.WriteLine(max);
            Console.ReadLine();
        }

        public class BFSClass
        {
            /// <summary>
            /// 1...道、2...障害物(0は未知)
            /// </summary>
            /// <param name="map"></param>
            public BFSClass(int[][] map)
            {
                Map = map;
            }

            private class TileFrom
            {
                public TileFrom(int[] thisTile, int[] from)
                {
                    ThisTile = thisTile;
                    From = from;
                }
                public int[] ThisTile { get; }
                public int[] From { get; }
            }

            public int[][] Map { get; }

            //調べる予定の位置を入れる
            Queue<int[]> search = new Queue<int[]>();

            //調べ終わった位置
            List<TileFrom> done = new List<TileFrom>();

            /// <summary>
            /// 
            /// </summary>
            /// <param name="map"></param>
            public int BFS(int[] startPos, int[] goalPos)
            {
                done.Add(new TileFrom(startPos, null));

                //現在の位置
                int[] currentPos = startPos;

                return StartBFS(0,currentPos, goalPos);
                //if (StartBFS(currentPos, goalPos)) Console.WriteLine("ゴール");
                //else Console.WriteLine("経路が見つかりませんでした");
            }

            /// <summary>
            /// 終わったらtrue
            /// </summary>
            /// <param name="currentPos"></param>
            /// <param name="goalPos"></param>
            private int StartBFS(int currentCount,int[] currentPos, int[] goalPos)
            {
                //Console.WriteLine("現在位置は[" + currentPos[0] + "," + currentPos[1] + "]");
                //Console.WriteLine(currentCount);
                if (currentPos.SequenceEqual(goalPos))
                {
                    return currentCount;
                    //return FindRoot(goalPos);
                    //return true;
                }

                List<int[]> around = GetAroundTile(currentPos);
                foreach (var item in around)
                {
                    if (!done.Exists(i => i.ThisTile.SequenceEqual(item)))
                    {
                        done.Add(new TileFrom(item, currentPos));
                        search.Enqueue(item);

                    }
                }

                while (search.Count > 0)
                {
                    var item = search.Dequeue();
                    if (Map[item[0]][item[1]] == 1)
                    {
                        //if (StartBFS(item, goalPos)) return true;
                        return StartBFS(currentCount+1,item, goalPos);
                    }
                }

                return -1;
            }

            private List<int[]> GetAroundTile(int[] pos)
            {
                List<int[]> ans = new List<int[]>();
                int[][] deltas = {  new int[2] { 0, 1 },
                                new int[2] { 1, 0 },
                                new int[2] { 0, -1 },
                                new int[2] { -1, 0 } };

                foreach (var delta in deltas)
                {
                    int[] newPos = { pos[0] + delta[0], pos[1] + delta[1] };
                    if (OnMap(newPos)) ans.Add(newPos);
                }
                return ans;
            }

            private bool OnMap(int[] pos)
            {
                if (pos[0] >= 0 && pos[0] < Map.Length)
                {
                    if (pos[1] >= 0 && pos[1] < Map[0].Length)
                    {
                        return true;
                    }
                }
                return false;
            }

            private int FindRoot(int[] goalPos)
            {
                Stack<int[]> root = new Stack<int[]>();
                root.Push(goalPos);

                TileFrom f = done.Find(i => i.ThisTile[0] == goalPos[0] && i.ThisTile[1] == goalPos[1]);
                while (true)
                {
                    root.Push(f.From);
                   // Console.WriteLine("[" + f.ThisTile[0] + "," + f.ThisTile[1] + "]" + "から[" + f.From[0] + "," + f.From[1] + "]");

                    TileFrom test = done.Find(i => i.ThisTile[0] == f.From[0] && i.ThisTile[1] == f.From[1]);

                    if (test.From == null) break;
                    f = test;
                }
                //while (root.Count > 0)
                //{
                //    int[] r = root.Pop();
                //    Console.WriteLine("[" + r[0] + "," + r[1] + "]");
                //}
                return root.Count - 1;
            }
        }

        private static int[] Read(string input)
        {
            string[] strings = input.Split(' ');
            int num = strings.Length;
            int[] ints = new int[num];
            for (int i = 0; i < num; i++)
            {
                ints[i] = int.Parse(strings[i]);
            }
            
            return ints;
        }


    }


}
