# ＢＦＳ
# グリッド
# スタート位置 と ゴール位置 の全パターンの経路を探索 → 最長経路
 # ※ 要削除

from collections import deque

h,w = map(int,input().split())
pic = [list(input()) for i in range(h)]
visited = [[0 for i in range(w)] for i in range(h)] # 各位置までに必要な移動回数記録用メモ
queue = deque([]) # 探索候補のキューを dequeオブジェクトとして初期化
print(h,w) # ※
print(pic) # ※
print(visited) # ※

ans = 0

for i in range(h):
    for j in range(w):
        if pic[i][j] == '.': # スタート位置を決めて...
            visited[i][j] = 1 # 訪問 '1' を記録して..._後で '1' 引く
            queue.append([i,j]) # 探索候補に積む

            dy_dx = [[1,0],[0,1],[-1,0],[0,-1]] # 探索子、4方向

            while queue:
                now = queue.popleft() # 現在地を探索候補から popleft する
                for k in range(4): # 現在地から4方向の探索先を生成
                    y = now[0]+dy_dx[k][0] # 探索子を使う
                    x = now[1]+dy_dx[k][1] # 〃
                    if 0 <= y < h and 0 <= x < w: # 探索の条件4つを2行で確認
                        if pic[y][x] != '#' and visited[y][x] == 0:
                            visited[y][x] = visited[now[0]][now[1]] + 1 # 移動回数のカウント_ひとつ前の回数に'1'を足す
                            queue.append([y,x]) # 現在地を探索候補に積む
        print(visited) # ※ 
        for l in range(h): # 一探索ごとに'max'を比較 → 記録する
            for m in range(w):
                ans = max(ans,visited[l][m])

        queue = deque([]) # 探索候補のキューを初期化
        visited = [[0 for i in range(w)] for i in range(h)] # 移動回数記録用メモを初期化

print(ans-1)