#include <bits/stdc++.h>
using namespace std;
using pii = pair<int, int>;
bool isvalidpos(pii p, int h, int w) {
  return p.first >= 0 && p.first < h && p.second >= 0 && p.second < w;
}
int main() {
  int h, w;
  cin >> h >> w;
  vector<string> s(h);
  vector<vector<int>> check(h, vector<int>(w));
  vector<int> dy = {0, 0, 1, -1};
  vector<int> dx = {1, -1, 0, 0};
  int answer = 0;
  for (int i = 0; i < h; i++) cin >> s[i];
  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      if (check[i][j] == 0 && s[i][j] == '.') {
        queue<pair<pii, int>> q;
        pii start;
        int maxdist = 0;
        q.push({{i, j}, 0});
        check[i][j] = 2;
        while (!q.empty()) {
          auto now = q.front();
          q.pop();
          if (maxdist < now.second) {
            maxdist = now.second;
            start = now.first;
          }
          for (int k = 0; k < 4; k++) {
            pii nxt = now.first;
            nxt.first += dy[k];
            nxt.second += dx[k];
            if (isvalidpos(nxt, h, w) && s[nxt.first][nxt.second] == '.' &&
                check[nxt.first][nxt.second] != 2) {
              check[nxt.first][nxt.second] = 2;
              q.push({nxt, now.second + 1});
            }
          }
        }
        q.push({start, 0});
        maxdist = 0;
        check[start.first][start.second] = 1;
        while (!q.empty()) {
          auto now = q.front();
          q.pop();
          maxdist = max(maxdist, now.second);
          for (int k = 0; k < 4; k++) {
            pii nxt = now.first;
            nxt.first += dy[k];
            nxt.second += dx[k];
            if (isvalidpos(nxt, h, w) && s[nxt.first][nxt.second] == '.' &&
                check[nxt.first][nxt.second] != 1) {
              check[nxt.first][nxt.second] = 1;
              q.push({nxt, now.second + 1});
            }
          }
        }
        answer = max(answer, maxdist);
      }
    }
  }
  cout << answer;
  return 0;
}
