#include <bits/stdc++.h>
using namespace std;
using ll = long long;
ll H, W;
ll WALL = -1;
ll BFS(vector<vector<ll>> cost, ll x, ll y) {
  vector<ll> dist_x = {1, -1, 0, 0};
  vector<ll> dist_y = {0, 0, 1, -1};
  queue<pair<ll, ll>> que;
  que.push({x, y});
  cost[x][y] = 0;
  ll ans = 0;
  while (!que.empty()) {
    pair<ll, ll> q = que.front();
    que.pop();
    for (ll(i) = (0); (i) < (dist_x.size()); ++(i)) {
      ll next_x = q.first + dist_x[i];
      ll next_y = q.second + dist_y[i];
      if (next_x >= 0 && next_x < H && next_y >= 0 && next_y < W) {
        if (cost[next_x][next_y] == INT_MAX) {
          cost[next_x][next_y] = cost[q.first][q.second] + 1;
          ans = max(ans, cost[next_x][next_y]);
          que.push({next_x, next_y});
        }
      }
    }
  }
  return ans;
}
int main(void) {
  cin >> H >> W;
  char s;
  vector<vector<ll>> cost(H, vector<ll>(W, INT_MAX));
  for (ll(i) = (0); (i) < (H); ++(i)) {
    for (ll(j) = (0); (j) < (W); ++(j)) {
      cin >> s;
      if (s == '#') cost[i][j] = WALL;
    }
  }
  ll ans = 0;
  for (ll(i) = (0); (i) < (H); ++(i)) {
    for (ll(j) = (0); (j) < (W); ++(j)) {
      ans = max(ans, BFS(cost, i, j));
    }
  }
  cout << ans << endl;
}
