#include <bits/stdc++.h>
using namespace std;
int main() {
  int H, W;
  cin >> H >> W;
  string S[H];
  for (int i = 0; i < (H); i++) cin >> S[i];
  queue<pair<int, int>> q;
  pair<int, int> init;
  bool found = false;
  for (int row = 0; row < (H); row++) {
    for (int col = 0; col < (W); col++) {
      if (S[row][col] == '.') {
        init = make_pair(row, col);
        found = true;
        break;
      }
    }
    if (found) break;
  }
  int to_x[4] = {0, 0, 1, -1};
  int to_y[4] = {1, -1, 0, 0};
  vector<vector<int>> dist(H, vector<int>(W, -1));
  q.push(init);
  dist[init.first][init.second] = 0;
  while (!q.empty()) {
    auto now = q.front();
    q.pop();
    for (int to = 0; to < 4; to++) {
      int y = now.first + to_y[to], x = now.second + to_x[to];
      if (y < 0 || y >= H || x < 0 || x >= W) continue;
      if (S[y][x] == '.' &&
          (dist[y][x] == -1 || dist[y][x] > dist[now.first][now.second] + 1)) {
        q.push({y, x});
        dist[y][x] = dist[now.first][now.second] + 1;
      }
    }
  }
  int max_dist = 0;
  for (int row = 0; row < (H); row++)
    for (int col = 0; col < (W); col++) {
      if (dist[row][col] > max_dist) {
        max_dist = dist[row][col];
        init = make_pair(row, col);
      }
    }
  vector<vector<int>> dist2(H, vector<int>(W, -1));
  q.push(init);
  dist2[init.first][init.second] = 0;
  while (!q.empty()) {
    auto now = q.front();
    q.pop();
    for (int to = 0; to < 4; to++) {
      int y = now.first + to_y[to], x = now.second + to_x[to];
      if (y < 0 || y >= H || x < 0 || x >= W) continue;
      if (S[y][x] == '.' && (dist2[y][x] == -1 ||
                             dist2[y][x] > dist2[now.first][now.second] + 1)) {
        q.push({y, x});
        dist2[y][x] = dist2[now.first][now.second] + 1;
      }
    }
  }
  for (int row = 0; row < (H); row++)
    for (int col = 0; col < (W); col++) {
      if (dist2[row][col] > max_dist) {
        max_dist = dist2[row][col];
      }
    }
  cout << max_dist << endl;
  return 0;
}
