H,W = gets.split.map(&:to_i)
org_map = []
H.times do |row|
  org_map << gets.split("")
end
cx = 0
cy = 0

max_step = 0
cur_step = 0

sx = 0
sy = 0
loop do
  break if H-1 < sy
  cx = sx
  cy = sy
  cur_step = 0
  q = [{cy: cy, cx:cx, len:cur_step}]
  cur_map = Marshal.load(Marshal.dump(org_map))
  while q.empty? == false
    pos = q.shift
    cx = pos[:cx]
    cy = pos[:cy]
    len = pos[:len]
    proc = Proc.new do |cy,cx,len|
      if cur_map[cy][cx] == '.'
        cur_map[cy][cx] = 'w'
        len += 1
        max_step = len if max_step < len
        q << {cy:cy,cx:cx, len:len}
      end
    end
  
    # 左
    if 0 < cx && cur_map[cy][cx-1] == '.'
      proc.call(cy, cx-1, len)
    end
  
    # 上
    if 0 < cy && cur_map[cy-1][cx] == '.'
      proc.call(cy-1, cx, len)
    end
  
    # 右
    if cx < W-1 && cur_map[cy][cx+1] == '.'
      proc.call(cy, cx+1, len)
    end
    # 下
    if cy < H-1 && cur_map[cy+1][cx] == '.'
      proc.call(cy+1, cx, len)
    end
  end
  if sx < W-1
    sx += 1
  elsif sx == W-1
    sx = 0
    sy += 1
  end
end

puts max_step
