#include <bits/stdc++.h>
using namespace std;
const long long mod = 1000000007;
const long long inf = 10e17;
const long double eps = 10e-9;
long long solve(void);
long long gcd(long long x, long long y);
int main(void) {
  while (solve()) {
  }
  return 0;
}
long long mulmod(long long x, long long y) { return (x * y) % mod; }
long long submod(long long x, long long y) { return (x - y + 100 * mod) % mod; }
long long power(long long n, long long r) {
  if (r == 0) {
    return 1;
  }
  if (r == 1) {
    return n;
  }
  if (n == 0) {
    return 0;
  }
  if (n == 1) {
    return 1;
  }
  if (r % 2 == 0) {
    long long y = power(n, r / 2);
    return mulmod(y, y);
  } else {
    long long y = power(n, (r - 1) / 2);
    return n * mulmod(y, y) % mod;
  }
}
long long gcd(long long x, long long y) {
  if (y == 1) {
    return 1;
  }
  if (x % y == 0) {
    return y;
  }
  return gcd(y, x % y);
}
vector<long long> perm;
vector<long long> inv;
void init_inv(long long m) {
  perm.resize(m);
  inv.resize(m);
  perm[0] = 1;
  inv[0] = 1;
  for (long long i = 1; i < m; i++) {
    perm[i] = mulmod(perm[i - 1], i);
  }
  for (long long i = 1; i < m; i++) {
    inv[i] = power(perm[i], mod - 2);
  }
}
long long ncr(long long n, long long r) {
  if (r == n || r == 0) {
    return 1;
  }
  long long ans = 1;
  return mulmod(perm[n], mulmod(inv[n - r], inv[r]));
}
long long h, w;
bool iswall(vector<vector<bool>> s, pair<long long, long long> pl) {
  if (pl.first < 0 || pl.first >= h) {
    return true;
  }
  if (pl.second < 0 || pl.second >= w) {
    return true;
  }
  return s[pl.first][pl.second];
}
long long func(vector<vector<bool>> s, pair<long long, long long> start,
               pair<long long, long long> end) {
  if (iswall(s, start) || iswall(s, end)) {
    return 0;
  }
  queue<pair<long long, long long>> q;
  q.push(start);
  vector<vector<long long>> d(h, vector<long long>(w, 0));
  vector<vector<bool>> v(h, vector<bool>(w, false));
  vector<pair<long long, long long>> mv = {
      pair<long long, long long>(1, 0), pair<long long, long long>(0, 1),
      pair<long long, long long>(-1, 0), pair<long long, long long>(0, -1)};
  v[start.first][start.second] = true;
  while (!q.empty()) {
    auto qf = q.front();
    auto df = d[qf.first][qf.second];
    q.pop();
    for (auto m : mv) {
      auto n =
          pair<long long, long long>(m.first + qf.first, m.second + qf.second);
      auto nd = df + 1;
      if (!iswall(s, n) && (!v[n.first][n.second])) {
        v[n.first][n.second] = true;
        d[n.first][n.second] = nd;
        q.push(n);
      }
    }
  }
  return d[end.first][end.second];
}
long long solve(void) {
  cin >> h >> w;
  vector<vector<bool>> s(h, vector<bool>(w, false));
  for (long long i = 0; i < h; i++) {
    string si;
    cin >> si;
    for (long long j = 0; j < si.length(); j++) {
      s[i][j] = (si[j] == '#');
    }
  }
  long long ans = 0;
  for (long long i = 0; i < h; i++)
    for (long long j = 0; j < w; j++)
      for (long long k = 0; k < h; k++)
        for (long long l = 0; l < w; l++) {
          pair<long long, long long> start(i, j);
          pair<long long, long long> end(k, l);
          long long c = func(s, start, end);
          ans = max(ans, c);
        }
  cout << ans << endl;
  return 0;
}
