#include <bits/stdc++.h>
using namespace std;
template <typename T>
void chmin(T &a, T b) {
  if (a > b) a = b;
}
template <typename T>
void chmax(T &a, T b) {
  if (a < b) a = b;
}
int in() {
  int x;
  scanf("%d", &x);
  return x;
}
long long lin() {
  long long x;
  scanf("%lld", &x);
  return x;
}
int main() {
  int H, W;
  cin >> H >> W;
  vector<string> maze(H);
  for (int i = 0; i < H; ++i) cin >> maze[i];
  int ans = 0;
  for (int i = 0; i < H; ++i) {
    for (int j = 0; j < H; ++j) {
      vector<vector<int> > dist(H, vector<int>(W, -1));
      queue<pair<int, int> > que;
      que.push(make_pair(i, j));
      dist[i][j] = 0;
      vector<pair<int, int> > drs = {make_pair(-1, 0), make_pair(1, 0),
                                     make_pair(0, 1), make_pair(0, -1)};
      while (!que.empty()) {
        pair<int, int> front = que.front();
        que.pop();
        for (pair<int, int> dr : drs) {
          int y = front.first + dr.first;
          int x = front.second + dr.second;
          if (y < 0 || y >= H || x < 0 || x >= W || maze[y][x] == '#') continue;
          if (dist[y][x] == -1) {
            dist[y][x] = dist[front.first][front.second] + 1;
            que.push(make_pair(y, x));
          }
        }
      }
      for (int y = 0; y < H; ++y)
        for (int x = 0; x < W; ++x) ans = max(ans, dist[y][x]);
    }
  }
  cout << ans << endl;
  return 0;
}
