#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using P = pair<int, int>;
int main() {
  int h, w;
  cin >> h >> w;
  vector<int> a;
  vector<string> M(h);
  for (int i = 0; i < h; i++) {
    string s;
    cin >> s;
    M[i] = s;
  }
  map<P, vector<P>> G;
  map<P, int> dist;
  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      dist[P(i, j)] = -1;
      if (M[i][j] == '#') {
        G[P(i, j)].push_back(P(-1, -1));
      }
      if (i != 0 && M[i - 1][j] == '.') G[P(i, j)].push_back(P(i - 1, j));
      if (i != h && M[i + 1][j] == '.') G[P(i, j)].push_back(P(i + 1, j));
      if (j != 0 && M[i][j - 1] == '.') G[P(i, j)].push_back(P(i, j - 1));
      if (j != w && M[i][j + 1] == '.') G[P(i, j)].push_back(P(i, j + 1));
    }
  }
  for (int i = 0; i < h; i++)
    for (int j = 0; j < w; j++) {
      queue<P> que;
      map<P, int> dist2;
      dist2.insert(dist.begin(), dist.end());
      dist2[P(i, j)] = 0;
      que.push(P(i, j));
      while (!que.empty()) {
        P v = que.front();
        que.pop();
        for (P nv : G[v]) {
          if (dist2[nv] != -1) continue;
          dist2[nv] = dist2[v] + 1;
          que.push(nv);
        }
      }
      int ans = 0;
      for (int i = 0; i < h; i++)
        for (int j = 0; j < w; j++) a.push_back(max(ans, dist2[P(i, j)]));
    }
  int ans = 0;
  for (int i = 0; i < a.size() - 1; i++) ans = max(ans, a[i]);
  cout << ans << endl;
  return 0;
}
