#%%
def dfs_deep_measure(st, h, w, reach):
    #木の深さを、各ノードに対して求める。
    deep = [[500] * w for _ in range(h)]
    check = [[0] * w for _ in range(h)]
    stack = [st]
    st_i, st_j = st[0], st[1]
    check[st_i][st_j] = 1
    deep[st_i][st_j] = 0
    while len(stack) > 0:
        tmp = stack.pop(0)
        tmp_i, tmp_j = tmp[0], tmp[1]
        tmp_list = reach[tmp_i][tmp_j]
        for i in range(len(tmp_list)):
            t_i, t_j = tmp_list[i][0], tmp_list[i][1]
            if check[t_i][t_j] != 1:
                stack.append((t_i, t_j))
                check[t_i][t_j] = 1
                for j in range(len(reach[t_i][t_j])):
                    ii = (reach[t_i][t_j])[j][0]
                    jj = (reach[t_i][t_j])[j][1]
                    deep[t_i][t_j] = min(deep[ii][jj]+1, deep[t_i][t_j])
    return deep


h, w = map(int, input().split())
s = [list(input()) for _ in range(h)]

move = [(0, 1), (0, -1), (1, 0), (-1, 0)]
reach = [[[] for _ in range(w)] for _ in range(h)]

for i in range(h):
    for j in range(w):
        for k in range(len(move)):
            if s[i][j] == '#':
                break
            x = i + move[k][0]
            y = j + move[k][1]
            if 0 <= x <= h-1 and 0 <= y <= w-1:
                if s[x][y] == '.':
                    reach[i][j].append((x, y))




ans = 0
for i in range(h):
    for j in range(w):
        if s[i][j] == '#':
            break
        tmp_deep = dfs_deep_measure((i, j), h, w, reach)
        #print(tmp_deep)
        for k in range(h):
            for l in range(w):
                if tmp_deep[k][l] != 500:
                    ans = max(ans, tmp_deep[k][l])


print(ans)