#include <bits/stdc++.h>
using namespace std;
using ll = long long;
template <class T, class U>
ostream& operator<<(ostream& o, const pair<T, U>& p) {
  o << "(" << p.first << "," << p.second << ")";
  return o;
}
template <class T>
ostream& operator<<(ostream& o, const vector<T>& v) {
  o << "[";
  for (T t : v) {
    o << t << ",";
  }
  o << "]";
  return o;
}
using pi = pair<int, int>;
const int dx[4] = {-1, 1, 0, 0};
const int dy[4] = {0, 0, -1, 1};
const int INF = 1010101;
int main() {
  int h, w;
  cin >> h >> w;
  vector<string> s(h);
  for (int i = 0; i < (int)(h); ++i) cin >> s[i];
  auto IN = [&](int y, int x) { return 0 <= y && y < h && 0 <= x && x < w; };
  int ans = 0;
  for (int sy = 0; sy < (int)(h); ++sy)
    for (int sx = 0; sx < (int)(w); ++sx) {
      vector<vector<int>> d(h, vector<int>(w, INF));
      d[sy][sx] = 0;
      queue<pi> que({{sy, sx}});
      while (!que.empty()) {
        pi p = que.front();
        que.pop();
        for (int i = 0; i < (int)(4); ++i) {
          int ny = p.first + dy[i], nx = p.second + dx[i];
          if (IN(ny, nx) && s[ny][nx] != '#' &&
              d[ny][nx] > d[p.first][p.second] + 1) {
            que.push({ny, nx});
            d[ny][nx] = d[p.first][p.second] + 1;
          }
        }
      }
      for (int i = 0; i < (int)(h); ++i)
        for (int j = 0; j < (int)(w); ++j)
          if (d[i][j] < INF) ans = max(ans, d[i][j]);
    }
  cout << ans << "\n";
  return 0;
}
