#include <bits/stdc++.h>
using namespace std;
vector<vector<long long>> grid_bfs(vector<string> &s, char start,
                                   const char &wall = '#') {
  const long long vx[] = {0, 1, 0, -1}, vy[] = {1, 0, -1, 0};
  vector<vector<long long>> min_cost(s.size(),
                                     vector<long long>(s[0].size(), -1));
  queue<pair<long long, long long>> que;
  for (long long i = 0; i < s.size(); i++) {
    for (long long j = 0; j < s[i].size(); j++) {
      if (s[i][j] == start) {
        que.emplace(i, j);
        min_cost[i][j] = 0;
      }
    }
  }
  while (!que.empty()) {
    auto p = que.front();
    que.pop();
    for (long long i = 0; i < 4; i++) {
      long long ny = p.first + vy[i], nx = p.second + vx[i];
      if (nx < 0 || ny < 0 || nx >= s[0].size() || ny >= s.size()) continue;
      if (min_cost[ny][nx] != -1) continue;
      if (s[ny][nx] != wall) continue;
      min_cost[ny][nx] = min_cost[p.first][p.second] + 1;
      que.emplace(ny, nx);
    }
  }
  return min_cost;
}
signed main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  long long h, w;
  cin >> h >> w;
  vector<string> vs(h);
  for (long long i = 0; i < h; i++) {
    cin >> vs[i];
  }
  long long maxv = 0;
  for (long long i = (0), i_len = (h); i < i_len; ++i)
    for (long long j = (0), j_len = (w); j < j_len; ++j) {
      if (vs[i][j] == '.') {
        vector<string> t = vs;
        t[i][j] = 'S';
        vector<vector<long long>> ret = grid_bfs(t, 'S');
        for (auto &x : ret) {
          for (auto &y : x) {
            maxv = max(maxv, y);
          }
        }
      }
    }
  cout << maxv << endl;
  return 0;
}
