#include <bits/stdc++.h>
using namespace std;
const long long INF = 1LL << 60;
const long long MOD = 1e9 + 7;
template <class T>
inline bool chmin(T& a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
template <class T>
inline bool chmax(T& a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
struct Edge {
  long long to, cap, rev;
  Edge(long long _to, long long _cap, long long _rev) {
    to = _to;
    cap = _cap;
    rev = _rev;
  }
};
void add_edge(vector<vector<Edge> >& G, long long from, long long to,
              long long cap, bool revFlag, long long revCap) {
  G[from].push_back(Edge(to, cap, (long long)G[to].size()));
  if (revFlag)
    G[to].push_back(Edge(from, revCap, (long long)G[from].size() - 1));
}
long long mod_pow(long long x, long long n, long long mod) {
  long long res = 1LL;
  while (n > 0) {
    if (n & 1) res = res * x % mod;
    x = x * x % mod;
    n >>= 1;
  }
  return res;
}
long long mod_inv(long long x, long long mod) {
  return mod_pow(x, mod - 2, mod);
}
void WarshallFloyd(vector<vector<Edge> >& G, vector<vector<long long> >& d) {
  d.resize(G.size());
  for (long long(i) = 0; (i) < (d.size()); (i)++) d[i].resize(G.size());
  for (long long(i) = 0; (i) < (d.size()); (i)++) {
    for (long long(j) = 0; (j) < (d[i].size()); (j)++) {
      d[i][j] = INF;
    }
  }
  for (long long(i) = 0; (i) < (G.size()); (i)++) {
    for (long long(j) = 0; (j) < (G[i].size()); (j)++) {
      d[i][G[i][j].to] = G[i][j].cap;
    }
  }
  for (long long(i) = 0; (i) < (G.size()); (i)++) {
    for (long long(j) = 0; (j) < (G.size()); (j)++) {
      for (long long(k) = 0; (k) < (G.size()); (k)++) {
        chmin(d[j][k], d[j][i] + d[i][k]);
      }
    }
  }
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  cout.tie(nullptr);
  long long h, w;
  cin >> h >> w;
  vector<string> s(h);
  for (long long(i) = 0; (i) < (h); (i)++) cin >> s[i];
  vector<vector<Edge> > g(h * w);
  for (long long(i) = 0; (i) < (h); (i)++) {
    for (long long(j) = 0; (j) < (w); (j)++) {
      if (s[i][j] == '.') {
        if (i - 1 >= 0 && s[i - 1][j] == '.')
          add_edge(g, i * w + j, (i - 1) * w + j, 1, false, 1);
        if (i + 1 < h && s[i + 1][j] == '.')
          add_edge(g, i * w + j, (i + 1) * w + j, 1, false, 1);
        if (j - 1 >= 0 && s[i][j - 1] == '.')
          add_edge(g, i * w + j, i * w + j - 1, 1, false, 1);
        if (j + 1 < w && s[i][j + 1] == '.')
          add_edge(g, i * w + j, i * w + j + 1, 1, false, 1);
      }
    }
  }
  vector<vector<long long> > d;
  WarshallFloyd(g, d);
  long long ans = 0;
  for (long long(i) = 0; (i) < (h * w); (i)++) {
    for (long long(j) = 0; (j) < (h * w); (j)++) {
      if (d[i][j] != INF) chmax(ans, d[i][j]);
    }
  }
  cout << ans << endl;
  return 0;
}
