import itertools
from collections import deque
import math
H, W = map(int,input().split())
#S=list(map(list,input().split()[6:]))
S = []
for i in range(H):
    a = list(map(str,input().split()))
    S.append(a)

#まずはスタートまたはゴールになりうるマス（外側のマス）を集める
start_or_goal = []
for i in range(H):
    a = S[i][0]
    b = S[i][W-1]
    c = []
    d = []
    if a == ".":
        c.append(i)
        c.append(0)
        if c not in start_or_goal:
            start_or_goal.append(c)
    if b == ".":
        d.append(i)
        d.append(W-1)
        if d not in start_or_goal:
            start_or_goal.append(d)
for i in range(W):
    a = S[0][i]
    b = S[H-1][i]
    c = []
    d = []
    if a == ".":
        c.append(0)
        c.append(i)
        if c not in start_or_goal:
            start_or_goal.append(c)
    if b == ".":
        d.append(H-1)
        d.append(i)
        if d not in start_or_goal:
            start_or_goal.append(d)
#スタートとゴールの組み合わせが分かった。
max_root = []
def bfs(h,w,sy,sx,gy,gx,maze):

    #maze=list(map(list,raw_input.split()[6:]))
    for y in range(h):
        for x in range(w):
            if maze[y][x]=='.':
                maze[y][x]=math.inf


    maze[sy-1][sx-1]=0
    que=deque([[sy-1,sx-1]])
    while que:
        y,x=que.popleft()
        for i,j in [(1,0),(0,1),(-1,0),(0,-1)]:
            nexty,nextx=y+i,x+j
            dist=maze[nexty][nextx]
            if dist!='#':
                if dist>maze[y][x]+1:
                    maze[nexty][nextx]=maze[y][x]+1
                    que.append([nexty,nextx])
    return maze[gy-1][gx-1]

s_to_g = list(itertools.combinations(start_or_goal,2))
for i in range(len(s_to_g)):
    sy = s_to_g[i][0][0]+1
    sx = s_to_g[i][0][1]+1
    gy = s_to_g[i][1][0]+1
    gx = s_to_g[i][1][1]+1
    ans = bfs(H,W,sy,sx,gy,gx,S)
    max_root.append(ans)
ans = max(max_root)
print(ans)