#include <bits/stdc++.h>
using namespace std;
const long long int INF = 1LL << 60;
const int inf = (1 << 30);
const int MOD = 1000000007;
long long int n, k, ans = 0, h = 1, W, sum = 0, p;
template <typename A, size_t N, typename T>
void Fill(A (&array)[N], const T& val) {
  std::fill((T*)array, (T*)(array + N), val);
}
struct Corr {
  int x;
  int y;
  int depth;
};
queue<Corr> q;
long long int bfs(vector<vector<char>> grid, int i, int j) {
  Corr sta = {j, i, 0};
  vector<vector<int>> ispassed(grid.size(), vector<int>(grid[0].size(), false));
  int dx[8] = {1, 0, -1, 0};
  int dy[8] = {0, 1, 0, -1};
  int sd = 0;
  q.push(sta);
  while (!q.empty()) {
    Corr now = q.front();
    q.pop();
    sd = max(sd, now.depth);
    for (int i = 0; i < 4; i++) {
      int nextx = now.x + dx[i];
      int nexty = now.y + dy[i];
      if (nextx >= grid[0].size() || nextx < 0) continue;
      if (nexty >= grid.size() || nexty < 0) continue;
      if (ispassed[nexty][nextx]) continue;
      if (grid[nexty][nextx] == '#') continue;
      ispassed[nexty][nextx] = true;
      Corr next = {nextx, nexty, now.depth + 1};
      q.push(next);
    }
  }
  return sd;
}
int main() {
  int h, w;
  cin >> h >> w;
  vector<vector<char>> s(h, vector<char>(w));
  for (int i = 0; i < (int)(h); i++) {
    for (int j = 0; j < (int)(w); j++) {
      cin >> s[i][j];
    }
  }
  for (int i = 0; i < (int)(h); i++) {
    for (int j = 0; j < (int)(w); j++) {
      if (s[i][j] == '.') {
        ans = max(bfs(s, i, j), ans);
      }
    }
  }
  cout << ans << endl;
}
