#include <bits/stdc++.h>
using namespace std;
inline int ci() {
  register char ch;
  int f = 1;
  while (!isdigit(ch = getchar())) f = ch == '-' ? -1 : 1;
  register int x = ch ^ '0';
  while (isdigit(ch = getchar())) x = (x * 10) + (ch ^ '0');
  return f * x;
}
enum { N = 23 };
char g[N][N];
int f[N][N];
const int dx[4] = {0, 1, -1, 0};
const int dy[4] = {1, 0, 0, -1};
int main() {
  int n = ci(), m = ci();
  for (register int i = (1); i <= (n); i++) {
    scanf("%s", g[i] + 1);
  }
  for (register int i = (1); i <= (n); i++) g[i][0] = g[i][m + 1] = '#';
  for (register int j = (1); j <= (m); j++) g[0][j] = g[n + 1][j] = '#';
  int ans = 0;
  for (register int i = (1); i <= (n); i++)
    for (register int j = (1); j <= (m); j++)
      if (g[i][j] == '.') {
        memset(f, 0, sizeof(f));
        queue<int> q;
        f[i][j] = 1;
        q.push(i * 20 + j);
        while (q.empty() == 0) {
          int x = q.front() / 20, y = q.front() % 20;
          q.pop();
          for (register int s = (0); s <= (3); s++) {
            int tx = x + dx[s], ty = y + dy[s];
            if (g[tx][ty] == '#' || f[tx][ty] != 0) continue;
            f[tx][ty] = f[x][y] + 1;
            ans = max(ans, f[tx][ty] - 1);
            q.push(tx * 20 + ty);
          }
        }
      }
  printf("%d\n", ans);
  return 0;
}
