#include <bits/stdc++.h>
using namespace std;
const int dx[] = {0, 1, 0, -1};
const int dy[] = {1, 0, -1, 0};
inline int toInt(string s) {
  int v;
  istringstream sin(s);
  sin >> v;
  return v;
}
inline long long toLL(string s) {
  long long v;
  istringstream sin(s);
  sin >> v;
  return v;
}
template <class T>
inline string toString(T x) {
  ostringstream sout;
  sout << x;
  return sout.str();
}
long long h, w;
long long solve(vector<string> &b, pair<int, int> s, pair<int, int> g) {
  int cnt[b.size()][b[0].size()];
  memset(cnt, -1, sizeof(cnt));
  deque<pair<int, int> > que;
  cnt[s.first][s.second] = 0;
  que.push_back(s);
  while (que.empty() == false) {
    pair<int, int> f = que.front();
    que.pop_front();
    for (long long dir = 0; dir < (long long)(4); dir++) {
      int ni = f.first + dy[dir];
      int nj = f.second + dx[dir];
      if (ni >= 0 && ni < h && nj >= 0 && nj < w && b[ni][nj] != '#' &&
          cnt[ni][nj] == -1) {
        cnt[ni][nj] = cnt[f.first][f.second] + 1;
        if (ni == g.first && nj == g.second) return cnt[ni][nj];
        que.push_back(pair<int, int>(ni, nj));
      }
    }
  }
  return cnt[g.first][g.second];
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cin >> h >> w;
  vector<string> b(h);
  for (long long i = 0; i < (long long)(h); i++) cin >> b[i];
  long long ans = 0;
  for (long long si = 0; si < (long long)(h); si++)
    for (long long sj = 0; sj < (long long)(w); sj++)
      for (long long gi = 0; gi < (long long)(h); gi++)
        for (long long gj = 0; gj < (long long)(w); gj++) {
          ans = max(ans,
                    solve(b, pair<int, int>(si, sj), pair<int, int>(gi, gj)));
        }
  cout << ans << endl;
  return 0;
}
