#include <bits/stdc++.h>
using namespace std;
int main() {
  long long H, W;
  cin >> H >> W;
  char MAP[H][W];
  for (int h = 0; h < H; h++) {
    for (int w = 0; w < W; w++) {
      cin >> MAP[h][w];
    }
  }
  long long max_distance = 0;
  for (int s_h = 0; s_h < H; s_h++) {
    for (int s_w = 0; s_w < W; s_w++) {
      if (MAP[s_h][s_w] == '#') continue;
      deque<tuple<long long, long long, long long> > q;
      vector<vector<long long> > MEMO(H, vector<long long>(W, -1));
      q.push_back(make_tuple(s_h, s_w, 0));
      while (q.size() != 0) {
        tuple<long long, long long, long long> current_pos = q.at(0);
        long long cur_h = get<0>(current_pos);
        long long cur_w = get<1>(current_pos);
        long long cur_d = get<2>(current_pos);
        q.pop_front();
        if (cur_h - 1 >= 0 && MEMO[cur_h - 1][cur_w] == -1 &&
            MAP[cur_h - 1][cur_w] != '#') {
          MEMO[cur_h - 1][cur_w] = cur_d + 1;
          q.push_back(make_tuple(cur_h - 1, cur_w, cur_d + 1));
        }
        if (cur_h + 1 < H && MEMO[cur_h + 1][cur_w] == -1 &&
            MAP[cur_h + 1][cur_w] != '#') {
          MEMO[cur_h + 1][cur_w] = cur_d + 1;
          q.push_back(make_tuple(cur_h + 1, cur_w, cur_d + 1));
        }
        if (cur_w - 1 >= 0 && MEMO[cur_h][cur_w - 1] == -1 &&
            MAP[cur_h][cur_w - 1] != '#') {
          MEMO[cur_h][cur_w - 1] = cur_d + 1;
          q.push_back(make_tuple(cur_h, cur_w - 1, cur_d + 1));
        }
        if (cur_w + 1 < W && MEMO[cur_h][cur_w + 1] == -1 &&
            MAP[cur_h][cur_w + 1] != '#') {
          MEMO[cur_h][cur_w + 1] = cur_d + 1;
          q.push_back(make_tuple(cur_h, cur_w + 1, cur_d + 1));
        }
        if (cur_d > max_distance) max_distance = cur_d;
      }
    }
  }
  cout << max_distance << endl;
  return 0;
}
