#include <bits/stdc++.h>
using namespace std;
const int MOD = 1e9 + 7;
const long long INF = 1LL << 60;
using Graph = vector<vector<int>>;
struct Corr {
  long long y;
  long long x;
  long long depth;
};
long long H, W;
long long sh, sw, gh, gw;
int y, x, depth;
vector<string> vec;
queue<Corr> q;
bool seen[510][510];
vector<long long> y_vec = {0, 0, -1, +1};
vector<long long> x_vec = {-1, +1, 0, 0};
void bfs() {
  while (!q.empty()) {
    Corr now = q.front();
    q.pop();
    y = now.y, x = now.x, depth = now.depth;
    for (long long i = 0; i < 4; ++i) {
      Corr next = {y + y_vec[i], x + x_vec[i], depth + 1};
      if (seen[next.y][next.x]) continue;
      if (0 <= next.y && next.y <= H - 1 && 0 <= next.x && next.x <= W - 1 &&
          vec[next.y][next.x] == '.') {
        seen[next.y][next.x] = true;
        q.push(next);
      }
    }
  }
}
int main() {
  cin >> H >> W;
  vec.resize(H);
  for (long long i = 0; i < H; ++i) cin >> vec[i];
  int sh, sw, gh, gw;
  int ans = 0;
  for (int h = 0; h < H; ++h) {
    for (int w = 0; w < W; ++w) {
      memset(seen, 0, sizeof(seen));
      if (vec[h][w] == '.') sh = h, sw = w;
      Corr start = {sh, sw, 0};
      q.emplace(start);
      bfs();
      ans = max(depth, ans);
      depth = 0;
    }
  }
  cout << ans << endl;
  return 0;
}
