#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e4 + 23;
int hd[maxn], e[maxn], nxt[maxn], v[maxn], d[404];
int n, m, cnt;
bool vis[404];
void add(int x, int y, int z) {
  v[++cnt] = z, e[cnt] = y, nxt[cnt] = hd[x], hd[x] = cnt;
}
void dijkstra(int s) {
  priority_queue<pair<int, int>> q;
  memset(d, 0x3f, sizeof(d));
  memset(vis, false, sizeof(vis));
  q.push({0, s});
  d[s] = 0;
  while (!q.empty()) {
    int x = q.top().second;
    q.pop();
    if (vis[x]) continue;
    vis[x] = 1;
    for (int i = hd[x]; i; i = nxt[i]) {
      int y = e[i], z = v[i];
      if (d[y] > d[x] + z) {
        d[y] = d[x] + z;
        q.push({-d[y], y});
      }
    }
  }
}
char s[30][30];
int cal(int i, int j) { return i * m + j; }
int main() {
  for (int i = 0; i < 30; i++) {
    for (int j = 0; j < 30; j++) s[i][j] = '#';
  }
  cin >> n >> m;
  for (int i = 1; i <= n; i++) scanf("%s", s[i] + 1), s[i][m + 1] = '#';
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++) {
      if (s[i][j] == '#') continue;
      if (s[i][j + 1] != '#') add(cal(i, j), cal(i, j + 1), 1);
      if (s[i][j - 1] != '#') add(cal(i, j), cal(i, j - 1), 1);
      if (s[i + 1][j] != '#') add(cal(i, j), cal(i + 1, j), 1);
      if (s[i - 1][j] != '#') add(cal(i, j), cal(i - 1, j), 1);
    }
  }
  int mx = 0;
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++) {
      dijkstra(cal(i, j));
      for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++)
          if (d[cal(i, j)] < 1e9) mx = max(mx, d[cal(i, j)]);
      }
    }
  }
  cout << mx;
}
