#include <bits/stdc++.h>
using namespace std;
using ll = long long;
ll MOD = 1000000007;
ll mod = 998244353;
int inf = 1000001000;
ll INF = 1e18 + 5;
int main() {
  int h, w, ans = 0;
  cin >> h >> w;
  vector<vector<char>> mp(h + 2, vector<char>(w + 2, '0'));
  char ch;
  for (int(i) = 0; (i) < (h); (i)++) {
    for (int(j) = 0; (j) < (w); (j)++) {
      cin >> ch;
      mp[i + 1][j + 1] = ch;
    }
  }
  int dx, dy;
  int cost, x, y, ans_;
  vector<pair<int, int>> dir = {make_pair(-1, 0), make_pair(0, -1),
                                make_pair(1, 0), make_pair(0, 1)};
  vector<vector<int>> dis;
  for (int i = 1; i <= h; i++) {
    for (int j = 1; j <= w; j++) {
      if (mp[i][j] != '.') continue;
      priority_queue<tuple<int, int, int>, vector<tuple<int, int, int>>,
                     greater<tuple<int, int, int>>>
          pq;
      dis = vector<vector<int>>(h + 2, vector<int>(w + 2, inf));
      dis[i][j] = 0;
      ans_ = 0;
      pq.push(make_tuple(0, i, j));
      while (!(pq.empty())) {
        tie(cost, x, y) = pq.top();
        pq.pop();
        if (cost != dis[x][y]) continue;
        for (auto p : dir) {
          tie(dx, dy) = p;
          if (mp[x + dx][y + dy] == '.' && dis[x + dx][y + dy] > cost + 1) {
            dis[x + dx][y + dy] = cost + 1;
            pq.push(make_tuple(dis[x + dx][y + dy], x + dx, y + dy));
            ans_ = max(ans_, dis[x + dx][y + dy]);
          }
        }
      }
    }
    ans = max(ans, ans_);
  }
  cout << ans << endl;
}
