#include <bits/stdc++.h>
using namespace std;
vector<long long> node[100000];
vector<long long> height(10000, 0);
vector<long long> vis(100000, 0);
void bfs(int s) {
  queue<int> q;
  q.push(s);
  height[s] = 0;
  vis[s] = true;
  while (!q.empty()) {
    int p = q.front();
    q.pop();
    for (int i = 0; i < node[p].size(); i++) {
      if (vis[node[p][i]] == false) {
        height[node[p][i]] = height[p] + 1;
        q.push(node[p][i]);
        vis[node[p][i]] = true;
      }
    }
  }
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  long long n, m;
  cin >> n >> m;
  vector<string> gp;
  for (long long i = 0; i < n; i++) {
    string s;
    cin >> s;
    gp.push_back(s);
  }
  for (long long i = 0; i < n; i++) {
    for (long long j = 0; j < m; j++) {
      if (gp[i][j] == '.') {
        if (i + 1 < n && gp[i + 1][j] == '.')
          node[i * m + j].push_back((i + 1) * m + j);
        if (j + 1 < m && gp[i][j + 1] == '.')
          node[i * m + j].push_back(i * m + j + 1);
        if (i - 1 >= 0 && gp[i - 1][j] == '.')
          node[i * m + j].push_back((i - 1) * m + j);
        if (j - 1 >= 0 && gp[i][j - 1] == '.')
          node[i * m + j].push_back(i * m + j - 1);
      }
    }
  }
  bool flag = 0;
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      if (!flag && gp[i][j] == '.') {
        flag = 1;
        bfs(i * m + j);
        break;
      }
    }
    if (flag) break;
  }
  long long index = 0;
  long long maxi = -1;
  for (long long i = 0; i < n * m; i++) {
    if (height[i] > maxi) {
      maxi = height[i];
      index = i;
    }
    height[i] = 0;
    vis[i] = 0;
  }
  bfs(index);
  long long ans = 0;
  for (long long i = 0; i < n * m; i++) {
    ans = max(ans, height[i]);
  }
  cout << ans << endl;
  return 0;
}
