#include <bits/stdc++.h>
int H, W;
struct Entry {
  int y;
  int x;
  int len;
};
std::vector<std::pair<int, int>> dir = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
int calcLen(int i, int j, const std::vector<std::string>& grid) {
  std::queue<Entry> queue;
  queue.emplace(Entry{i, j, 0});
  std::set<std::pair<int, int>> visited;
  int result = 0;
  while (!queue.empty()) {
    auto cur = queue.front();
    queue.pop();
    result = result > cur.len ? result : cur.len;
    visited.emplace(cur.y, cur.x);
    for (const auto& d : dir) {
      auto newy = cur.y + d.first;
      auto newx = cur.x + d.second;
      if (newx >= 0 && newx < W && newy >= 0 && newy < H &&
          grid[newy][newx] == '.' && !visited.count(std::make_pair(newy, newx)))
        queue.emplace(Entry{newy, newx, cur.len + 1});
    }
  }
  return result;
}
int main() {
  std::cin >> H >> W;
  std::vector<std::string> grid(H);
  for (int i = 0; i < H; ++i) std::cin >> grid.at(i);
  long long result = 0;
  for (int i = 0; i < H; ++i) {
    for (int j = 0; j < W; ++j) {
      if (grid[i][j] == '#') continue;
      auto len = calcLen(i, j, grid);
      result = result > len ? result : len;
    }
  }
  std::cout << result << "\n";
}
