#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];
vector<pair<long long, long long> > v;
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;
  queue<pair<long long, long long> > q;
  vis.clear(), dis.clear();
  q.push({sx, sy});
  vis[{sx, sy}] = 1;
  while (!q.empty()) {
    pair<long long, long long> now = q.front();
    q.pop();
    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];
      if (m[i][j] != '#') v.push_back({i, j});
    }
  }
  int ans = 0;
  for (int i = 0; i < v.size(); i++) {
    for (int j = i; j < v.size(); j++) {
      int tmp = bfs(v[i].first, v[i].second, v[j].first, v[j].second);
      ans = max(ans, tmp);
    }
  }
  cout << ans << endl;
  return 0;
}
