#include <bits/stdc++.h>
using namespace std;
template <class K, class V>
ostream &operator<<(ostream &out, pair<K, V> &elem) {
  out << "{" << elem.first << "," << elem.second << "}";
  return out;
}
int DEBUG = 1;
using namespace std;
const int N = 50;
int n, m;
char x[N][N];
int di[] = {0, 1, 0, -1};
int dj[] = {1, 0, -1, 0};
bool ins(int i, int j) { return 0 <= i && i < n && 0 <= j && j < m; }
int get(int si, int sj) {
  queue<int> q;
  int dist[N][N];
  for (int i = 0; i < n; i++)
    for (int j = 0; j < m; j++) dist[i][j] = INT_MAX;
  int used[N][N];
  for (int i = 0; i < n; i++)
    for (int j = 0; j < m; j++) used[i][j] = 0;
  q.push(si);
  q.push(sj);
  used[si][sj] = 1;
  dist[si][sj] = 0;
  while (!q.empty()) {
    int fi = q.front();
    q.pop();
    int fj = q.front();
    q.pop();
    for (int d = 0; d < 4; d++) {
      int ti = fi + di[d];
      int tj = fj + dj[d];
      if (ins(ti, tj) && !used[ti][tj] && x[ti][tj] == '.') {
        used[ti][tj] = 1;
        dist[ti][tj] = dist[fi][fj] + 1;
        q.push(ti);
        q.push(tj);
      }
    }
  }
  int mx = 0;
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      if (used[i][j]) {
        mx = max(mx, dist[i][j]);
      }
    }
  }
  return mx;
}
int main() {
  cin >> n >> m;
  for (int i = 0; i < n; i++) {
    string s;
    cin >> s;
    for (int j = 0; j < m; j++) {
      x[i][j] = s[j];
    }
  }
  int ans = 0;
  for (int si = 0; si < n; si++) {
    for (int sj = 0; sj < m; sj++) {
      if (x[si][sj] == '.') {
        int mx = get(si, sj);
        ans = max(ans, mx);
      }
    }
  }
  cout << ans << endl;
  return 0;
}
