#include <bits/stdc++.h>
using namespace std;
using II = pair<long long, long long>;
long long gcd(long long a, long long b) { return b != 0 ? gcd(b, a % b) : a; }
long long lcm(long long a, long long b) { return a * b / gcd(a, b); }
long long extgcd(long long a, long long b, long long &x, long long &y) {
  long long g = a;
  x = 1;
  y = 0;
  if (b != 0) g = extgcd(b, a % b, y, x), y -= (a / b) * x;
  return g;
}
const long long MAX_H = 21;
long long H, W;
char F[MAX_H][MAX_H];
bool canMove(long long x, long long y) {
  return 0 <= x && x < W && 0 <= y && y < H && F[y][x] != '#';
}
long long dx[] = {1, -1, 0, 0};
long long dy[] = {0, 0, 1, -1};
long long dist[MAX_H][MAX_H];
long long calc(long long x, long long y) {
  memset(dist, -1, sizeof(dist));
  dist[y][x] = 0;
  queue<II> que;
  que.push(II(x, y));
  long long ans = 0;
  while (que.size()) {
    II pos = que.front();
    que.pop();
    for (long long d = (0); d < (4); ++d) {
      long long nx = pos.first + dx[d];
      long long ny = pos.second + dy[d];
      if (canMove(nx, ny) && dist[ny][nx] == -1) {
        dist[ny][nx] = dist[pos.second][pos.first] + 1;
        ans = max(ans, dist[ny][nx]);
        que.push(II(nx, ny));
      }
    }
  }
  return ans;
}
signed main() {
  cin >> H >> W;
  for (long long h = (0); h < (H); ++h) {
    for (long long w = (0); w < (W); ++w) {
      cin >> F[h][w];
    }
  }
  long long ans = -1;
  for (long long h = (0); h < (H); ++h) {
    for (long long w = (0); w < (W); ++w) {
      ans = max(ans, calc(w, h));
    }
  }
  cout << ans << endl;
  return 0;
}
