#include <bits/stdc++.h>
using namespace std;
static const int N = 100;
static const int INF = 1e9;
int h, w;
int sy, sx, gy, gx;
int d[N][N];
bool used[N][N];
vector<string> S;
int bfs(int sh, int sw) {
  queue<pair<int, int> > Q;
  for (int i = 0; i < h; i++)
    for (int j = 0; j < w; j++) used[i][j] = false;
  for (int i = 0; i < h; i++)
    for (int j = 0; j < h; j++) d[i][j] = INF;
  used[sh][sw] = true;
  d[sy][sx] = 0;
  Q.push(make_pair(sy, sx));
  while (!Q.empty()) {
    pair<int, int> u = Q.front();
    Q.pop();
    int th = u.first, tw = u.second;
    used[th][tw] = true;
    if (th + 1 < h && !used[th + 1][tw] && S[th + 1][tw] == '.') {
      Q.push(make_pair(th + 1, tw));
      used[th + 1][tw] = true;
      d[th + 1][tw] = d[th][tw] + 1;
    }
    if (th - 1 >= 0 && !used[th - 1][tw] && S[th - 1][tw] == '.') {
      Q.push(make_pair(th - 1, tw));
      used[th - 1][tw] = true;
      d[u.first - 1][tw] = d[th][tw] + 1;
    }
    if (tw + 1 < w && !used[th][tw + 1] && S[th][tw + 1] == '.') {
      Q.push(make_pair(th, tw + 1));
      used[th][tw + 1] = true;
      d[u.first][tw + 1] = d[th][tw] + 1;
    }
    if (tw - 1 >= 0 && !used[th][tw - 1] && S[th][tw - 1] == '.') {
      Q.push(make_pair(th, tw - 1));
      used[th][tw - 1] = true;
      d[u.first][tw - 1] = d[th][tw] + 1;
    }
  }
  int ans = 0;
  for (int i = 0; i < h; i++)
    for (int j = 0; j < w; j++)
      if (d[i][j] != INF) ans = max(ans, d[i][j]);
}
int main() {
  cin >> h >> w;
  S.resize(h);
  for (int i = 0; i < h; i++) cin >> S[i];
  int ans = 0;
  for (int i = 0; i < h; i++)
    for (int j = 0; j < h; j++) d[i][j] = INF;
  for (int i = 0; i < h; i++)
    for (int j = 0; j < w; j++)
      if (S[i][j] == '.') {
        ans = max(bfs(i, j), ans);
      }
  cout << ans << endl;
}
