import sequtils, strutils
import macros
macro unpack(s:seq, n:static[int]): auto =
  let t = genSym()
  result = quote do:(let `t` = `s`;())
  when NimMajor == 0 and NimMinor <= 17:
    for i in 0..<n: result[0][1].add(quote do:(`t`[`i`]))
  else:
    for i in 0..<n: result[1].add(quote do:(`t`[`i`]))
when NimMajor == 0 and NimMinor < 20:
  import queues
else:
  import deques
  type Queue[T] = Deque[T]
  proc initQueue[T]():Queue[T] = initDeque[T]()
  proc enqueue[T](q:var Queue[T], item:T) = q.addLast(item)
  proc dequeue[T](q:var Queue[T]): T = q.popFirst

const
  dxs = @[1, 0, -1, 0]
  dys = @[0, 1, 0, -1]
  inf = 1 shl 30
let
  (h, w) = stdin.readline.split.map(parseInt).unpack(2)
  sss = newSeqWith(h, stdin.readline)
var
  dss = newSeqWith(h, newSeq[int](w))
  q = initQueue[(int, int)]()

for i, ss in sss:
  for j, s in ss:
    if s == '.':
      dss[i][j] = inf
      if len(q) == 0:
        q.enqueue((i, j))
        dss[i][j] = 0
    else:
      dss[i][j] = -1

while len(q) > 0:
  let (x, y) = q.dequeue
  for dxy in zip(dxs, dys):
    let (dx, dy) = dxy
    if x+dx >= 0 and x+dx < h and y+dy >= 0 and y+dy < w and dss[x+dx][y+dy] == inf:
      dss[x+dx][y+dy] = dss[x][y]+1
      q.enqueue((x+dx, y+dy))

var s, t = 0
for x, ds in dss:
  for y, d in ds:
    if dss[s][t] < d:
      s = x
      t = y
for ds in dss.mitems:
  for d in ds.mitems:
    if d >= 0:
      d = inf

q.enqueue((s, t))
dss[s][t] = 0
while len(q) > 0:
  let (x, y) = q.dequeue
  for dxy in zip(dxs, dys):
    let (dx, dy) = dxy
    if x+dx >= 0 and x+dx < h and y+dy >= 0 and y+dy < w and dss[x+dx][y+dy] == inf:
      dss[x+dx][y+dy] = dss[x][y]+1
      q.enqueue((x+dx, y+dy))

echo dss.mapIt(max(it)).max
