#include <bits/stdc++.h>
using namespace std;
template <typename T>
using V = vector<T>;
using Vi = V<int>;
using Vs = V<string>;
const int INF = 1999999999;
const int DX[4] = {-1, 0, 1, 0};
const int DY[4] = {0, -1, 0, 1};
template <typename T>
T SUM(V<T> v, T init_val = 0) {
  return accumulate((v).begin(), (v).end(), T(init_val));
}
int main() {
  int h, w;
  cin >> h >> w;
  Vs s(h);
  for (int(i) = 0; (i) < (h); (i)++) {
    cin >> s[i];
  }
  V<Vi> dist(h * w, Vi(h * w, INF / 2));
  for (int(i) = 0; (i) < (h * w); (i)++) {
    dist[i][i] = 0;
  }
  for (int(y) = 0; (y) < (h); (y)++) {
    for (int(x) = 0; (x) < (w); (x)++) {
      for (int(i) = 0; (i) < (4); (i)++) {
        int dx = x + DX[i];
        int dy = y + DY[i];
        if (dx < 0 || w <= dx) continue;
        if (dy < 0 || h <= dy) continue;
        if (s[dy][dx] == '#') continue;
        dist[y * w + x][dy * w + dx] = 1;
      }
    }
  }
  for (int(k) = 0; (k) < (h * w); (k)++) {
    for (int(i) = 0; (i) < (h * w); (i)++) {
      for (int(j) = 0; (j) < (h * w); (j)++) {
        dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]);
      }
    }
  }
  int ans = 0;
  for (int(i) = 0; (i) < (h * w); (i)++) {
    for (int(j) = 0; (j) < (h * w); (j)++) {
      if (dist[i][j] == INF / 2) continue;
      ans = max(ans, dist[i][j]);
    }
  }
  cout << ans << endl;
  return 0;
}
