#include <bits/stdc++.h>
using namespace std;
using pii = pair<int, int>;
using pll = pair<long long, long long>;
const long long INF = 1 << 29;
const int MOD = 1000000007;
long long ruizyou(long long m, long long n) {
  if (m == 0) return 0;
  if (m == 1) return 1;
  long long ans = 1;
  long long tmp = m;
  for (int i = 0; i <= 30; i++) {
    if (n & (1 << i)) {
      ans *= tmp;
      ans %= MOD;
    }
    tmp *= tmp;
    tmp %= MOD;
  }
  return ans;
}
long long kaizyou(long long x) {
  if (x == 0) return 1;
  return x * kaizyou(x - 1) % MOD;
}
long long comb(long long x, long long y) {
  long long bunsi = kaizyou(x);
  long long bunbo = kaizyou(x - y) * kaizyou(y) % MOD;
  return bunsi * ruizyou(bunbo, MOD - 2) % MOD;
}
struct unionfind {
  vector<int> par;
  vector<int> hukasa;
  unionfind(int n) {
    par = vector<int>(n);
    hukasa = vector<int>(n, 0);
    for (int i = 0; i < n; i++) {
      par.at(i) = i;
    }
  }
  int root(int x) {
    if (par.at(x) == x) return x;
    return root(par.at(x));
  }
  void unite(int x, int y) {
    int rx = root(x);
    int ry = root(y);
    if (rx == ry) return;
    if (hukasa.at(rx) >= hukasa.at(ry)) {
      par.at(ry) = rx;
      hukasa.at(rx) = max(hukasa.at(ry) + 1, hukasa.at(rx));
    } else {
      par.at(rx) = ry;
    }
  }
  bool same(int x, int y) { return root(x) == root(y); }
};
int ctoi(char a) { return a - '0'; }
long long gcd(long long a, long long b) {
  long long c = max(a, b);
  long long d = min(a, b);
  if (d % c == 0) return c;
  return gcd(c, d % c);
}
long long lcm(long long a, long long b) { return a * b / gcd(a, b); }
int main() {
  int h, w;
  cin >> h >> w;
  vector<vector<char>> s(h, vector<char>(w));
  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) cin >> s.at(i).at(j);
  }
  int ans = 0;
  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      vector<vector<int>> unko(h, vector<int>(w, -1));
      unko.at(i).at(j) = 0;
      queue<pii> q;
      q.push(pii(i, j));
      while (q.size() != 0) {
        pii p = q.front();
        q.pop();
        int px, py;
        tie(px, py) = p;
        set<pii> se;
        se.insert(pii(px - 1, py));
        se.insert(pii(px + 1, py));
        se.insert(pii(px, py - 1));
        se.insert(pii(px, py + 1));
        for (auto pp : se) {
          int x, y;
          tie(x, y) = pp;
          if (0 <= x && x < h && 0 <= y && y < w && unko.at(x).at(y) == -1 &&
              s.at(x).at(y) == '.') {
            unko.at(x).at(y) = unko.at(px).at(py) + 1;
            q.push(pii(x, y));
          }
        }
      }
      for (int k = 0; k < h; k++) {
        for (int l = 0; l < w; l++) ans = max(ans, unko.at(k).at(l));
      }
    }
  }
  cout << ans << endl;
}
