#include <bits/stdc++.h>
using namespace std;
int h, w;
char s[30][30];
int pti(int x, int y) { return (x - 1) * w + y; }
vector<int> adj[1000];
int dis[1000];
bool vis[1000];
int st = 0, maxi = 0;
void bfs(int v) {
  queue<int> q;
  q.push(v);
  vis[v] = true;
  dis[v] = 0;
  while (!q.empty()) {
    int g = q.front();
    q.pop();
    for (auto it : adj[g])
      if (!vis[it]) {
        vis[it] = true;
        dis[it] = dis[g] + 1;
        q.push(it);
      }
  }
  return;
}
int main() {
  cin >> h >> w;
  for (int i = 1; i <= h; i++) {
    for (int j = 1; j <= w; j++) cin >> s[i][j];
  }
  for (int i = 1; i <= h; i++) {
    for (int j = 1; j <= w; j++) {
      if (s[i][j] == '.') {
        if (i + 1 <= h && s[i + 1][j] == '.') {
          adj[pti(i, j)].push_back(pti(i + 1, j));
          adj[pti(i + 1, j)].push_back(pti(i, j));
        }
        if (j + 1 <= w && s[i][j + 1] == '.') {
          adj[pti(i, j)].push_back(pti(i, j + 1));
          adj[pti(i, j + 1)].push_back(pti(i, j));
        }
      }
    }
  }
  int ans = 0;
  for (int i = 1; i <= h * w; i++) {
    if (s[(i / w) + 1][i % w] == '.') {
      bfs(i);
      for (int j = 1; j <= h * w; j++) {
        vis[j] = false;
        ans = max(ans, dis[j]);
        dis[j] = 0;
      }
    }
  }
  cout << ans;
}
