using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using static System.Console;

class Program
{
    static void Main(string[] args)
    {
        var HW = ReadLine().Split(' ').Select(s => int.Parse(s)).ToArray();
        var (H, W) = (HW[0], HW[1]);
        var S = new bool[H][];
        for (int i = 0; i < H; i++)
            S[i] = ReadLine().Select(c => (c == '.')).ToArray();

        int BFS((int, int) start, (int, int) end)
        {
            var visited = new int[H, W];
            for (int i = 0; i < H; i++)
                for (int j = 0; j < W; j++)
                    visited[i, j] = -1;

            void Visit((int, int) v, int step) => visited[v.Item1, v.Item2] = step;
            bool Visited((int, int) v) => visited[v.Item1, v.Item2] != -1;
            int GetSteps((int, int) v) => visited[v.Item1, v.Item2];

            IEnumerable<(int, int)> GetNextV((int, int) v)
            {
                var (y, x) = v;

                if ((0 < x) && S[y][x - 1])
                    yield return (y, x - 1);
                if ((0 < y) && S[y - 1][x])
                    yield return (y - 1, x);
                if ((x < W - 1) && S[y][x + 1])
                    yield return (y, x + 1);
                if ((y < H - 1) && S[y + 1][x])
                    yield return (y + 1, x);
            }

            var q = new Queue<(int, int)>();

            Visit(start, 0);
            q.Enqueue(start);

            while(0 < q.Count)
            {
                var v = q.Dequeue();
                var steps = GetSteps(v);

                if (v == end)
                    return steps;

                foreach (var nextV in GetNextV(v))
                {
                    if(!Visited(nextV))
                    {
                        Visit(nextV, steps + 1);
                        q.Enqueue(nextV);
                    }
                }
            }

            return int.MaxValue;
        }

        var ans = -1;

        for (int y1 = 0; y1 < H; y1++)
        {
            for (int x1 = 0; x1 < W; x1++)
            {
                if (S[y1][x1])
                {
                    for (int y2 = y1 + 1; y2 < H; y2++)
                    {
                        for (int x2 = x1 + 1; x2 < W; x2++)
                        {
                            if (S[y2][x2])
                            {
                                ans = Math.Max(ans, BFS((y1, x1), (y2, x2)));
                            }
                        }
                    }
                }
            }
        }

        WriteLine(ans);
    }
}
