import copy
from collections import deque
from itertools import combinations

H, W = map(int, input().split())
field_s = []

# フィールドを作る
for h in range(H + 2):
    field_s.append(["#"] * (W + 2))
    if 1 <= h <= (H):
        field_s[h][1:-1] = list(map(str, input().rstrip()))

#　動き方のセットを準備
moves = [[1, 0], [-1, 0], [0, 1], [0, -1]]

# スタートとゴールの座標の組み合わせを作成
sg = []
for y in range(H + 2):
    for x in range(W + 2):
        if field_s[y][x] == ".":
            sg.append([y, x])

# 答え
ans = 0

# スタートとゴールの座標を組み合わせてぐるぐる
for s, g in list(combinations(sg, 2)):

    # startとgoalの座標が同じならスキップ
    if s == g:
        continue

    # fieldの初期化
    field = copy.deepcopy(field_s)

    # startをキューに追加
    que = deque([s])

    # startの距離は0に
    field[s[0]][s[1]] = 0

    # キューに何かがある限り探索を続ける
    while que:
        c = que.popleft()

        # 今の距離
        dist = field[c[0]][c[1]]

        # 動いた先が「.」なら、距離を記録してキューに追加
        for m in moves:
            my = c[0] + m[0]
            mx = c[1] + m[1]

            if field[my][mx] == ".":
                field[my][mx] = dist + 1
                que.append([my, mx])
            else:
                continue

            # もしゴールに到達していたらansを差し替えてbreak
            if [my, mx] == g:
                ans = max(ans, field[my][mx])
                break

print(ans)