from collections import deque
N,M = map(int,input().split())
maze = []
for i in range(N):
    maze.append(list(input()))
INF = -1
cost = [[INF]*M for _ in range(N)]
dx = [1,0,-1,0]
dy = [0,1,0,-1]
sx,sy = 0,0
gx,gy = 0,0

# 左上、右下
sf = False
gf = False
for i in range(N):
    if sf:
        break
    for j in range(M):
        if sf:
            break
        if maze[i][j] != "#":
            sx,sy = i,j
            sf = True
for i in range(N-1,-1,-1):
    if gf:
        break
    for j in range(M-1,-1,-1):
        if gf:
            break
        if maze[i][j] != "#":
            gx,gy = i,j
            gf = True
def bfs():
    P = deque()
    P.append([sx,sy])
    cost[sx][sy] = 0
    while len(P) != 0:
        p = P.popleft()
        if p[0] == gx and p[1] == gy:
            break
        for i in range(4):
            nx = p[0] + dx[i]
            ny = p[1] + dy[i]
            if 0 <= nx < N and 0 <= ny < M and maze[nx][ny] != "#" and cost[nx][ny] == INF:
                P.append([nx,ny])
                cost[nx][ny] = cost[p[0]][p[1]]+1
    return cost[gx][gy]
bfs()
ans = 0
for i in cost:
    if ans < max(i):
        ans = max(i)

# 左下、右上
cost = [[INF]*M for _ in range(N)]
sf = False
gf = False
for i in range(N-1,-1,-1):
    if sf:
        break
    for j in range(M):
        if sf:
            break
        if maze[i][j] != "#":
            sx,sy = i,j
            sf = True
for i in range(N):
    if gf:
        break
    for j in range(M-1,-1,-1):
        if gf:
            break
        if maze[i][j] != "#":
            gx,gy = i,j
            gf = True
bfs()
for i in cost:
    if ans < max(i):
        ans = max(i)

# 左上、左下
cost = [[INF]*M for _ in range(N)]
sf = False
gf = False
for i in range(N):
    if sf:
        break
    for j in range(M):
        if sf:
            break
        if maze[i][j] != "#":
            sx,sy = i,j
            sf = True
for i in range(N-1,-1,-1):
    if gf:
        break
    for j in range(M):
        if gf:
            break
        if maze[i][j] != "#":
            gx,gy = i,j
            gf = True
bfs()
for i in cost:
    if ans < max(i):
        ans = max(i)

# 右上、右下
cost = [[INF]*M for _ in range(N)]
sf = False
gf = False
for i in range(N):
    if sf:
        break
    for j in range(M-1,-1,-1):
        if sf:
            break
        if maze[i][j] != "#":
            sx,sy = i,j
            sf = True
for i in range(N-1,-1,-1):
    if gf:
        break
    for j in range(M-1,-1,-1):
        if gf:
            break
        if maze[i][j] != "#":
            gx,gy = i,j
            gf = True
bfs()
for i in cost:
    if ans < max(i):
        ans = max(i)

# 左上、右上
cost = [[INF]*M for _ in range(N)]
sf = False
gf = False
for i in range(N):
    if sf:
        break
    for j in range(M):
        if sf:
            break
        if maze[i][j] != "#":
            sx,sy = i,j
            sf = True
for i in range(N):
    if gf:
        break
    for j in range(M-1,-1,-1):
        if gf:
            break
        if maze[i][j] != "#":
            gx,gy = i,j
            gf = True
bfs()
for i in cost:
    if ans < max(i):
        ans = max(i)

# 左下、右下
cost = [[INF]*M for _ in range(N)]
sf = False
gf = False
for i in range(N-1,-1,-1):
    if sf:
        break
    for j in range(M):
        if sf:
            break
        if maze[i][j] != "#":
            sx,sy = i,j
            sf = True
for i in range(N-1,-1,-1):
    if gf:
        break
    for j in range(M-1,-1,-1):
        if gf:
            break
        if maze[i][j] != "#":
            gx,gy = i,j
            gf = True
bfs()
for i in cost:
    if ans < max(i):
        ans = max(i)

print(ans)