local mma = math.max
local h, w = io.read("*n", "*n", "*l")
local map = {}
for i = 1, h do
  local s = io.read()
  for j = 1, w do
    map[(i - 1) * w + j] = s:sub(j, j) == "."
  end
end


local function getlength(start_idx, dst_idx)
  local taskstate = {}
  for i = 1, h * w do taskstate[i] = false end
  local tasks = {}
  local tasknum = 0
  local done = 0

  local len = {}
  local inf = -1
  for i = 1, h * w do len[i] = inf end
  len[start_idx] = 0

  local function addtask(idx)
    if not taskstate[idx] then
      taskstate[idx] = true
      tasknum = tasknum + 1
      tasks[tasknum] = idx
    end
  end
  addtask(start_idx)

  local function walk(src, dst)
    if map[dst] then
      if len[dst] == inf or len[src] + 1 < len[dst] then
        len[dst] = len[src] + 1
        addtask(dst)
      end
    end
  end

  while done < tasknum do
    done = done + 1
    local idx = tasks[done]
    taskstate[idx] = false
    local tmp = {}

    if w < idx then walk(idx, idx - w) end
    if idx <= (h - 1) * w then walk(idx, idx + w) end
    if 1 < w then
      if idx % w ~= 0 then walk(idx, idx + 1) end
      if idx % w ~= 1 then walk(idx, idx - 1) end
    end
  end
  local ret = 0
  for i = 1, h * w do
    if 0 < len[i] then
      ret = mma(ret, len[i])
    end
  end
  return ret
end
local totret = 0
for i = 1, h * w do
  totret = mma(totret, getlength(i))
end
print(totret)
