H,W = map(int,input().split())
Maze=[]
for h in range(H):
    Maze.append(input())
# startをすべてのマスについてまわして，BFSをすればよい．
# queueを使うと，常に最小の要素が取り出せるので，うまくいく．
import queue
max_length = 0
for i in range(H*W):
    height = int(i/W)
    width = int(i%W)
    if Maze[height][width]=='.':
        Maze_distance = [[-1 for _ in range(W)] for __ in range(H)]
        # lambda update x: lambda４季には名前をつけないほうがいいらしい．多分名前をつけてもいいけどpython的には
        # 無名関数に名前つけるくらいだったらdef使って定義しとけよということらしい
        q = queue.Queue()
        q.put([height,width])
        Maze_distance[height][width] = 0
        while not q.empty():
            pos = q.get()
            if pos[0]+1 <= H-1 and Maze_distance[pos[0]+1][pos[1]]==-1 and Maze[pos[0]+1][pos[1]] == '.':
                Maze_distance[pos[0]+1][pos[1]] = Maze_distance[pos[0]][pos[1]] + 1
                q.put([pos[0]+1, pos[1]])
            if pos[0]-1 >= 0 and Maze_distance[pos[0]-1][pos[1]] == -1 and Maze[pos[0]-1][pos[1]] == '.':
                Maze_distance[pos[0]-1][pos[1]] = Maze_distance[pos[0]][pos[1]] + 1
                q.put([pos[0]-1, pos[1]])
            if pos[1]+1 <= W-1 and Maze_distance[pos[0]][pos[1]+1] == -1 and Maze[pos[0]][pos[1]+1] == '.':
                Maze_distance[pos[0]][pos[1]+1] = Maze_distance[pos[0]][pos[1]] + 1
                q.put([pos[0], pos[1]+1])
            if pos[1]-1 >= 0 and Maze_distance[pos[0]][pos[1]-1] == -1 and Maze[pos[0]][pos[1]-1] == '.':
                Maze_distance[pos[0]][pos[1]-1] = Maze_distance[pos[0]][pos[1]] + 1
                q.put([pos[0], pos[1]-1])
        # 2次元リストの最大をとるにはmaxを２回取らないといけいない．n次元に対してmaxをn回つかう．
        max_length = max(max_length,max(max(Maze_distance)))

print(max_length)






