#include <bits/stdc++.h>
using namespace std;
const int mod = 1e9 + 7;
const long long inf = 3e18 + 5;
int add(int a, int b) { return (a += b) < mod ? a : a - mod; }
int mul(int a, int b) { return 1LL * a * b % mod; }
int sub(int a, int b) { return (a -= b) < 0 ? a + mod : a; }
int ctz(int x) { return __builtin_ctz(x); }
int clz(int x) { return __builtin_clz(x); }
string g[21];
int done[21][21];
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  int n, m;
  cin >> n >> m;
  for (int i = 0; i < n; i++) {
    cin >> g[i];
  }
  const int dx[] = {-1, 0, 0, 1};
  const int dy[] = {0, -1, 1, 0};
  int res = 0;
  for (int si = 0; si < n; si++) {
    for (int sj = 0; sj < m; sj++) {
      for (int ti = 0; ti < n; ti++) {
        for (int tj = 0; tj < m; tj++) {
          if (si == ti && sj == tj) continue;
          queue<tuple<int, int, int>> q;
          q.emplace(0, si, sj);
          memset(done, 0, sizeof done);
          done[si][sj] = 1;
          while (!q.empty()) {
            int d, x, y;
            tie(d, x, y) = q.front();
            q.pop();
            if (x == ti && y == tj) {
              res = max(res, d);
              break;
            }
            for (int dir = 0; dir < 4; dir++) {
              int nx = x + dx[dir];
              int ny = y + dy[dir];
              if (nx < 0 || ny < 0 || nx >= n || ny >= m || done[nx][ny] ||
                  g[nx][ny] == '#')
                continue;
              done[nx][ny] = 1;
              q.emplace(d + 1, nx, ny);
            }
          }
        }
      }
    }
  }
  cout << res;
}
