H, W = map(int, input().split())
S    = [None] * H # S[h][w]
for h in range(H):
    S[h] = list(input())

# find temporary start
is_break = False
for h in range(H):
    for w in range(W):
        if S[h][w] == '.':
            is_break = True
            break
    if is_break:
        break

h_init, w_init = h, w

# find goal
STEPs                 = [[-1 for w in range(W)] for h in range(H)] # STEPs[x][y]
STEPs[h_init][w_init] = 0
max_STEP              = 0

Q = [(h_init, w_init)]

while len(Q) > 0:
    Q_new = []
    for q in Q:
        step     = STEPs[q[0]][q[1]]
        max_STEP = max(max_STEP, step)
        for h, w in [(q[0]-1, q[1]), (q[0], q[1]-1), (q[0], q[1]+1), (q[0]+1, q[1])]:
            if (h < 0 or w < 0) or (h >= H or w >= W) or (STEPs[h][w] != -1) or S[h][w] != '.':
                continue
            else:
                STEPs[h][w] = step+1
                Q_new.append((h, w))
    Q = Q_new

Q_start = []
for h in range(H):
    for w in range(W):
        if STEPs[h][w] == max_STEP:
            Q_start.append((h, w))

answer = 0

# find start
for h_goal, w_goal in Q_start:
    STEPs                 = [[-1 for w in range(W)] for h in range(H)] # STEPs[x][y]
    STEPs[h_goal][w_goal] = 0
    max_STEP              = 0

    Q = [(h_goal, w_goal)]
    while len(Q) > 0:
        Q_new = []
        for q in Q:
            step     = STEPs[q[0]][q[1]]
            max_STEP = max(max_STEP, step)
            for h, w in [(q[0]-1, q[1]), (q[0], q[1]-1), (q[0], q[1]+1), (q[0]+1, q[1])]:
                if (h < 0 or w < 0) or (h >= H or w >= W) or (STEPs[h][w] != -1) or S[h][w] != '.':
                    continue
                else:
                    STEPs[h][w] = step+1
                    Q_new.append((h, w))
        Q = Q_new
    answer = max(answer, max_STEP)

print(answer)
