import sequtils, strutils, algorithm, math, sets, tables
when NimMajor == 0 and NimMinor <= 18: import future else: import sugar
#template `MIN=`(a,b:untyped)=a=min(a,b)
template SEQ2D(y,x:int,p:untyped):untyped=newSeqWith(y,newSeqWith(x,p))

var (H,W) = (let t = stdin.readline.split.map(parseInt);(t[0],t[1]))
var S = newSeqWith(H,stdin.readline)

# 仮のスタート位置を探す
var sx,sy = 0
for h in 0..<H:
  for w in 0..<W:
    if S[h][w] == '.':
      sx = w
      sy = h

var map = SEQ2D(H,W,1000)
var max_c = 0

proc dfs(x,y,c:int)=
  if x < 0: return
  if y < 0: return
  if x >= W: return
  if y >= H: return
  if S[y][x] == '#': return
  if map[y][x] <= c: return
  map[y][x] = c
  dfs(x+1,y,c+1)
  dfs(x-1,y,c+1)
  dfs(x,y+1,c+1)
  dfs(x,y-1,c+1)

dfs(sx,sy,0)
#dump(map)

# 仮スタート位置から一番遠かったとこを探す
max_c = -1
for h in 0..<H:
  for w in 0..<W:
    if S[h][w] == '#': continue
    if map[h][w]>max_c:
      max_c = map[h][w]
      sx = w
      sy = h

map = SEQ2D(H,W,1000)
dfs(sx,sy,0)
#dump(map)

# 2回目の結果を計測
max_c = -1
for h in 0..<H:
  for w in 0..<W:
    if S[h][w] == '#': continue
    if map[h][w]>max_c:
      max_c = map[h][w]
      sx = w
      sy = h

echo max_c
