#include <bits/stdc++.h>
using namespace std;
using LL = long long;
using ULL = unsigned long long;
const int dx[] = {1, 0, -1, 0};
const int dy[] = {0, 1, 0, -1};
int bfs(int y, int x, int gy, int gx, int h, int w, vector<string> arr) {
  vector<vector<int>> dist(h, vector<int>(w, -1));
  queue<pair<int, int>> que;
  int res = 0;
  dist[y][x] = 0;
  que.push({y, x});
  while (!que.empty()) {
    auto cur = que.front();
    que.pop();
    res = max(res, dist[cur.first][cur.second]);
    for (int i = 0; i < (int)(4); i++) {
      int ny = cur.first + dy[i];
      int nx = cur.second + dx[i];
      if (ny < 0 || ny >= h || nx < 0 || nx >= w) continue;
      if (arr[ny][nx] == '#') continue;
      if (dist[ny][nx] != -1) continue;
      dist[ny][nx] = dist[cur.first][cur.second] + 1;
      que.push({ny, nx});
    }
  }
  return res;
}
int main() {
  int h, w;
  cin >> h >> w;
  vector<string> arr(h);
  for (int i = 0; i < (int)(h); i++) cin >> arr[i];
  int ans = 0;
  for (int start_y = 0; start_y < (int)(h); start_y++) {
    for (int start_x = 0; start_x < (int)(w); start_x++) {
      for (int goal_y = 0; goal_y < (int)(h); goal_y++) {
        for (int goal_x = 0; goal_x < (int)(w); goal_x++) {
          if (start_x != goal_x && start_y != goal_y &&
              arr[start_y][start_x] != '#' && arr[goal_y][goal_x] != '#') {
            int dist = bfs(start_y, start_x, goal_y, goal_x, h, w, arr);
            ans = max(ans, dist);
          }
        }
      }
    }
  }
  cout << ans << endl;
}
