"""
蟻本p37にスタート・ゴールの座標が決まっている場合のコードがある
この問題ではスタート・ゴールの座標が決まっていないので以下のように改変する
"""
h, w = list(map(int, input().split()))
field = [input() for _ in range(h)]

INF = 10**8
d = [[0]*w for i in range(h)] # 各点までの最短距離の配列
dx = [1,0,-1,0]; dy = [0,1,0,-1] # 移動4方向のベクトル

# (sx, sy)から(gx, gy)への最短距離を求める
# たどり着けないとINF
import queue

def bfs(sx, sy, gx, gy):
    que = queue.Queue()
    # 全ての点をINFで初期化
    for i in range(h):
        for j in range(w):
            d[i][j] = INF
    # スタート地点をキューに入れ、その点の距離を0にする
    que.put([sx, sy])
    d[sx][sy] = 0
    
    # キューが空になるまでループ
    while que.qsize():
        # キューの先頭を取り出す
        p = que.get()
        # 取り出してきた状態がゴールなら探索を辞める
        if p[0] == gx and p[1] == gy: break
        
        # 移動4方向をループ
        for i in range(4):
            # 移動した後の点を(nx, ny)とする
            nx = p[0] + dx[i]; ny = p[1] + dy[i]

            # 移動が可能かの判定と既に訪れたことがあるかの判定(d[nx][ny] != INF なら訪れたことあり)
            if 0 <= nx and nx < h and 0 <= ny and ny < w and field[nx][ny] != '#' and d[nx][ny] == INF:
                # 移動できるならキューに入れ、その点の距離をpからの距離+1で確定する
                que.put([nx, ny])
                d[nx][ny] = d[p[0]][p[1]] + 1
            
    return d[gx][gy]

# この問題ではスタート・ゴールの位置が決まっていないので取り得る位置の組み合わせを列挙する
from itertools import combinations

sg_candidates = []
for i in range(h):
    for j in range(w):
        if field[i][j] == '.':
            sg_candidates.append((i,j))
sg_pairs = combinations(sg_candidates, 2)

ans = 0
for s,g in sg_pairs:
    res = bfs(s[0],s[1],g[0],g[1])
    ans = max(res, ans)

print(ans)