#include <bits/stdc++.h>
using namespace std;
int shortest_length(int sy, int sx, int gy, int gx, vector<string> field,
                    char block) {
  int h = field.size();
  int w = field[0].size();
  vector<vector<int>> d(h, vector<int>(w, ((1 << 30) - 1)));
  d[sy][sx] = 0;
  queue<pair<long long, long long>> que;
  que.push(make_pair(sy, sx));
  while (que.size()) {
    pair<long long, long long> p = que.front();
    que.pop();
    int y = p.first;
    int x = p.second;
    if (x == gx && y == gy) break;
    for (int dx = -1, dy = 0, i = 0; i < 4;
         dx += dy, dy = dx - dy, dx = dy - dx, i++) {
      int ny = y + dy;
      int nx = x + dx;
      if (nx >= 0 && nx < w && ny >= 0 && ny < h && field[ny][nx] != block &&
          d[ny][nx] == ((1 << 30) - 1)) {
        d[ny][nx] = d[y][x] + 1;
        que.push(make_pair(ny, nx));
      }
    }
  }
  if (d[gy][gx] == ((1 << 30) - 1)) return -1;
  return d[gy][gx];
}
int main() {
  int h, w;
  cin >> h >> w;
  vector<string> field(h);
  for (int i = 0; i < h; i++) cin >> field[i];
  int ans = 0;
  for (int start_y = 0; start_y < h; start_y++) {
    for (int start_x = 0; start_x < w; start_x++) {
      for (int goal_y = 0; goal_y < h; goal_y++) {
        for (int goal_x = 0; goal_x < w; goal_x++) {
          int sl =
              shortest_length(start_y, start_x, goal_y, goal_x, field, '#');
          ans = max(ans, sl);
        }
      }
    }
  }
  cout << ans << endl;
}
