#include <bits/stdc++.h>
using namespace std;
const long long int dx[] = {-1, 0, 1, 0};
const long long int dy[] = {0, -1, 0, 1};
long long int gcd(long long int a, long long int b) {
  return b ? gcd(b, a % b) : a;
}
long long int lcm(long long int a, long long int b) {
  return a / gcd(a, b) * b;
}
long long int mpow(long long int N,
                   long long int pair<long long int, long long int>,
                   long long int M) {
  if (pair<long long int, long long int> == 0) return 1;
  if (pair<long long int, long long int> % 2 == 0) {
    long long int t = mpow(N, pair<long long int, long long int> / 2, M);
    return t * t % M;
  }
  return N * mpow(N, pair<long long int, long long int> - 1, M) % M;
}
long long int counter(long long int x) {
  if (x == 0) return 0;
  return counter(x >> 1) + (x & 1);
}
vector<bool> prime(100 + 1, true);
void prime_table(void) {
  prime[0] = false;
  prime[1] = false;
  for (long long int i = 2; i * i <= 100; i++) {
    if (!prime[i]) {
      continue;
    }
    for (long long int j = i + i; j <= 100; j += j + i) {
      prime[j] = false;
    }
  }
}
bool IsPrime(long long int num) {
  if (num < 2)
    return false;
  else if (num == 2)
    return true;
  else if (num % 2 == 0)
    return false;
  double sqrtNum = sqrt(num);
  for (long long int i = 3; i <= sqrtNum; i += 2) {
    if (num % i == 0) {
      return false;
    }
  }
  return true;
}
signed main() {
  long long int H, W;
  long long int ans = 0;
  cin >> H >> W;
  vector<string> S(H);
  for (long long int i = (0); i < (H); i++) cin >> S[i];
  for (long long int si = (0); si < (H); si++)
    for (long long int sj = (0); sj < (W); sj++) {
      if (S[si][sj] == '#') continue;
      vector<vector<long long int>> dist(
          H, vector<long long int>(W, 100010001000));
      queue<pair<long long int, long long int>> q;
      auto update = [&](long long int i, long long int j, long long int x) {
        if (dist[i][j] != 100010001000) return;
        dist[i][j] = x;
        q.push(pair<long long int, long long int>(i, j));
      };
      update(si, sj, 0);
      while (!q.empty()) {
        long long int i = q.front().first;
        long long int j = q.front().second;
        q.pop();
        for (long long int dis = (0); dis < (4); dis++) {
          long long int ni = i + dx[dis];
          long long int nj = j + dy[dis];
          if (ni < 0 || ni >= W || nj < 0 || nj >= H) continue;
          if (S[ni][nj] == '#') continue;
          update(ni, nj, dist[i][j] + 1);
        }
      }
      for (long long int i = (0); i < (H); i++)
        for (long long int j = (0); j < (W); j++) {
          if (dist[i][j] == 100010001000) continue;
          ans = max(ans, dist[i][j]);
        }
    }
  cout << ans << endl;
}
