H,W=map(int,input().split())
grid=[None]*H
# 仮のスタート
sx,sy=-1,-1
found=False
for i in range(H):
  grid[i]=input()
  if not found:
    for j in range(len(grid[i])):
      if grid[i][j]==".":
        sy=i
        sx=j
        found=True
        
from collections import deque
stack=deque()
# y,x,そこまでの距離
stack.append([sy,sx,0])
INF=10**9
seen=[[INF for j in range(W)] for i in range(H)]

longest=0
longestY=-1
longestX=-1
while stack:
  node=stack.popleft()
  y=node[0]
  x=node[1]
  dist=node[2]
  if grid[y][x]=="#":
    continue
  if seen[y][x]<=dist:
    continue
  if dist>longest:
    longest=dist
    longestY=y
    longestX=x
  seen[y][x]=dist
  if y-1>=0:
    stack.append([y-1,x,dist+1])
  if y+1<H:
    stack.append([y+1,x,dist+1])
  if x-1>=0:
    stack.append([y,x-1,dist+1])
  if x+1<W:
    stack.append([y,x+1,dist+1])

longest=0
longestY=-1
longestX=-1
for i in range(H):
  for j in range(W):
    if grid[i][j]==".":
      if seen[i][j]>longest:
        longest=seen[i][j]
        longestY=i
        longestX=j
        
stack=deque()
stack.append([longestY,longestX,0])
seen=[[INF for j in range(W)] for i in range(H)]
longest=0
while stack:
  node=stack.popleft()
  y=node[0]
  x=node[1]
  dist=node[2]
  if grid[y][x]=="#":
    continue
  if seen[y][x]<=dist:
    continue
  if dist>longest:
    longest=dist
  seen[y][x]=dist
  if y-1>=0:
    stack.append([y-1,x,dist+1])
  if y+1<H:
    stack.append([y+1,x,dist+1])
  if x-1>=0:
    stack.append([y,x-1,dist+1])
  if x+1<W:
    stack.append([y,x+1,dist+1])

ans=0
for i in range(H):
  for j in range(W):
    if grid[i][j]==".":
      if seen[i][j]>ans:
        ans=seen[i][j]
print(ans)