#include <bits/stdc++.h>
using namespace std;
int main() {
  long long H, W;
  cin >> H >> W;
  vector<string> S;
  for (int(i) = 0; (i) < (H); ++(i)) {
    string s;
    cin >> s;
    S.push_back(s);
  }
  map<pair<long long, long long>, vector<pair<long long, long long>>> G;
  vector<pair<long long, long long>> road;
  for (int(i) = 0; (i) < (H); ++(i)) {
    for (int(j) = 0; (j) < (W); ++(j)) {
      pair<long long, long long> p = make_pair(i, j);
      if (S[i][j] == '.') {
        if (i - 1 >= 0)
          if (S[i - 1][j] == '.') G[p].push_back(make_pair(i - 1, j));
        if (j - 1 >= 0)
          if (S[i][j - 1] == '.') G[p].push_back(make_pair(i, j - 1));
        if (i + 1 < H)
          if (S[i + 1][j] == '.') G[p].push_back(make_pair(i + 1, j));
        if (j + 1 < W)
          if (S[i][j + 1] == '.') G[p].push_back(make_pair(i, j + 1));
        road.push_back(p);
      }
    }
  }
  long long ans = 0;
  for (long long i = 0; i < road.size() - 1; ++i) {
    for (long long j = i + 1; j < road.size(); ++j) {
      pair<long long, long long> st = road[i];
      bool isDestination = false;
      queue<pair<long long, long long>> q;
      q.push(st);
      map<pair<long long, long long>, bool> visited;
      map<pair<long long, long long>, long long> dist;
      dist[st] = 0;
      while (!q.empty()) {
        pair<long long, long long> p = q.front();
        q.pop();
        visited[p] = true;
        for (auto(iter) = (G[p]).begin(); (iter) != (G[p]).end(); ++(iter)) {
          if (visited.find(*iter) == visited.end()) {
            visited[*iter] = true;
            q.push(*iter);
            dist[*iter] = dist[p] + 1;
            if (*iter == road[j]) {
              isDestination = true;
              break;
            }
          }
        }
        if (isDestination) {
          ans = max(ans, dist[road[j]]);
          break;
        }
      }
    }
  }
  cout << ans << endl;
}
