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

namespace SolutionCS
{
    class Program
    {
        class COORD
        {
            public COORD(int x, int y, int dist)
            {
                this.x = x;
                this.y = y;
                distance = dist;
            }

            public int x;
            public int y;
            public int distance;
        }

        static void Main(string[] args)
        {
            string[] s = Console.ReadLine().Split(' ');
            int H = int.Parse(s[0]);
            int W = int.Parse(s[1]);

            int[,] field = new int[W, H];

            for (int y = 0; y < H; y++)
            {
                string s0 = Console.ReadLine();

                for (int x = 0; x < W; x++)
                {
                    if(s0[x] == '#')
                    {
                        field[x, y] = 1;
                    }
                    else
                    {
                        field[x, y] = 0;
                    }
                }
            }

            int startX = -1;
            int startY = -1;
            for (int y = 0; y < H; y++)
            {
                for (int x = 0; x < W; x++)
                {
                    if(0 == field[x,y])
                    {
                        startX = x;
                        startY = y;
                        break;
                    }
                }

                if(startX >= 0 && startY >= 0)
                {
                    break;
                }
            }

            if(startX < 0 || startY < 0)
            {
                Console.WriteLine("0");
                return;
            }

            int maxDist = 0;
            int[,] dist = new int[W, H];

            Queue<COORD> q = new Queue<COORD>();
            q.Enqueue(new COORD(startX, startY, 1));
            dist[startX, startY] = 1;

            while (q.Count > 0)
            {
                COORD c = q.Dequeue();

                maxDist = Math.Max(maxDist, c.distance);

                int newDistance = c.distance + 1;

                if(SetDistance(c.x + 1, c.y, newDistance, field, dist))
                {
                    q.Enqueue(new COORD(c.x + 1, c.y, newDistance));
                }
                if (SetDistance(c.x - 1, c.y, newDistance, field, dist))
                {
                    q.Enqueue(new COORD(c.x - 1, c.y, newDistance));
                }
                if (SetDistance(c.x, c.y + 1, newDistance, field, dist))
                {
                    q.Enqueue(new COORD(c.x, c.y + 1, newDistance));
                }
                if (SetDistance(c.x, c.y - 1, newDistance, field, dist))
                {
                    q.Enqueue(new COORD(c.x, c.y - 1, newDistance));
                }
            }

            startX = -1;
            startY = -1;
            for (int y = 0; y < H; y++)
            {
                for (int x = 0; x < W; x++)
                {
                    if (maxDist == dist[x, y])
                    {
                        startX = x;
                        startY = y;
                        break;
                    }
                }

                if (startX >= 0 && startY >= 0)
                {
                    break;
                }
            }

            int[,] dist2 = new int[W, H];

            Queue<COORD> q2 = new Queue<COORD>();
            q2.Enqueue(new COORD(startX, startY, 1));
            dist2[startX, startY] = 1;
            maxDist = 0;

            while (q2.Count > 0)
            {
                COORD c = q2.Dequeue();

                maxDist = Math.Max(maxDist, c.distance);

                int newDistance = c.distance + 1;

                if (SetDistance(c.x + 1, c.y, newDistance, field, dist2))
                {
                    q2.Enqueue(new COORD(c.x + 1, c.y, newDistance));
                }
                if (SetDistance(c.x - 1, c.y, newDistance, field, dist2))
                {
                    q2.Enqueue(new COORD(c.x - 1, c.y, newDistance));
                }
                if (SetDistance(c.x, c.y + 1, newDistance, field, dist2))
                {
                    q2.Enqueue(new COORD(c.x, c.y + 1, newDistance));
                }
                if (SetDistance(c.x, c.y - 1, newDistance, field, dist2))
                {
                    q2.Enqueue(new COORD(c.x, c.y - 1, newDistance));
                }
            }

            Console.WriteLine("{0}", maxDist - 1);
        }

        static bool SetDistance(int x, int y, int distance, int[,] f, int[,] d)
        {
            if(x < 0 || y < 0 || x >= f.GetLength(0) || y >= f.GetLength(1))
            {
                return false;
            }

            if(f[x,y] != 0)
            {
                return false;
            }

            if(d[x,y] != 0)
            {
                return false;
            }

            d[x, y] = distance;

            return true;
        }
    }
}
