#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vll = vector<ll>;
using pll = pair<ll, ll>;
using qll = queue<ll>;
using vb = vector<bool>;
using mll = map<ll, ll>;
using sll = stack<ll>;
const ll INF = 1LL << 60;
ll H, W, N;
vector<string> S;
vector<vll> d;
vll dx{1, 0, -1, 0}, dy{0, 1, 0, -1};
ll xyToIdx(ll x, ll y) { return (x * W + y); }
void idxToxy(ll idx, ll &x, ll &y) {
  x = idx / W;
  y = idx % W;
  return;
}
int main() {
  cin >> H >> W;
  N = H * W;
  for (ll _(0); (_) < (H); (_)++) {
    string tmp;
    cin >> tmp;
    S.push_back(tmp);
  }
  d.resize(N);
  for (ll i(0); (i) < (N); (i)++) {
    d[i].resize(N);
    fill(d[i].begin(), d[i].end(), INF);
  }
  for (ll x(0); (x) < (H); (x)++) {
    for (ll y(0); (y) < (W); (y)++) {
      if (S[x][y] == '#') continue;
      ll xto, yto;
      for (ll k(0); (k) < (4); (k)++) {
        xto = x + dx[k], yto = y + dy[k];
        if (0 <= xto && xto < H && 0 <= yto && yto < W) {
          if (S[xto][yto] == '.') {
            d[xyToIdx(x, y)][xyToIdx(xto, yto)] = 1;
            d[xyToIdx(xto, yto)][xyToIdx(x, y)] = 1;
          }
        }
      }
    }
  }
  for (ll k(0); (k) < (N); (k)++) {
    for (ll i(0); (i) < (N); (i)++) {
      for (ll j(0); (j) < (N); (j)++) {
        d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
      }
    }
  }
  ll ans = 0;
  for (ll i(0); (i) < (N); (i)++) {
    for (ll j(0); (j) < (N); (j)++) {
      ll xi, yi, xj, yj;
      idxToxy(i, xi, yi);
      idxToxy(j, xj, yj);
      if (S[xi][yi] == '.' && S[xj][yj] == '.' && d[i][j] < INF) {
        ans = max(ans, d[i][j]);
      }
    }
  }
  cout << ans << endl;
  return 0;
}
