using System;
using System.Linq;
using System.Collections.Generic;
class Program
{
    
	static void Main(string[] args)
	{
	    var maze = new Maze();
		string[] input = Console.ReadLine().Split(' ');
		maze.r = int.Parse(input[0]);
		maze.c = int.Parse(input[1]);
		/*input = Console.ReadLine().Split(' ');
		int sy = int.Parse(input[0])-1;
		int sx = int.Parse(input[1])-1;
		input = Console.ReadLine().Split(' ');
		int gy = int.Parse(input[0])-1;
		int gx = int.Parse(input[1])-1;*/
        maze.cells = new Cell[maze.r][];
        for(var i=0;i<maze.r;i++)
        {
            maze.cells[i] = Cell.GetCells(Console.ReadLine().ToCharArray(), i+1);
        }
        //maze.st=maze.cells[0][0];
        //maze.gl=maze.cells[gy][gx];
        int max=0;
        for(var i=0;i<maze.r;i++)
        {
            for(var j=0;j<maze.c;j++){
                maze.st=maze.cells[i][j];
                maze.bfs();
                if(max<maze.max)max=maze.max;
                maze.reset();
            }
        }
        Console.WriteLine(max);
	}
}

    public class Cell
    {
        public int X { get; set; }
        public int Y { get; set; }
        public string CellType { get; set; }
        public int Step { get; set; }

        public static Cell[] GetCells(char[] row, int y)
        {
            var cells = Enumerable.Range(0, row.Length).Select(x => new Cell
            {
                X = x+1,
                Y = y,
                CellType = Convert.ToString(row[x]),
                Step = -1,
            });
            return cells.ToArray();
        }
    }
    
    public class Maze{
        public Cell[][] cells;
        public int r;
        public int c;
        public Cell st;
        public Cell gl;
        public int max;
        
        public Maze(){
            r=0;
            c=0;
            max=0;
        }
        
        public void reset(){
            for(var i=0;i<cells.Length;i++){
                for(var j=0;j<cells[i].Length;j++){
                    cells[i][j].Step=-1;
                }
            }
        }
        
    public void bfs(){
        var queue =new Queue<Cell>();
        st.Step=0;
        queue.Enqueue(st);
        while(queue.Count>0){
            var cell =queue.Dequeue();
                var nextTarget = new Tuple<int, int>[]
                {
                    new Tuple<int, int>(cell.Y-1, cell.X),
                    new Tuple<int, int>(cell.Y+1, cell.X),
                    new Tuple<int, int>(cell.Y, cell.X-1),
                    new Tuple<int, int>(cell.Y, cell.X+1),
                }.Where(x => x.Item1 >= 1 && x.Item1 <= r && x.Item2 >= 1 && x.Item2 <= c)
                .Select(x => cells[x.Item1-1][x.Item2-1])
                .Where(x => x.CellType == "." && x.Step < 0);//未訪問＋通れるマス

                foreach(var nextCell in nextTarget)
                {
                    nextCell.Step = cell.Step + 1;
                    queue.Enqueue(nextCell);
                    
                    if(max<nextCell.Step)max=nextCell.Step;

                    if(gl!=null && nextCell.Y == gl.Y && nextCell.X == gl.X)
                    {
                        Console.WriteLine(nextCell.Step);
                        return;
                    }
                }
        }
    }
    }