#include <bits/stdc++.h>
template <class T>
inline T chmax(T& a, const T b) {
  return a = (a < b) ? b : a;
}
template <class T>
inline T chmin(T& a, const T b) {
  return a = (a > b) ? b : a;
}
using ll = long long;
using ull = unsigned long long;
using ld = long double;
const ll MOD = 1000000007;
const ll INF = 1e18;
using namespace std;
ll H, W;
ll dx[4] = {0, 0, 1, -1};
ll dy[4] = {1, -1, 0, 0};
ll ans = 0;
vector<string> vec;
vector<vector<ll>> dist;
vector<vector<bool>> visited;
void dfs(ll x, ll y, ll depth) {
  if (dist[x][y] > depth) dist[x][y] = depth;
  for (ll i = 0; i < ll(4); ++i) {
    ll xx = x + dx[i];
    ll yy = y + dy[i];
    if ((0 <= xx && xx < H) && (0 <= yy && yy < W)) {
      if (visited[xx][yy]) continue;
      if (vec[xx][yy] == '#') continue;
      visited[xx][yy] = true;
      dfs(xx, yy, depth + 1);
      visited[xx][yy] = false;
    }
  }
}
signed main() {
  cin >> H >> W;
  vec = vector<string>(H);
  for (ll i = 0; i < ll(H); ++i) cin >> vec[i];
  for (ll i = 0; i < ll(H); ++i)
    for (ll j = 0; j < ll(W); ++j) {
      dist = vector<vector<ll>>(H, vector<ll>(W, INF));
      visited = vector<vector<bool>>(H, vector<bool>(W, false));
      dfs(i, j, 0);
      for (ll i = 0; i < ll(H); ++i)
        for (ll j = 0; j < ll(W); ++j) {
          if (dist[i][j] == INF) continue;
          chmax(ans, dist[i][j]);
        }
    }
  cout << ans << endl;
  return 0;
}
