#include <bits/stdc++.h>
int main() {
  using vi = std::vector<int>;
  using vvi = std::vector<vi>;
  int H, W;
  scanf("%d%d", &H, &W);
  using vb = std::vector<bool>;
  using vvb = std::vector<vb>;
  vvb room(H + 2, vb(W + 2));
  for (int r{1}; r <= H; r++)
    for (int c{1}; c <= W; c++) {
      char S;
      scanf(" %c", &S);
      room[r][c] = S == '.';
    }
  constexpr int inf{1 << 30};
  int ans{};
  int dir[4][2]{{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
  for (int start_r{1}; start_r <= H; start_r++)
    for (int start_c{1}; start_c <= W; start_c++) {
      if (!room[start_r][start_c]) continue;
      vvi distance(H + 2, vi(W + 2, inf));
      std::queue<std::pair<int, int>> que;
      distance[start_r][start_c] = 0;
      que.push({start_r, start_c});
      while (!que.empty()) {
        auto now{que.front()};
        que.pop();
        for (auto& e : dir) {
          std::pair<int, int> next{now.first + e[0], now.second + e[1]};
          if (!room[next.first][next.second]) continue;
          if (distance[next.first][next.second] <=
              distance[now.first][now.second])
            continue;
          distance[next.first][next.second] =
              distance[now.first][now.second] + 1;
          que.push(next);
        }
      }
      for (auto& e : distance)
        for (auto& f : e)
          if (f != inf) ans = std::max(ans, f);
    }
  printf("%d\n", ans);
  return 0;
}
