#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using P = pair<ll, ll>;
template <class T>
bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T>
bool chmin(T &a, const T &b) {
  if (b < a) {
    a = b;
    return 1;
  }
  return 0;
}
const ll MOD = 100000007;
const ll INF = 10e9;
vector<ll> dx = {1, 0, -1, 0};
vector<ll> dy = {0, 1, 0, -1};
int main() {
  ll H;
  cin >> H;
  ;
  ll W;
  cin >> W;
  ;
  vector<string> maze(H);
  for (ll i = 0; i < (int)(H); i++) {
    cin >> maze[i];
  };
  ll ans = 0;
  vector<vector<ll>> d(H, vector<ll>(W, INF));
  queue<P> que;
  for (ll i = 0; i < (int)(H); i++) {
    for (ll j = 0; j < (int)(W); j++) {
      if (d.at(i).at(j) == INF) continue;
      vector<vector<ll>> d2 = d;
      que.push(P(i, j));
      d2.at(i).at(j) = 0;
      while (que.size()) {
        P p = que.front();
        que.pop();
        for (ll k = 0; k < (int)(4); k++) {
          ll ny = p.first + dy.at(k);
          ll nx = p.second + dx.at(k);
          if (0 <= ny && ny < H && 0 <= nx && nx < W &&
              maze.at(ny).at(nx) != '#' && d.at(ny).at(nx) == INF) {
            que.push(P(ny, nx));
            d2.at(ny).at(nx) = d2.at(p.first).at(p.second) + 1;
            chmax(ans, d2.at(ny).at(nx));
          }
        }
      }
    }
  }
  cout << ans << endl;
}
