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

namespace BFS2
{
    class Program
    {
        static void Main(string[] args)
        {
            int H = 0;
            int W = 0;
            char[][] map = null;
            int[] startPos = { 0, 0, 0 };
            int[] goalPos = { 2, 2 };

            map = ReadMap(out H,out W);

            List<int[]> road = new List<int[]>();
            for (int i = 0; i < H; i++)
            {
                for (int j = 0; j < W; j++)
                {
                    if (map[i][j] == '.') road.Add(new int[2] { i, j });
                }
            }

            Queue<int[]> queue = new Queue<int[]>();
            List<int[]> done = new List<int[]>();
            queue.Enqueue(startPos);
            done.Add(startPos);
            int[][] deltas = { new int[2] { 0, 1 }, new int[2] { 1, 0 }, new int[2] { 0, -1 }, new int[2] { -1, 0 } };

            int[] currentPos = null;


            int maxCount = 0;

            for (int i = 0; i < road.Count-1; i++)
            {
                for (int j = i+1; j < road.Count; j++)
                {
                    startPos = new int[3] { road[i][0],road[i][1],0 };
                    goalPos = road[j];
                    queue = new Queue<int[]>();
                    queue.Enqueue(startPos);
                    done = new List<int[]>();
                    while (true)
                    {
                        currentPos = queue.Dequeue();
                        //Console.WriteLine(currentPos[0] + "," + currentPos[1]);
                        //Console.ReadLine();

                        //ゴールなら
                        if (currentPos[0] == goalPos[0] && currentPos[1] == goalPos[1])
                        {
                            break;
                        }

                        //通れるなら
                        if (map[currentPos[0]][currentPos[1]] == '.')
                        {
                            foreach (var delta in deltas)
                            {
                                int[] aroundPos = new int[] { currentPos[0] + delta[0], currentPos[1] + delta[1], currentPos[2] + 1 };
                                if (aroundPos[0] >= 0 && aroundPos[0] < H && aroundPos[1] >= 0 && aroundPos[1] < W)
                                {
                                    if (!done.Any(pos => pos[0] == aroundPos[0] && pos[1] == aroundPos[1]))
                                    {
                                        queue.Enqueue(aroundPos);
                                        done.Add(aroundPos);
                                    }
                                }
                            }
                        }
                    }
                    maxCount = Math.Max(maxCount, currentPos[2]);

                }

            }



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

        static private char[][] ReadMap(out int H,out int W)
        {
            string[] HW = Console.ReadLine().Split(' ');
            H = int.Parse(HW[0]);
            W = int.Parse(HW[1]);

            char[][] map = new char[H][];
            for (int i = 0; i < H; i++)
            {
                map[i] = Console.ReadLine().ToArray();
            }
            return map;
        }
    }
}
