#include <bits/stdc++.h>
using namespace std;
const uint64_t UNREACHABLE = static_cast<uint64_t>(-1);
struct QueueItem {
  uint64_t x, y, d;
  QueueItem(uint64_t x, uint64_t y, uint64_t d) : x(x), y(y), d(d) {}
};
int search(uint64_t H, uint64_t W, const vector<string> &S,
           vector<vector<uint64_t>> &dist, uint64_t x, uint64_t y) {
  queue<QueueItem> q;
  dist[y][x] = 0;
  q.emplace(x, y, 0);
  while (!q.empty()) {
    QueueItem item = q.front();
    q.pop();
    int dy[4] = {+1, -1, 0, 0}, dx[4] = {0, 0, +1, -1};
    for (uint64_t dir = 0; dir < 4; ++dir) {
      uint64_t nx = item.x + dx[dir], ny = item.y + dy[dir];
      uint64_t nd = item.d + 1;
      if (nx < W && ny < H && S[ny][nx] == '.') {
        if (dist[ny][nx] > nd) {
          dist[ny][nx] = nd;
          q.emplace(nx, ny, nd);
        }
      }
    }
  }
  return 0;
}
pair<uint64_t, uint64_t> max_postition(uint64_t H, uint64_t W,
                                       const vector<vector<uint64_t>> &dist) {
  uint64_t max_dist = 0;
  pair<uint64_t, uint64_t> max_pos = make_pair(UNREACHABLE, UNREACHABLE);
  for (uint64_t h = 0; h < H; ++h) {
    for (uint64_t w = 0; w < W; ++w) {
      if (dist[h][w] == UNREACHABLE) {
        continue;
      }
      if (dist[h][w] >= max_dist) {
        max_dist = dist[h][w];
        max_pos = make_pair(w, h);
      }
    }
  }
  return max_pos;
}
int main() {
  uint64_t H, W;
  cin >> H >> W;
  pair<uint64_t, uint64_t> start = make_pair(UNREACHABLE, UNREACHABLE);
  vector<string> S(H);
  for (uint64_t h = 0; h < H; ++h) {
    cin >> S[h];
    if (start.first > W && start.second > H) {
      for (uint64_t w = 0; w < W; ++w) {
        if (S[h][w] == '.') {
          start = make_pair(w, h);
          break;
        }
      }
    }
  }
  vector<vector<uint64_t>> dist1(H), dist2(H);
  for (uint64_t h = 0; h < H; ++h) {
    dist1[h] = vector<uint64_t>(W, UNREACHABLE);
    dist2[h] = vector<uint64_t>(W, UNREACHABLE);
  }
  search(H, W, S, dist1, start.first, start.second);
  pair<uint64_t, uint64_t> p1 = max_postition(H, W, dist1);
  search(H, W, S, dist2, p1.first, p1.second);
  pair<uint64_t, uint64_t> p2 = max_postition(H, W, dist2);
  cout << dist2[p2.second][p2.first] << endl;
  return 0;
}
