#include <bits/stdc++.h>
using namespace std;
template <typename T>
inline bool chmax(T& a, T b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <typename T>
inline bool chmin(T& a, T b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}
const long long INF = 1LL << 60;
const int INT_INF = 1LL << 30;
int main() {
  int H, W;
  cin >> H >> W;
  vector<string> S(H);
  for (int i = 0; i < H; i++) {
    cin >> S.at(i);
  }
  vector<int> dx = {1, -1, 0, 0};
  vector<int> dy = {0, 0, 1, -1};
  int result = INT_INF;
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      if (S.at(i).at(j) == '#') continue;
      vector<vector<int>> way(H, vector<int>(W, INT_INF));
      way.at(i).at(j) = 0;
      vector<vector<bool>> flag(H, vector<bool>(W, false));
      flag.at(i).at(j) = true;
      queue<pair<int, int>> que;
      que.push(pair<int, int>(i, j));
      while (!que.empty()) {
        int y = que.front().first;
        int x = que.front().second;
        for (int k = 0; k < 4; k++) {
          int xx = x + dx.at(k);
          int yy = y + dy.at(k);
          if (xx < 0 || xx >= W || yy < 0 || yy >= H) continue;
          if (S.at(yy).at(xx) == '#' || flag.at(yy).at(xx)) continue;
          way.at(yy).at(xx) = way.at(y).at(x) + 1;
          chmax(result, way.at(yy).at(xx));
          que.push(pair<int, int>(yy, xx));
        }
      }
    }
  }
  cout << result << endl;
}
