#include <bits/stdc++.h>
using namespace std;
const long long INF = 1001001001;
const long long LINF = 1001001001001001001;
const long long D4[] = {0, 1, 0, -1, 0};
const long long D8[] = {0, 1, 1, 0, -1, -1, 1, -1, 0};
template <class T>
bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T>
bool chmin(T &a, const T &b) {
  if (b < a) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T>
using pq = priority_queue<T, vector<T>, greater<T>>;
void solve();
int main() {
  cin.tie(0);
  ios::sync_with_stdio(0);
  solve();
}
void solve() {
  long long h, w;
  cin >> h >> w;
  vector<string> s(h);
  for (long long i = 0; i < (h); ++i) cin >> s[i];
  long long ans = 0;
  for (long long i = 0; i < (h); ++i)
    for (long long j = 0; j < (w); ++j) {
      queue<pair<long long, long long>> q;
      vector<vector<long long>> d(h, vector<long long>(w, INF));
      d[i][j] = 0;
      q.emplace(i, j);
      while (q.size()) {
        pair<long long, long long> p = q.front();
        q.pop();
        for (long long k = 0; k < (4); ++k) {
          long long ty = p.first + D4[k], tx = p.second + D4[k + 1];
          if (ty < 0 || ty >= h || tx < 0 || tx >= w || s[ty][tx] == '#' ||
              d[ty][tx] != INF)
            continue;
          d[ty][tx] = d[p.first][p.second] + 1;
          chmax(ans, d[ty][tx]);
          q.emplace(ty, tx);
        }
      }
    }
  cout << ans << endl;
}
