#include <bits/stdc++.h>
using namespace std;
void search_start(vector<vector<int>> &dis_map, int &H, int &W, int y, int x,
                  int dis) {
  if (y < 0 || y > H - 1 || x < 0 || x > W - 1)
    return;
  else if (dis_map.at(y).at(x) == -1 || dis_map.at(y).at(x) <= dis)
    return;
  else {
    dis_map.at(y).at(x) = dis;
    search_start(dis_map, H, W, y, x + 1, dis + 1);
    search_start(dis_map, H, W, y + 1, x, dis + 1);
    search_start(dis_map, H, W, y, x - 1, dis + 1);
    search_start(dis_map, H, W, y - 1, x, dis + 1);
  }
}
int main() {
  int H, W;
  cin >> H >> W;
  vector<vector<char>> S(H, vector<char>(W));
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      cin >> S.at(i).at(j);
    }
  }
  vector<vector<int>> dis_map(H, vector<int>(W, -1));
  vector<vector<int>> dis_map_2(H, vector<int>(W, -1));
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      if (S.at(i).at(j) == '.') {
        dis_map.at(i).at(j) = 500;
        dis_map_2.at(i).at(j) = 500;
      }
    }
  }
  pair<int, int> yx;
  bool check = false;
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      if (S.at(i).at(j) == '.') {
        yx.first = i;
        yx.second = j;
        check = true;
        break;
      }
    }
    if (check) break;
  }
  search_start(dis_map, H, W, yx.first, yx.second, 0);
  int Max = -1;
  pair<int, int> start_yx;
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      if (Max < dis_map.at(i).at(j)) {
        Max = dis_map.at(i).at(j);
        start_yx.first = i;
        start_yx.second = j;
      }
    }
  }
  search_start(dis_map_2, H, W, start_yx.first, start_yx.second, 0);
  int ans_Max = -1;
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      ans_Max = max(dis_map_2.at(i).at(j), ans_Max);
    }
  }
  cout << ans_Max << endl;
}
