#include <bits/stdc++.h>
using namespace std;
int main() {
  int64_t H, W;
  cin >> H >> W;
  vector<string> S(H);
  for (int64_t i = 0; i < H; i++) {
    cin >> S[i];
  }
  int64_t sx, sy;
  for (int64_t i = 0; i < H; i++) {
    for (int64_t j = 0; j < W; j++) {
      if (S[i][j] != '#') {
        sx = j;
        sy = i;
        i = H;
        j = W;
      }
    }
  }
  struct Element {
    int64_t x, y, cost;
    bool operator<(const Element& rhs) const { return cost < rhs.cost; }
    bool operator>(const Element& rhs) const { return cost > rhs.cost; }
  };
  int64_t dx[] = {0, 1, 0, -1};
  int64_t dy[] = {1, 0, -1, 0};
  {
    vector<vector<int64_t>> cost(H, vector<int64_t>(W, INT_MAX));
    priority_queue<Element, vector<Element>, greater<Element>> pq;
    cost[sy][sx] = 0;
    pq.push({sx, sy, 0});
    while (!pq.empty()) {
      Element t = pq.top();
      pq.pop();
      if (t.cost > cost[t.y][t.x]) {
        continue;
      }
      for (int64_t i = 0; i < 4; i++) {
        int64_t nx = t.x + dx[i];
        int64_t ny = t.y + dy[i];
        if (nx < 0 || nx >= W || ny < 0 || ny >= H || S[ny][nx] == '#') {
          continue;
        }
        int64_t new_cost = t.cost + 1;
        if (new_cost < cost[ny][nx]) {
          cost[ny][nx] = new_cost;
          pq.push({nx, ny, new_cost});
        }
      }
    }
    int64_t max_cost = -1;
    for (int64_t i = 0; i < H; i++) {
      for (int64_t j = 0; j < W; j++) {
        if (S[i][j] == '#') {
          continue;
        }
        if (cost[i][j] > max_cost) {
          max_cost = cost[i][j];
          sx = j;
          sy = i;
        }
      }
    }
  }
  int64_t ans = -1;
  {
    vector<vector<int64_t>> cost(H, vector<int64_t>(W, INT_MAX));
    priority_queue<Element, vector<Element>, greater<Element>> pq;
    cost[sy][sx] = 0;
    pq.push({sx, sy, 0});
    while (!pq.empty()) {
      Element t = pq.top();
      pq.pop();
      if (t.cost > cost[t.y][t.x]) {
        continue;
      }
      for (int64_t i = 0; i < 4; i++) {
        int64_t nx = t.x + dx[i];
        int64_t ny = t.y + dy[i];
        if (nx < 0 || nx >= W || ny < 0 || ny >= H || S[ny][nx] == '#') {
          continue;
        }
        int64_t new_cost = t.cost + 1;
        if (new_cost < cost[ny][nx]) {
          cost[ny][nx] = new_cost;
          pq.push({nx, ny, new_cost});
        }
      }
    }
    for (int64_t i = 0; i < H; i++) {
      for (int64_t j = 0; j < W; j++) {
        if (S[i][j] == '#') {
          continue;
        }
        if (cost[i][j] > ans) {
          ans = cost[i][j];
          sx = j;
          sy = i;
        }
      }
    }
  }
  cout << ans << endl;
}
