#include <bits/stdc++.h>
using namespace std;
const long long MOD = 1e9 + 7;
const int INF = 2e9;
const int MAX_LOG = 21;
const int MAX_N = 12800;
int give_cnt(vector<vector<char>> &grid, int sx, int sy, int ex, int ey) {
  int h = grid.size(), w = grid[0].size();
  vector<vector<bool>> visited(h, vector<bool>(w));
  queue<pair<int, pair<int, int>>> Q;
  Q.push(make_pair(0, (make_pair(sx, sy))));
  while (!Q.empty()) {
    pair<int, pair<int, int>> curr = Q.front();
    Q.pop();
    int level = curr.first, x = curr.second.first, y = curr.second.second;
    if (!visited[x][y]) {
      visited[x][y] = 1;
      if (ex == x && ey == y) {
        return level;
      }
      vector<pair<int, int>> dxy = {{-1, 0}, {1, 0}, {0, 1}, {0, -1}};
      for (pair<int, int> temp : dxy) {
        int dx = temp.first, dy = temp.second;
        int nextx = x + dx, nexty = y + dy;
        if (0 <= nextx && nextx < h && 0 <= nexty && nexty < w &&
            grid[nextx][nexty] == '.') {
          Q.push({level + 1, {nextx, nexty}});
        }
      }
    }
  }
  return INF;
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  int h, w;
  cin >> h >> w;
  vector<vector<char>> grid(h, vector<char>(w));
  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      cin >> grid[i][j];
    }
  }
  int ans = 0;
  for (int sx = 0; sx < h; sx++) {
    for (int sy = 0; sy < w; sy++) {
      if (grid[sx][sy] == '#') {
        continue;
      }
      for (int ex = 0; ex < h; ex++) {
        for (int ey = 0; ey < w; ey++) {
          if (grid[ex][ey] == '#') {
            continue;
          }
          ans = max(ans, give_cnt(grid, sx, sy, ex, ey));
        }
      }
    }
  }
  cout << ans << endl;
}
