#include <bits/stdc++.h>
using namespace std;
typedef struct Point_Coordinates {
  int x, y;
} point;
queue<point> que;
void BFS(point n, vector<string>& mp, vector<vector<int>>& ans) {
  int x = n.x, y = n.y;
  if (x > 0 && mp[y][x - 1] == '.') {
    que.push({x - 1, y});
    mp[y][x - 1] = '#';
    ans[y][x - 1] = ans[y][x] + 1;
  }
  if (y > 0 && mp[y - 1][x] == '.') {
    que.push({x, y - 1});
    mp[y - 1][x] = '#';
    ans[y - 1][x] = ans[y][x] + 1;
  }
  if (x < mp[0].size() - 1 && mp[y][x + 1] == '.') {
    que.push({x + 1, y});
    mp[y][x + 1] = '#';
    ans[y][x + 1] = ans[y][x] + 1;
  }
  if (y < mp.size() - 1 && mp[y + 1][x] == '.') {
    que.push({x, y + 1});
    mp[y + 1][x] = '#';
    ans[y + 1][x] = ans[y][x] + 1;
  }
  if (que.empty()) return;
  n = que.front();
  que.pop();
  BFS(n, mp, ans);
  return;
}
int main(void) {
  int num, i, j, h, w, a, b, ans = 0;
  cin >> h >> w;
  vector<string> s(h), buf(h);
  for (i = 0; i < (h); i++) cin >> s[i];
  for (j = 0; j < (h); j++) {
    for (i = 0; i < (w); i++) {
      if (s[j][i] == '.') {
        buf = s;
        vector<vector<int>> d(h, vector<int>(w, 0));
        BFS({i, j}, buf, d);
        for (a = 0; a < (h); a++) {
          for (b = 0; b < (w); b++) {
            ans = max(ans, d[a][b]);
          }
        }
      }
    }
  }
  cout << ans << "\n";
  return 0;
}
