#include <bits/stdc++.h>
using namespace std;
using Graph = vector<vector<int64_t>>;
const double pi = M_PI;
const int64_t MOD = 1000000007;
const int dx[4] = {0, 1, 0, -1};
const int dy[4] = {1, 0, -1, 0};
int H, W;
vector<string> field;
vector<vector<int>> dist;
int bfs(int h, int w) {
  int distmax = 0;
  queue<pair<int, int>> que;
  que.push({h, w});
  while (!que.empty()) {
    pair<int, int> v = que.front();
    que.pop();
    for (int i = 0; i < 4; i++) {
      int nh = v.first + dx[i];
      int nw = v.second + dy[i];
      if (nh < 0 || nw < 0 || H <= nh || W <= nw) {
        continue;
      }
      if (dist[nh][nw] != -1) {
        continue;
      }
      if (field[v.first][v.second] == '#') {
        continue;
      }
      dist[nh][nw] = dist[v.first][v.second] + 1;
      distmax = max(distmax, dist[nh][nw]);
      que.push({nh, nw});
    }
  }
  return distmax;
}
int main() {
  cin >> H >> W;
  dist.assign(H, vector<int>(W, -1));
  for (int i = 0; i < H; i++) {
    string s;
    cin >> s;
    field.push_back(s);
  }
  int sh1 = -1, sh2 = -1, sw1 = -1, sw2 = -1;
  for (int h = 0; h < H; h++) {
    for (int w = 0; w < W; w++) {
      if (field[h][w] == '.') {
        sh1 = h;
        sw1 = w;
      }
    }
    if (sh1 != -1) {
      break;
    }
  }
  int distm = 0;
  dist[sh1][sw1] = 0;
  distm = bfs(sh1, sw1);
  for (int h = 0; h < H; h++) {
    for (int w = 0; w < W; w++) {
      if (dist[h][w] == distm) {
        sh2 = h;
        sw2 = w;
      }
    }
    if (sh2 != -1) {
      break;
    }
  }
  dist.assign(H, vector<int>(W, -1));
  distm = bfs(sh2, sw2);
  cout << distm + 1 << endl;
  return 0;
}
