#include <bits/stdc++.h>
using namespace std;
constexpr int64_t mod = 1e9 + 7;
vector<int> dx = {1, 0, -1, 0};
vector<int> dy = {0, -1, 0, 1};
queue<pair<int, int>> next_point;
int main() {
  int h, w;
  cin >> h >> w;
  vector<string> s(h);
  for (auto&& e : s) {
    cin >> e;
  }
  priority_queue<int> ans;
  for (int i = 0; i < h; ++i) {
    for (int j = 0; j < w; ++j) {
      vector<vector<int>> num_field(h, vector<int>(w, -1));
      if (s[i][j] == '#') continue;
      num_field[i][j] = 0;
      for (int k = 0; k < 4; ++k) {
        if (i + dx[k] < 0 || i + dx[k] >= h || j + dy[k] < 0 || j + dy[k] >= w)
          continue;
        if (s[i + dx[k]][j + dy[k]] == '#') continue;
        next_point.push(make_pair(i + dx[k], j + dy[k]));
      }
      while (!next_point.empty()) {
        int nx = next_point.front().first, ny = next_point.front().second;
        next_point.pop();
        priority_queue<int, vector<int>, greater<int>> point;
        for (int k = 0; k < 4; ++k) {
          if (nx + dx[k] < 0 || nx + dx[k] >= h || ny + dy[k] < 0 ||
              ny + dy[k] >= w)
            continue;
          if (num_field[nx + dx[k]][ny + dy[k]] != -1)
            point.push(num_field[nx + dx[k]][ny + dy[k]]);
          if (s[nx + dx[k]][ny + dy[k]] != '#' &&
              num_field[nx + dx[k]][ny + dy[k]] == -1)
            next_point.push(make_pair(nx + dx[k], ny + dy[k]));
        }
        if (!point.empty()) num_field[nx][ny] = point.top() + 1;
      }
      int tmp = 0;
      for (int x = 0; x < h; ++x) {
        for (int y = 0; y < w; ++y) {
          tmp = (num_field[x][y] >= tmp ? num_field[x][y] : tmp);
        }
      }
      ans.push(tmp);
    }
  }
  cout << ans.top();
}
