#include <bits/stdc++.h>
using namespace std;
const int N = 25;
const int MOD = 1e9 + 7;
const double PI = 2 * acos(0.0);
const int dx[] = {0, 1, 0, -1};
const int dy[] = {1, 0, -1, 0};
int h, w;
char m[N][N];
map<pair<long long, long long>, int> vis, dis;
map<pair<pair<long long, long long>, pair<long long, long long> >, int> done;
struct compare {
  bool operator()(const pair<long long, long long> &l,
                  const pair<long long, long long> &r) {
    return dis[{l.first, l.second}] > dis[{r.first, r.second}];
  }
};
bool ok(int x, int y) {
  return (x >= 0 && x < h) && (y >= 0 && y < w) && m[x][y] != '#';
}
int bfs(int sx, int sy, int tx, int ty) {
  if (m[sx][sy] == '#' || m[tx][ty] == '#') return -1;
  priority_queue<pair<long long, long long>,
                 vector<pair<long long, long long> >, compare>
      q;
  vis.clear(), dis.clear();
  q.push({sx, sy});
  vis[{sx, sy}] = 1;
  while (!q.empty()) {
    pair<long long, long long> now = q.top();
    q.pop();
    if (now.first == tx && now.second == ty) {
      break;
    }
    for (int i = 0; i < 4; i++) {
      int nx = dx[i] + now.first;
      int ny = dy[i] + now.second;
      if (!ok(nx, ny)) continue;
      if (vis[{nx, ny}] == 0) {
        vis[{nx, ny}] = 1;
        dis[{nx, ny}] = dis[{now.first, now.second}] + 1;
        q.push({nx, ny});
      }
    }
  }
  return dis[{tx, ty}];
}
int main() {
  cin >> h >> w;
  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      cin >> m[i][j];
    }
  }
  int ans = 0;
  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      for (int k = 0; k < h; k++) {
        for (int x = 0; x < w; x++) {
          if (done[{{i, j}, {k, x}}]) continue;
          int tmp = bfs(i, j, k, x);
          ans = max(ans, tmp);
          done[{{i, j}, {k, x}}] = 1;
          done[{{k, x}, {i, j}}] = 1;
        }
      }
    }
  }
  cout << ans << endl;
  return 0;
}
