#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using P = pair<ll, ll>;
using Vec = vector<ll>;
using VecP = vector<P>;
using VecB = vector<bool>;
using VecC = vector<char>;
using VecD = vector<double>;
using VecS = vector<string>;
using VecVec = vector<Vec>;
using Tree = vector<VecP>;
template <typename T>
using Vec1 = vector<T>;
template <typename T>
using Vec2 = vector<vector<T> >;
template <typename T>
bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <typename T>
bool chmin(T &a, const T &b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
template <typename T>
void co(const T n) {
  cout << n << endl;
}
template <typename T>
void cosp(const T n) {
  cout << n << ' ';
}
void coVec(const Vec &v) {
  for (ll i : v) cosp(i);
  cout << endl;
}
void sonic() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
}
void setp(const ll n) { cout << fixed << setprecision(n); }
const ll INF = 1e9 + 1;
const ll LINF = 1e18 + 1;
const ll MOD = 1e9 + 7;
const double PI = acos(-1);
const double EPS = 1e-9;
ll h, w;
VecS s;
VecVec dist;
void init() {
  for (ll(i) = (0); (i) < (h); ++(i))
    fill((dist[i]).begin(), (dist[i]).end(), LINF);
}
void wfs(ll x, ll y) {
  queue<P> que;
  que.push({x * w + y, 0});
  while (!que.empty()) {
    P p = que.front();
    que.pop();
    ll x1 = p.first / w, y1 = p.first % w;
    dist[x1][y1] = p.second;
    if (x1 - 1 >= 0 && s[x1 - 1][y1] == '.' && dist[x1 - 1][y1] == LINF)
      que.push({(x1 - 1) * w + y1, p.second + 1});
    if (y1 - 1 >= 0 && s[x1][y1 - 1] == '.' && dist[x1][y1 - 1] == LINF)
      que.push({x1 * w + y1 - 1, p.second + 1});
    if (x1 + 1 < h && s[x1 + 1][y1] == '.' && dist[x1 + 1][y1] == LINF)
      que.push({(x1 + 1) * w + y1, p.second + 1});
    if (y1 + 1 < w && s[x1][y1 + 1] == '.' && dist[x1][y1 + 1] == LINF)
      que.push({x1 * w + y1 + 1, p.second + 1});
  }
}
ll maxDist() {
  ll res = 0;
  for (ll(i) = (0); (i) < (h); ++(i)) {
    for (ll(j) = (0); (j) < (w); ++(j))
      if (dist[i][j] != LINF) chmax(res, dist[i][j]);
  }
  return res;
}
int main(void) {
  cin >> h >> w;
  s.resize(h);
  for (ll(i) = (0); (i) < (h); ++(i)) cin >> s[i];
  dist.resize(h);
  for (ll(i) = (0); (i) < (h); ++(i)) dist[i].resize(w);
  ll ans = 0;
  for (ll(i) = (0); (i) < (h); ++(i)) {
    for (ll(j) = (0); (j) < (w); ++(j))
      if (s[i][j] == '.') {
        init();
        wfs(i, j);
        chmax(ans, maxDist());
      }
  }
  co(ans);
  return 0;
}
