#include <bits/stdc++.h>
using namespace std;
using i64 = int64_t;
using i32 = int32_t;
template <class T, class U>
void init_n(vector<T>& v, size_t n, U x) {
  v = vector<T>(n, x);
}
template <class T>
void init_n(vector<T>& v, size_t n) {
  init_n(v, n, T());
}
template <class T>
void read_n(vector<T>& v, size_t n, size_t o = 0) {
  v = vector<T>(n + o);
  for (size_t i = o; i < n + o; ++i) cin >> v[i];
}
template <class T>
void read_n(T a[], size_t n, size_t o = 0) {
  for (size_t i = o; i < n + o; ++i) cin >> a[i];
}
template <class T>
T iabs(const T& x) {
  return max(x, -x);
}
int h, w, dist[400][400];
vector<string> s;
int idx(int i, int j) { return w * i + j; }
int main() {
  cin >> h >> w;
  read_n(s, h);
  for (int i = 0; i < h * w; ++i) {
    for (int j = 0; j < h * w; ++j) {
      dist[i][j] = 1e9;
    }
  }
  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      if (s[i][j] == '.') {
        if (i < h - 1 && s[i + 1][j] == '.') {
          dist[idx(i, j)][idx(i + 1, j)] = dist[idx(i + 1, j)][idx(i, j)] = 1;
        }
        if (j < w - 1 && s[i][j + 1] == '.') {
          dist[idx(i, j)][idx(i, j + 1)] = dist[idx(i, j + 1)][idx(i, j)] = 1;
        }
      }
    }
  }
  for (int k = 0; k < h * w; ++k) {
    for (int i = 0; i < h * w; ++i) {
      for (int j = 0; j < h * w; ++j) {
        dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]);
      }
    }
  }
  int ans = 0;
  for (int i = 0; i < h * w; ++i) {
    for (int j = 0; j < h * w; ++j) {
      if (dist[i][j] < 1e9) {
        ans = max(ans, dist[i][j]);
      }
    }
  }
  cout << ans << endl;
  return 0;
}
