#include <bits/stdc++.h>
long long convert(long long i, long long j, long long w) { return i * w + j; }
std::pair<long long, long long> deconv(long long i, long long w) {
  std::pair<long long, long long> ret;
  ret.first = i / w;
  ret.second = i % w;
  return ret;
}
signed main() {
  long long h, w;
  std::cin >> h >> w;
  std::vector<std::string> g(h);
  for (long long i = 0; i < (h); i++) std::cin >> g[i];
  long long max = 0;
  for (long long i = 0; i < (h); i++) {
    for (long long j = 0; j < (w); j++) {
      if (g[i][j] == '.') {
        std::queue<std::pair<long long, long long> > que;
        std::vector<long long> went(h * w, false);
        que.emplace(convert(i, j, w), 0);
        while (!que.empty()) {
          auto tp = que.front();
          que.pop();
          long long xx = tp.first;
          long long x = deconv(xx, w).first;
          long long y = deconv(xx, w).second;
          long long d = tp.second;
          max = std::max(d, max);
          for (long long dx = -1; dx <= 1; dx++) {
            for (long long dy = -1; dy <= 1; dy++) {
              if (dx * dy == 0) {
                if (dx == 0 && dy == 0) continue;
                if (x + dx < 0 || x + dx >= h) continue;
                if (y + dy < 0 || y + dy >= w) continue;
                if (g[x][y] == '#') continue;
                if (went[convert(x + dx, y + dy, w)]) continue;
                went[convert(x + dx, y + dy, w)] = true;
                que.emplace(convert(x + dx, y + dy, w), d + 1);
              }
            }
          }
        }
      }
    }
  }
  std::cout << (max) << '\n';
  return 0;
}
