#include <bits/stdc++.h>
using namespace std;
using ll = long long;
constexpr int INF = 1e9;
int main(void) {
  int H, W;
  cin >> H >> W;
  vector<string> S(H);
  for (int i = 0; i < H; i++) {
    cin >> S[i];
  }
  int d[H * W][H * W];
  for (int a = 0; a < W * H; a++) {
    for (int b = 0; b < W * H; b++) {
      int ai = a / W;
      int aj = a % W;
      int bi = b / W;
      int bj = b % W;
      d[a][b] = INF;
      if (S[ai][aj] != '#' && S[bi][bj] != '#') {
        if (a == b) d[a][a] = 0;
        if (((ai == bi) && (abs(aj - bj) == 1)) ||
            ((aj == bj) && (abs(ai - bi) == 1))) {
          d[a][b] = 1;
        }
      }
    }
  }
  for (int k = 0; k < W * H; k++) {
    priority_queue<pair<int, int>, vector<pair<int, int> >,
                   greater<pair<int, int> > >
        que;
    que.push(pair<int, int>(0, k));
    while (!que.empty()) {
      pair<int, int> p = que.top();
      que.pop();
      int v = p.second;
      if (d[k][v] < p.first) continue;
      for (int x = -1, y = 0, i = 0; i < 4; x += y, y = x - y, x = y - x, ++i) {
        int vi = v / W + x;
        int vj = v % W + y;
        if (0 <= vi and vi < H and 0 <= vj and vj < W) {
          int e = vi * W + vj;
          if (d[k][e] >= d[k][v] + d[v][e]) {
            d[k][e] = d[k][v] + d[v][e];
            que.push(pair<int, int>(d[k][e], e));
          }
        }
      }
    }
  }
  int max_d = 0;
  for (int a = 0; a < W * H; a++) {
    for (int b = 0; b < W * H; b++) {
      if (d[a][b] >= INF) continue;
      max_d = max(d[a][b], max_d);
    }
  }
  cout << max_d << endl;
  return 0;
}
