#include <bits/stdc++.h>
using namespace std;
int H, W;
bool S[21][21];
bool visit[21][21];
struct pos {
  int h, w, d;
};
int solve(int h, int w) {
  fill(visit[0], visit[21], false);
  queue<pos> q;
  q.push(pos{h, w, 0});
  int m = 0;
  while (!q.empty()) {
    pos p = q.front();
    q.pop();
    visit[p.h][p.w] = true;
    m = max(m, p.d);
    if (p.w > 0 && S[p.h][p.w - 1] && !visit[p.h][p.w - 1]) {
      q.push(pos{p.h, p.w - 1, p.d + 1});
    }
    if (p.w < W - 1 && S[p.h][p.w + 1] && !visit[p.h][p.w + 1]) {
      q.push(pos{p.h, p.w + 1, p.d + 1});
    }
    if (p.h > 0 && S[p.h - 1][p.w] && !visit[p.h - 1][p.w]) {
      q.push(pos{p.h - 1, p.w, p.d + 1});
    }
    if (p.h < H - 1 && S[p.h + 1][p.w] && !visit[p.h + 1][p.w]) {
      q.push(pos{p.h + 1, p.w, p.d + 1});
    }
  }
  return m;
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cin >> H >> W;
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      char c;
      cin >> c;
      if (c == '.') {
        S[i][j] = true;
      }
    }
  }
  int ans = 0;
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      if (S[i][j]) {
        ans = max(ans, solve(i, j));
      }
    }
  }
  cout << ans << endl;
  return 0;
}
