#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
unsigned long long gcd(unsigned long long a, unsigned long long b) {
  return b ? gcd(b, a % b) : a;
}
unsigned long long lcm(unsigned long long a, unsigned long long b) {
  return a / gcd(a, b) * b;
}
const vector<int> dy = {-1, 0, 1, 0}, dx = {0, 1, 0, -1};
int main() {
  int h, w;
  cin >> h >> w;
  vector<string> s(h);
  for (int i = 0, i_len = (h); i < i_len; i++) cin >> s[i];
  int ans = 0;
  for (int si = 0, si_len = (h); si < si_len; si++)
    for (int sj = 0, sj_len = (w); sj < sj_len; sj++) {
      queue<pii> q;
      vector<vector<int> > dist(h, vector<int>(w, (1e9)));
      auto update = [&](int ny, int nx, int nd) {
        if (dist[ny][nx] <= nd) return;
        q.emplace(ny, nx);
        dist[ny][nx] = nd;
      };
      update(si, sj, 0);
      while (!q.empty()) {
        int y = q.front().first, x = q.front().second;
        q.pop();
        for (int i = 0, i_len = (4); i < i_len; i++) {
          int ny = y + dy[i], nx = x + dx[i];
          if (ny < 0 || ny >= h || nx < 0 || nx >= w) continue;
          if (s[ny][nx] == '#') continue;
          update(ny, nx, dist[y][x] + 1);
        }
      }
      for (int i = 0, i_len = (h); i < i_len; i++)
        for (int j = 0, j_len = (w); j < j_len; j++) {
          if (dist[i][j] == (1e9)) continue;
          ans = max(ans, dist[i][j]);
        }
    }
  cout << ans << endl;
  return 0;
}
