#include <bits/stdc++.h>
using namespace std;
using ll = long long;
ll MOD = 1e9 + 7;
ll devc(ll x, ll y) { return 1 + (x - 1) / y; }
char S[21][21];
ll func(ll sy, ll sx, ll gy, ll gx, ll H, ll W) {
  if (S[sy][sx] == '#' || S[gy][gx] == '#') return -1;
  struct point {
    ll y;
    ll x;
    ll counter;
  };
  queue<point> que;
  que.push({sy, sx, 0});
  ll ans = 0;
  while (!que.empty()) {
    point now = que.front();
    que.pop();
    if (now.y == gy && now.x == gx) {
      ans = now.counter;
      break;
    }
    if (now.y >= 1 && now.y <= H && now.x >= 1 && now.x <= W &&
        S[now.y][now.x] != '#') {
      que.push({now.y + 1, now.x, now.counter + 1});
      que.push({now.y - 1, now.x, now.counter + 1});
      que.push({now.y, now.x + 1, now.counter + 1});
      que.push({now.y, now.x - 1, now.counter + 1});
    }
  }
  return ans;
}
int main() {
  cin.tie(0);
  ios::sync_with_stdio(0);
  cout << fixed << setprecision(20);
  ll H, W;
  cin >> H >> W;
  for (ll i = 1; i <= (H); ++i)
    for (ll j = 1; j <= (W); ++j) cin >> S[i][j];
  ll ans = 0;
  for (ll sy = 1; sy <= (H); ++sy)
    for (ll sx = 1; sx <= (W); ++sx)
      for (ll gy = 1; gy <= (H); ++gy)
        for (ll gx = 1; gx <= (W); ++gx) {
          ll mv = func(sy, sx, gy, gx, H, W);
          ans = max(ans, mv);
        }
  cout << (ans) << '\n';
  return 0;
}
