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