#include <bits/stdc++.h>
using namespace std;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
const int N = 100;
int mat[N][N];
int dist[N][N];
vector<pair<int, int> > dir = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  ;
  int n, m;
  cin >> n >> m;
  int ii = 0, jj = 0;
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      char c;
      cin >> c;
      mat[i][j] = (c == '.' ? 0 : 1);
      if (mat[i][j] == 0) {
        ii = i;
        jj = j;
      }
    }
  }
  queue<pair<int, int> > q;
  q.push({ii, jj});
  memset(dist, 0x3f3f3f3f, sizeof dist);
  dist[ii][jj] = 0;
  auto check = [&](int i, int j) {
    return i >= 0 and i < n and j >= 0 and j < m and mat[i][j] != 1;
  };
  while (q.size()) {
    pair<int, int> p = q.front();
    q.pop();
    for (auto d : dir) {
      pair<int, int> nxt = {p.first + d.first, p.second + d.second};
      if (check(nxt.first, nxt.second) and
          dist[nxt.first][nxt.second] == 0x3f3f3f3f) {
        dist[nxt.first][nxt.second] = dist[p.first][p.second] + 1;
        q.push(nxt);
      }
    }
  }
  int M = 0;
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      if (dist[i][j] != 0x3f3f3f3f and dist[i][j] > M) {
        M = max(M, dist[i][j]);
        ii = i, jj = j;
      }
    }
  }
  q.push({ii, jj});
  memset(dist, 0x3f3f3f3f, sizeof dist);
  dist[ii][jj] = 0;
  while (q.size()) {
    pair<int, int> p = q.front();
    q.pop();
    for (auto d : dir) {
      pair<int, int> nxt = {p.first + d.first, p.second + d.second};
      if (check(nxt.first, nxt.second) and
          dist[nxt.first][nxt.second] == 0x3f3f3f3f) {
        dist[nxt.first][nxt.second] = dist[p.first][p.second] + 1;
        q.push(nxt);
      }
    }
  }
  M = 0;
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      if (dist[i][j] != 0x3f3f3f3f and dist[i][j] > M) {
        M = max(M, dist[i][j]);
      }
    }
  }
  cout << M << '\n';
  return 0;
}
