#include <bits/stdc++.h>
using namespace std;
const int N = 30;
int ans = -1;
int h, w;
int d[N];
int add[] = {1, -1, 0};
bool mark[N];
queue<int> bfsq;
vector<int> adj[N * N];
string s[N];
void bfs(int v) {
  bfsq.push(v);
  while (bfsq.size()) {
    v = bfsq.front();
    ans = max(ans, d[v]);
    bfsq.pop();
    for (int u : adj[v])
      if (mark[u])
        continue;
      else {
        d[u] = d[v] + 1;
        mark[u] = 1;
        bfsq.push(u);
      }
  }
}
bool check(int i, int j) { return (i < h && 0 <= i && j < w && 0 <= j); }
void set_adj() {
  for (int i = 0; i < h; i++)
    for (int j = 0; j < w; j++) {
      if (s[i][j] == '#') continue;
      for (int ai : add)
        for (int aj : add) {
          if (ai != 0 && aj != 0) continue;
          int hi = i + ai, hj = j + aj;
          if (check(hi, hj)) {
            if (s[hi][hj] == '#') continue;
            int v = i * w + j;
            int u = hi * w + hj;
            adj[v].push_back(u);
            adj[u].push_back(v);
          }
        }
    }
}
void vitex() {
  for (int i = 0; i < h * w; i++) mark[i] = 0;
}
int main() {
  cin >> h >> w;
  for (int i = 0; i < h; i++) cin >> s[i];
  set_adj();
  for (int i = 0; i < h * w; i++) d[i] = 0, bfs(i), vitex();
  cout << ans << endl;
  return 0;
}
