#include <bits/stdc++.h>
using namespace std;
bool isvowel(char c) {
  if (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u') return true;
  return false;
}
long long int isprime(long long int n) {
  long long int ans = 1;
  for (long long int i = 2; i <= sqrt(n); i++) {
    if (n % i == 0) ans = i;
  }
  return ans;
}
long long int power(long long int a, long long int b, long long int m) {
  if (b == 0) return 1;
  if (b == 1) return a % m;
  long long int temp = power(a, b / 2, m);
  if (b % 2 == 0)
    return ((temp % m) * (temp % m)) % m;
  else
    return ((((temp % m) * (temp % m)) % m) * a % m) % m;
}
long long int c(long long int n, long long int k) {
  long long int C[n + 1][k + 1];
  long long int i, j;
  for (i = 0; i <= n; i++) {
    for (j = 0; j <= min(i, k); j++) {
      if (j == 0 || j == i)
        C[i][j] = 1;
      else
        C[i][j] = (C[i - 1][j - 1] % 1000000007 + C[i - 1][j]) % 1000000007;
    }
  }
  return C[n][k] % 1000000007;
}
long long int modInverse(long long int a, long long int m) {
  long long int m0 = m;
  long long int y = 0, x = 1;
  if (m == 1) return 0;
  while (a > 1) {
    long long int q = a / m;
    long long int t = m;
    m = a % m, a = t;
    t = y;
    y = x - q * y;
    x = t;
  }
  if (x < 0) x += m0;
  return x;
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  long long int t;
  t = 1;
  while (t--) {
    long long int h, w;
    cin >> h >> w;
    string s[h];
    for (long long int i = 0; i < h; i++) cin >> s[i];
    long long int ans = 0;
    for (long long int i = 0; i < h; i++) {
      for (long long int j = 0; j < w; j++) {
        if (s[i][j] == '.') {
          queue<pair<long long int, pair<long long int, long long int>>> q;
          vector<vector<long long int>> visited(h, vector<long long int>(w, 0));
          q.push({0, {i, j}});
          long long int mx = 0;
          while (!q.empty()) {
            pair<long long int, pair<long long int, long long int>> q1 =
                q.front();
            q.pop();
            long long int d = q1.first;
            long long int x = q1.second.first;
            long long int y = q1.second.second;
            visited[x][y] = 1;
            mx = max(mx, d);
            if (y < w - 1 && s[x][y + 1] == '.' && !visited[x][y + 1])
              q.push({d + 1, {x, y + 1}});
            if (y > 0 && s[x][y - 1] == '.' && !visited[x][y - 1])
              q.push({d + 1, {x, y - 1}});
            if (x < h - 1 && s[x + 1][y] == '.' && !visited[x + 1][y])
              q.push({d + 1, {x + 1, y}});
            if (x > 0 && s[x - 1][y] == '.' && !visited[x - 1][y])
              q.push({d + 1, {x - 1, y}});
          }
          ans = max(ans, mx);
        }
      }
    }
    cout << ans;
  }
}
