#include <bits/stdc++.h>
using namespace std;
const long long INFLL = 1e18;
const int MAXN = 1e6 + 100;
const long long INF = 1e9;
const long long mod1 = 1e9 + 7;
const long long mod2 = 2e9 + 11;
int h, w;
vector<int> g[20 * 20];
vector<int> d;
int mx = -1, ind = -1;
void bfs(int s) {
  d = vector<int>(h * w, INF);
  d[s] = 0;
  if (mx < d[s]) {
    mx = d[s], ind = s;
  }
  queue<int> q;
  q.push(s);
  while (!q.empty()) {
    int f = q.front();
    q.pop();
    for (auto to : g[f]) {
      if (d[to] == INF) {
        d[to] = d[f] + 1;
        if (mx < d[to]) {
          mx = d[to], ind = to;
        }
        q.push(to);
      }
    }
  }
}
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  vector<int> x = {1, -1, 0, 0};
  vector<int> y = {0, 0, 1, -1};
  cin >> h >> w;
  vector<string> s(h);
  for (int i = 0; i < h; i++) cin >> s[i];
  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      for (int k = 0; k < 4; k++) {
        if (i + x[k] >= 0 && i + x[k] < h && j + y[k] < w && j + y[k] >= 0) {
          if (s[i][j] == '.' && s[i + x[k]][j + y[k]] == '.') {
            g[i * w + j].push_back((i + x[k]) * w + j + y[k]);
          }
        }
      }
    }
  }
  int u;
  for (int i = 0; i < h * w; i++) {
    if (s[i / w][i % w] == '.') {
      bfs(i);
      u = i;
      break;
    }
  }
  vector<int> tries;
  for (int i = 0; i < h * w; i++) {
    if (d[i] == mx) tries.push_back(i);
  }
  for (int i = 0; i < tries.size(); i++) {
    mx = -1;
    bfs(tries[i]);
  }
  cout << mx;
}
