#include <bits/stdc++.h>
using namespace std;
int main(void) {
  int H, W;
  cin >> H >> W;
  vector<string> S(H, "");
  for (int i = 0; i < H; i++) {
    cin >> S[i];
  }
  vector<vector<int>> G(H * W, vector<int>());
  vector<int> distance(H * W, -1);
  for (int i = 0; i < H - 1; i++) {
    for (int j = 0; j < W; j++) {
      if ((S[i][j] == '.') && (S[i + 1][j] == '.')) {
        G[i * W + j].push_back((i + 1) * W + j);
        G[(i + 1) * W + j].push_back(i * W + j);
      }
    }
  }
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W - 1; j++) {
      if ((S[i][j] == '.') && (S[i][j + 1] == '.')) {
        G[i * W + j].push_back(i * W + j + 1);
        G[i * W + j + 1].push_back(i * W + j);
      }
    }
  }
  bool bp = false;
  int startpoint;
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      if (S[i][j] == '.') {
        startpoint = i * W + j;
        bp = true;
        break;
      }
    }
    if (bp) break;
  }
  queue<int> queG;
  queG.push(startpoint);
  distance[startpoint] = 0;
  while (!queG.empty()) {
    int curpoint = queG.front();
    queG.pop();
    for (int nextpoint : G[curpoint]) {
      if (distance[nextpoint] != -1) continue;
      distance[nextpoint] = distance[curpoint] + 1;
      queG.push(nextpoint);
    }
  }
  int furthest = startpoint;
  for (int i = 0; i < H * W; i++) {
    if (distance[i] > distance[furthest]) furthest = i;
  }
  for (int i = 0; i < H * W; i++) distance[i] = -1;
  queG.push(furthest);
  distance[furthest] = 0;
  while (!queG.empty()) {
    int curpoint = queG.front();
    queG.pop();
    for (int nextpoint : G[curpoint]) {
      if (distance[nextpoint] != -1) continue;
      distance[nextpoint] = distance[curpoint] + 1;
      queG.push(nextpoint);
    }
  }
  int furthest2 = furthest;
  for (int i = 0; i < H * W; i++) {
    if (distance[i] > distance[furthest2]) furthest2 = i;
  }
  cout << distance[furthest2] << endl;
  return 0;
}
