#include <bits/stdc++.h>
using namespace std;
struct cww {
  cww() {
    ios::sync_with_stdio(false);
    cin.tie(0);
  }
} star;
const long long INF = numeric_limits<long long>::max();
int main() {
  int dx[] = {1, 0, -1, 0};
  int dy[] = {0, 1, 0, -1};
  int H, W;
  int ans = 0;
  cin >> H >> W;
  vector<vector<char>> S(W, vector<char>(H));
  vector<vector<int>> distance(W, vector<int>(H));
  for (int y = 0; y < (H); y++) {
    for (int x = 0; x < (W); x++) {
      cin >> S[x][y];
    }
  }
  vector<vector<bool>> arrived(W + 1, vector<bool>(H + 1));
  for (int y = 0; y < (H); y++) {
    for (int x = 0; x < (W); x++) {
      if (S[x][y] == '#') {
        continue;
      }
      pair<int, int> start = {x, y};
      for (int Y = 0; Y < (H); Y++) {
        for (int X = 0; X < (W); X++) {
          distance[X][Y] = -1;
          arrived[X][Y] = false;
        }
      }
      distance[x][y] = 0;
      queue<pair<int, int>> q;
      q.push(start);
      while (!q.empty()) {
        pair<int, int> now = q.front();
        int nowx = now.first;
        int nowy = now.second;
        int dis = distance[nowx][nowy];
        arrived[nowx][nowy] = true;
        q.pop();
        for (int k = 0; k < (4); k++) {
          if ((nowx + dx[k] < W and nowx + dx[k] >= 0 and nowy + dy[k] < H and
               nowy + dy[k] >= 0 and S[nowx + dx[k]][nowy + dy[k]] == '.') and
              arrived[nowx + dx[k]][nowy + dy[k]] == false) {
            q.push({nowx + dx[k], nowy + dy[k]});
            distance[nowx + dx[k]][nowy + dy[k]] = dis + 1;
          }
        }
      }
      for (int s = 0; s < (W); s++) {
        for (int t = 0; t < (H); t++) {
          ans = max(distance[s][t], ans);
        }
      }
    }
  }
  cout << ans;
  return 0;
}
