#include <bits/stdc++.h>
using namespace std;
char a[22][22];
int n, m;
struct pos {
  int x;
  int y;
  int steps;
};
pos make_pos(int a, int b, int c) {
  pos ret;
  ret.x = a;
  ret.y = b;
  ret.steps = c;
  return ret;
}
int bfs(int sx, int sy, int ex, int ey) {
  bool vis[n + 2][m + 2];
  for (int i = 0; i <= n + 1; ++i)
    for (int j = 0; j <= m + 1; ++j)
      if (a[i][j] == '#')
        vis[i][j] = true;
      else
        vis[i][j] = false;
  queue<pos> q;
  q.push(make_pos(sx, sy, 0));
  vis[sx][sy] = true;
  int move[2][4] = {{0, 0, -1, 1}, {-1, 1, 0, 0}};
  while (!q.empty()) {
    pos fr = q.front();
    q.pop();
    if (fr.x == ex && fr.y == ey) return fr.steps;
    pos newpo;
    for (int i = 0; i < 4; i++) {
      int nx = fr.x + move[0][i];
      int ny = fr.y + move[1][i];
      if (vis[nx][ny]) continue;
      vis[nx][ny] = true;
      newpo = make_pos(nx, ny, fr.steps + 1);
      q.push(newpo);
    }
  }
  return 0;
}
int main() {
  int i, j, i1, i2, j1, j2;
  for (i = 0; i < 22; i++)
    for (j = 0; j < 22; j++) a[i][j] = '#';
  cin >> n >> m;
  for (i = 1; i <= n; i++)
    for (j = 1; j <= m; j++) cin >> a[i][j];
  int maxv = 0;
  for (i1 = 1; i1 <= n; i1++)
    for (j1 = 1; j1 <= m; j1++) {
      if (a[i1][j1] == '#') continue;
      for (i2 = 1; i2 <= n; i2++)
        for (j2 = 1; j2 <= m; j2++) {
          if (a[i2][j2] == '#') continue;
          if (i1 == i2 && j1 == j2) continue;
          maxv = max(maxv, bfs(i1, i2, j1, j2));
        }
    }
  cout << maxv << endl;
  return 0;
}
