#include <bits/stdc++.h>
template <class T, class U>
inline bool chmax(T& lhs, const U& rhs) {
  if (lhs < rhs) {
    lhs = rhs;
    return 1;
  }
  return 0;
}
template <class T, class U>
inline bool chmin(T& lhs, const U& rhs) {
  if (lhs > rhs) {
    lhs = rhs;
    return 1;
  }
  return 0;
}
constexpr int dx[] = {1, 0, -1, 0};
constexpr int dy[] = {0, 1, 0, -1};
int H, W;
int dist[20][20];
char grid[20][20];
bool inside(int x, int y) { return 0 <= x && x < H && 0 <= y && y < W; }
int bfs(int x, int y) {
  for (int i = 0; i < (H); ++i)
    for (int j = 0; j < (W); ++j) dist[i][j] = 100000;
  dist[x][y] = 0;
  std::queue<std::pair<int, int>> que;
  que.push(std::make_pair(x, y));
  while (!que.empty()) {
    int s, t;
    std::tie(s, t) = que.front();
    que.pop();
    for (int k = 0; k < (4); ++k) {
      int ns = s + dx[k], nt = t + dy[k];
      if (!inside(ns, nt) || grid[ns][nt] == '#') {
        continue;
      }
      if (chmin(dist[ns][nt], dist[s][t] + 1)) {
        que.push(std::make_pair(ns, nt));
      }
    }
  }
  int res = 0;
  for (int i = 0; i < (H); ++i)
    for (int j = 0; j < (W); ++j) {
      if (grid[i][j] == '#') continue;
      chmax(res, dist[i][j]);
    }
  return res;
}
int main() {
  std::cin >> H >> W;
  for (int i = 0; i < (H); ++i)
    for (int j = 0; j < (W); ++j) std::cin >> grid[i][j];
  int ans = 0;
  for (int i = 0; i < (H); ++i)
    for (int j = 0; j < (W); ++j) chmax(ans, bfs(i, j));
  std::cout << ans << '\n';
  return 0;
}
