#include <bits/stdc++.h>
using namespace std;
const long long INF = 1e18;
const long long dh[4] = {1, 0, -1, 0};
const long long dw[4] = {0, 1, 0, -1};
long long H, W;
vector<string> maze;
long long bfs(long long sh, long long sw, long long gh, long long gw) {
  long long seen[25][25];
  long long dist[25][25];
  for (long long i = 0; i < 25; i++) {
    for (long long j = 0; j < 25; j++) {
      seen[i][j] = false;
      dist[i][j] = INF;
    }
  }
  seen[sh][sw] = true;
  dist[sh][sw] = 0;
  queue<pair<long long, long long>> que;
  que.push(make_pair(sh, sw));
  while (!que.empty()) {
    auto now = que.front();
    que.pop();
    long long nowh = now.first;
    long long noww = now.second;
    cout << 234 << endl;
    for (long long i = 0; i < 4; i++) {
      long long newh = nowh + dh[i];
      long long neww = neww + dw[i];
      bool isHOK = (0 <= newh && newh < H);
      bool isWOK = (0 <= neww && neww < W);
      if (!(isHOK && isWOK)) continue;
      if (maze[newh][neww] == '#') continue;
      if (seen[newh][neww]) continue;
      seen[newh][neww] = true;
      dist[newh][neww] = dist[nowh][noww] + 1;
      que.push(make_pair(newh, neww));
    }
    seen[nowh][noww] = true;
  }
  return ((dist[gh][gw] == INF) ? -1 : dist[gh][gw]);
}
void solve() {
  std::ifstream in("sample.txt");
  std::cin.rdbuf(in.rdbuf());
  cin.tie(0);
  ios::sync_with_stdio(false);
  cin >> H >> W;
  maze.resize(H);
  for (size_t h = (0); h < (H); ++h) cin >> maze[h];
  long long ans = 0;
  for (long long sh = 0; sh < H; sh++) {
    for (long long sw = 0; sw < W; sw++) {
      for (long long gh = 0; gh < H; gh++) {
        for (long long gw = 0; gw < W; gw++) {
          if (maze[sh][sw] == '#') continue;
          if (maze[gh][gw] == '#') continue;
          ans = max(ans, bfs(sh, sw, gh, gw));
        }
      }
    }
  }
  cout << ans << endl;
}
signed main() {
  solve();
  return 0;
}
