#include <bits/stdc++.h>
using namespace std;
bool passed[410][410];
int ans;
int main() {
  cin.tie(nullptr);
  ios::sync_with_stdio(false);
  int H, W;
  cin >> H >> W;
  vector<string> S(H);
  queue<pair<int, int>> q;
  for (auto& s : S) cin >> s;
  for (int i = 0; i < H; ++i) {
    for (int j = 0; j < W; ++j) {
      q.push({i, j});
      int dist = 0;
      passed[i * W + j][j * W + j] = true;
      while (!q.empty()) {
        int size = q.size();
        ans = max(dist++, ans);
        while (size--) {
          auto f = q.front();
          q.pop();
          if (f.first != 0 && S[f.first - 1][f.second] != '#' &&
              !passed[i * W + j][(f.first - 1) * W + f.second]) {
            q.push({f.first - 1, f.second});
            passed[i * W + j][(f.first - 1) * W + f.second] = true;
          }
          if (f.second != 0 && S[f.first][f.second - 1] != '#' &&
              !passed[i * W + j][(f.first) * W + f.second - 1]) {
            q.push({f.first, f.second - 1});
            passed[i * W + j][(f.first) * W + f.second - 1] = true;
          }
          if (f.first != H - 1 && S[f.first + 1][f.second] != '#' &&
              !passed[i * W + j][(f.first + 1) * W + f.second]) {
            q.push({f.first + 1, f.second});
            passed[i * W + j][(f.first + 1) * W + f.second] = true;
          }
          if (f.second != W - 1 && S[f.first][f.second + 1] != '#' &&
              !passed[i * W + j][(f.first) * W + f.second + 1]) {
            q.push({f.first, f.second + 1});
            passed[i * W + j][(f.first) * W + f.second + 1] = true;
          }
        }
      }
    }
  }
  printf("%d\n", ans);
  return 0;
}
