#include <bits/stdc++.h>
using namespace std;
long long dx[4] = {0, 1, 0, -1};
long long dy[4] = {1, 0, -1, 0};
long long H, W;
struct bfs_xy {
  long long x;
  long long y;
  long long d;
};
bool is_within_map(long long x, long long y) {
  return (0 <= x && x < W) && (0 <= y && y < H);
}
long long bfs(vector<vector<char>> bfs_map, long long sx, long long sy,
              long long gx, long long gy) {
  queue<bfs_xy> bfs_q;
  bfs_xy start = {sx, sy, 0};
  bfs_q.push(start);
  while (!bfs_q.empty()) {
    bfs_xy now = bfs_q.front();
    bfs_q.pop();
    for (long long i = 0; i < 4; i++) {
      long long tx = now.x + dx[i], ty = now.y + dy[i];
      if (!is_within_map(tx, ty)) continue;
      if (bfs_map[ty][tx] == '#') continue;
      if (tx == gx && ty == gy) return now.d + 1;
      bfs_xy new_xy = {tx, ty, now.d + 1};
      bfs_q.push(new_xy);
      bfs_map[ty][tx] = '#';
    }
  }
  return -1;
}
signed main() {
  cin >> H >> W;
  vector<vector<char>> bfs_map(H, vector<char>(W));
  for (long long i = 0; i < (long long)(H); i++) {
    string s;
    cin >> s;
    bfs_map[i] = vector<char>((s).begin(), (s).end());
  }
  long long maximum = 0;
  for (long long sx = 0; sx < (long long)(W); sx++)
    for (long long sy = 0; sy < (long long)(H); sy++) {
      for (long long gx = 0; gx < (long long)(W); gx++)
        for (long long gy = 0; gy < (long long)(H); gy++) {
          if (bfs_map[sy][sx] == '#' || bfs_map[gy][gx] == '#') continue;
          maximum = max(maximum, bfs(bfs_map, sx, sy, gx, gy));
        }
    }
  cout << maximum << endl;
  return 0;
}
