#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ii = pair<ll, ll>;
using iii = tuple<int, int, int>;
const int MAX{30};
const int oo{1000000007};
int found[MAX][MAX];
const vector<ii> dirs{ii(1, 0), ii(-1, 0), ii(0, 1), ii(0, -1)};
int maxdist(int x, int y, int H, int W, const vector<string>& xs) {
  for (int i = 0; i < H; ++i)
    for (int j = 0; j < W; ++j) found[i][j] = false;
  queue<iii> q;
  int ans = 0;
  q.push(iii(x, y, 0));
  found[x][y] = true;
  while (not q.empty()) {
    auto [i, j, d] = q.front();
    q.pop();
    ans = max(ans, d);
    for (auto dir : dirs) {
      auto u = i + dir.first, v = j + dir.second;
      if (u >= 0 and u < H and v >= 0 and v < W and not found[u][v] and
          xs[u][v] == '.') {
        q.push(iii(u, v, d + 1));
        found[u][v] = true;
      }
    }
  }
  return ans;
}
int solve(int H, int W, const vector<string>& xs) {
  int ans = 0;
  for (int i = 0; i < H; ++i)
    for (int j = 0; j < W; ++j)
      if (xs[i][j] == '.') ans = max(ans, maxdist(i, j, H, W, xs));
  return ans;
}
int main() {
  ios::sync_with_stdio(false);
  int H, W;
  cin >> H >> W;
  vector<string> xs(H);
  for (int i = 0; i < H; ++i) cin >> xs[i];
  auto ans = solve(H, W, xs);
  cout << ans << '\n';
  return 0;
}
