#include <bits/stdc++.h>
using namespace std;
using i8 = int8_t;
using i16 = int16_t;
using i32 = int32_t;
using i64 = int64_t;
using u8 = uint8_t;
using u16 = uint16_t;
using u32 = uint32_t;
using u64 = uint64_t;
const i32 lr[] = {0, 0, -1, 1};
const i32 td[] = {-1, 1, 0, 0};
constexpr auto MIN = -1;
i32 H, W;
char S[20][20];
i32 ans;
void bfs(i32 x, i32 y) {
  vector<vector<i32>> d(H, vector<i32>(W, MIN));
  deque<pair<i32, i32>> queue;
  d[y][x] = 0;
  queue.emplace_back(x, y);
  while (!queue.empty()) {
    auto xy = *queue.begin();
    queue.pop_front();
    for (i32 i = 0; i < 4; ++i) {
      auto nx = xy.first + lr[i];
      auto ny = xy.second + td[i];
      if (S[ny][nx] == '#') continue;
      if (ny < 0 || nx < 0 || ny >= H || nx >= W) continue;
      if (S[ny][nx] == '.' && d[ny][nx] == MIN) {
        d[ny][nx] = d[xy.second][xy.first] + 1;
        queue.emplace_back(nx, ny);
        ans = max(ans, d[ny][nx]);
      }
    }
  }
}
int main(int argc, char* argv[]) {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  cin >> H >> W;
  for (i32 y = 0; y < H; ++y) {
    for (i32 x = 0; x < W; ++x) {
      cin >> S[y][x];
    }
  }
  ans = 0;
  for (i32 j = 0; j < H; ++j) {
    for (i32 i = 0; i < W; ++i) {
      bfs(i, j);
    }
  }
  cout << ans << endl;
  return 0;
}
