#include <bits/stdc++.h>
using namespace std;
int n, m;
const long long INF = 1e9;
const int MAX = 500;
long long g[MAX][MAX];
char mat[MAX][MAX];
void floydWarshall() {
  for (int k = 0; k <= max(n * n, m * m); k++)
    for (int i = 0; i <= max(n * n, m * m); i++)
      for (int j = 0; j <= max(n * n, m * m); j++)
        g[i][j] = min(g[i][j], g[i][k] + g[k][j]);
}
void init() {
  for (int i = 0; i <= max(n * n, m * m); i++) {
    for (int j = 0; j <= max(n * n, m * m); j++) {
      g[i][j] = (i == j ? 0 : INF);
    }
  }
}
bool ok(int i, int j) { return i >= 0 && i < n && j >= 0 && j < m; }
int main() {
  ios::sync_with_stdio(0), cin.tie(0);
  cin >> n >> m;
  for (int i = 0; i < (int)n; i++) {
    string s;
    cin >> s;
    for (int j = 0; j < (int)m; j++) {
      mat[i][j] = s[j];
    }
  }
  init();
  for (int i = 0; i < (int)n; i++) {
    for (int j = 0; j < (int)m; j++) {
      if (mat[i][j] != '#') {
        int cur = i * n + j;
        if (ok(i, j + 1) && mat[i][j + 1] == '.') {
          g[cur][cur + 1] = 1;
        }
        if (ok(i, j - 1) && mat[i][j - 1] == '.') {
          g[cur][cur - 1] = 1;
        }
        if (ok(i + 1, j) && mat[i + 1][j] == '.') {
          g[cur][cur + n] = 1;
        }
        if (ok(i - 1, j) && mat[i - 1][j] == '.') {
          g[cur][cur - n] = 1;
        }
      }
    }
  }
  floydWarshall();
  long long mx = 0;
  for (int i = 0; i < (int)n; i++) {
    for (int j = 0; j < (int)m; j++) {
      if (mat[i][j] != '#') {
        for (int a = 0; a < (int)n; a++) {
          for (int b = 0; b < (int)m; b++) {
            if (mat[a][b] != '#') {
              long long dis = g[i * n + j][a * n + b];
              if (dis != INF) mx = max(mx, dis);
            }
          }
        }
      }
    }
  }
  cout << mx << '\n';
  return 0;
}
