#include <bits/stdc++.h>
using namespace std;
const int INF = 1e9;
template <class T, class U>
ostream& operator<<(ostream& o, const pair<T, U>& p) {
  o << "(" << p.first << ", " << p.second << ")";
  return o;
}
int Y, X;
vector<string> s;
int dy[4] = {-1, 0, +1, 0};
int dx[4] = {0, -1, 0, +1};
int solve(int sy, int sx, int gy, int gx) {
  using P = pair<int, int>;
  if (s[sy][sx] == '#' || s[gy][gx] == '#') return 0;
  if (sy == gy && sx == gx) return 0;
  queue<P> qu;
  vector<vector<int>> cost(Y, vector<int>(X, INF));
  qu.push({sy, sx});
  cost[sy][sx] = 0;
  int count = 0;
  while (qu.size()) {
    if (count++ == 20) break;
    P top = qu.front();
    qu.pop();
    int y = top.first;
    int x = top.second;
    if (y == gy && x == gx) return cost[y][x];
    for (int i = 0; i < int(4); ++i) {
      int ny = y + dy[i], nx = x + dx[i];
      if (ny < 0 || ny >= Y || nx < 0 || nx >= X) continue;
      if (s[ny][nx] == '#') continue;
      if (cost[ny][nx] > cost[y][x] + 1) {
        cost[ny][nx] = cost[y][x] + 1;
        qu.push({ny, nx});
      }
    }
  }
  assert(false);
}
int main(void) {
  cin >> Y >> X;
  s.resize(Y);
  for (int y = 0; y < int(Y); ++y) {
    cin >> s[y];
  }
  int res = 0;
  for (int sy = 0; sy < int(Y); ++sy)
    for (int sx = 0; sx < int(X); ++sx)
      for (int gy = 0; gy < int(Y); ++gy)
        for (int gx = 0; gx < int(X); ++gx) {
          res = max(res, solve(sy, sx, gy, gx));
        }
  cout << res << endl;
  return 0;
}
