#include <bits/stdc++.h>
using namespace std;
int main() {
  int H, W;
  cin >> H >> W;
  vector<vector<char>> g(H, vector<char>(W));
  for (auto &x : g) {
    for (auto &y : x) {
      cin >> y;
    }
  }
  function<int(pair<int, int>)> bfs = [&](pair<int, int> root) -> int {
    queue<pair<int, int>> q;
    q.push(root);
    vector<pair<int, int>> dirs = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
    vector<vector<int>> d(H, vector<int>(W));
    vector<vector<bool>> v(H, vector<bool>(W));
    d[root.first][root.second] = 0;
    while (!q.empty()) {
      pair<int, int> next = q.front();
      q.pop();
      for (int i = 0; i < (int)dirs.size(); ++i) {
        pair<int, int> next_d =
            make_pair(dirs[i].first + next.first, dirs[i].second + next.second);
        if (next_d.first < H && next_d.first >= 0 && next_d.second < W &&
            next_d.second >= 0 && g[next_d.first][next_d.second] != '#' &&
            !v[next_d.first][next_d.second]) {
          q.push(next_d);
          d[next_d.first][next_d.second] = d[next.first][next.second] + 1;
          v[next_d.first][next_d.second] = true;
        }
      }
    }
    int ans = INT_MIN;
    for (auto const &x : d) {
      for (auto const &y : x) {
        ans = max(ans, y);
      }
    }
    return ans;
  };
  int ans = INT_MIN;
  for (int i = 0; i < H; ++i) {
    for (int j = 0; j < W; ++j) {
      if (g[i][j] != '#') {
        ans = max(ans, bfs(make_pair(i, j)));
      }
    }
  }
  cout << ans << endl;
  return 0;
}
