#include <bits/stdc++.h>
using namespace std;
int dh[] = {1, 0, -1, 0}, dw[] = {0, 1, 0, -1};
pair<pair<int, int>, int> longest_point_dist(pair<int, int> first,
                                             vector<string> field) {
  int H = field.size(), W = field[0].size();
  vector<vector<int>> dist(H, vector<int>(W, 100000));
  queue<pair<pair<int, int>, int>> que;
  dist[first.first][first.second] = 0;
  que.push(make_pair(first, 0));
  while (!que.empty()) {
    pair<pair<int, int>, int> now = que.front();
    que.pop();
    int now_dist = now.second;
    pair<int, int> now_point = now.first;
    for (int i = 0; i < 4; i++) {
      int h = now_point.first + dh[i], w = now_point.second + dw[i];
      if (h >= 0 && h < H && w >= 0 && w < W && field[h][w] == '.' &&
          dist[h][w] == 1000) {
        dist[h][w] = now_dist + 1;
        que.push(make_pair(make_pair(h, w), now_dist + 1));
      }
    }
  }
  pair<int, int> ret_point = make_pair(0, 0);
  int ret_dist = 0;
  for (int h = 0; h < H; h++) {
    for (int w = 0; w < W; w++) {
      if (dist[h][w] != 1000 && dist[h][w] > ret_dist) {
        ret_point = make_pair(h, w);
        ret_dist = dist[h][w];
      }
    }
  }
  return make_pair(ret_point, ret_dist);
}
int main() {
  int H, W;
  cin >> H >> W;
  vector<string> S(H);
  for (int i = 0; i < H; i++) {
    cin >> S[i];
  }
  int h = 0, w = 0;
  for (h = 0; h < H; h++) {
    bool found = false;
    for (w = 0; w < W; w++) {
      if (S[h][w] == '.') {
        found = true;
        break;
      }
    }
    if (found) {
      break;
    }
  }
  pair<pair<int, int>, int> ret1 = longest_point_dist(make_pair(h, w), S);
  pair<pair<int, int>, int> ret2 = longest_point_dist(ret1.first, S);
  cout << ret2.second << endl;
}
