#include <bits/stdc++.h>
template <typename InputIterator>
typename InputIterator::value_type summation(InputIterator first,
                                             InputIterator last) {
  return std::accumulate(first, last, typename InputIterator::value_type());
}
template <typename T>
std::istream &operator>>(std::istream &stream, std::vector<T> &v);
template <typename T1, typename T2>
std::istream &operator>>(std::istream &stream, std::pair<T1, T2> &p);
template <typename T>
std::istream &operator>>(std::istream &stream, std::vector<T> &v) {
  for (auto &i : v) {
    stream >> i;
  }
  return stream;
}
template <typename T1, typename T2>
std::istream &operator>>(std::istream &stream, std::pair<T1, T2> &p) {
  stream >> p.first >> p.second;
  return stream;
}
int main() {
  int64_t h, w;
  std::cin >> h >> w;
  std::vector<std::vector<char>> s(h, std::vector<char>(w));
  for (int64_t i = 0; i < h; i++) {
    for (int64_t j = 0; j < w; j++) {
      char c;
      std::cin >> c;
      s[i][j] = c;
    }
  }
  int64_t ans = 0;
  for (int64_t i = 0; i < h; i++) {
    for (int64_t j = 0; j < w; j++) {
      if (s[i][j] == '#') {
        continue;
      }
      std::vector<std::vector<int64_t>> d(h, std::vector<int64_t>(w, h * w));
      std::queue<std::pair<int64_t, int64_t>> q;
      d[i][j] = 0;
      if (i + 1 < h && s[i + 1][j] == '.' && d[i + 1][j] == h * w) {
        q.push(std::make_pair(i + 1, j));
        d[i + 1][j] = std::min(d[i + 1][j], d[i][j] + 1);
      }
      if (0 <= i - 1 && s[i - 1][j] == '.' && d[i - 1][j] == h * w) {
        q.push(std::make_pair(i - 1, j));
        d[i - 1][j] = std::min(d[i - 1][j], d[i][j] + 1);
      }
      if (j + 1 < w && s[i][j + 1] == '.' && d[i][j + 1] == h * w) {
        q.push(std::make_pair(i, j + 1));
        d[i][j + 1] = std::min(d[i][j + 1], d[i][j] + 1);
      }
      if (0 < j - 1 && s[i][j - 1] == '.' && d[i][j - 1] == h * w) {
        q.push(std::make_pair(i, j - 1));
        d[i][j - 1] = std::min(d[i][j - 1], d[i][j] + 1);
      }
      while (!q.empty()) {
        const auto data = q.front();
        const auto i = data.first;
        const auto j = data.second;
        q.pop();
        ans = std::max(ans, d[i][j]);
        if (i + 1 < h && s[i + 1][j] == '.' && d[i + 1][j] == h * w) {
          q.push(std::make_pair(i + 1, j));
          d[i + 1][j] = std::min(d[i + 1][j], d[i][j] + 1);
        }
        if (0 <= i - 1 && s[i - 1][j] == '.' && d[i - 1][j] == h * w) {
          q.push(std::make_pair(i - 1, j));
          d[i - 1][j] = std::min(d[i - 1][j], d[i][j] + 1);
        }
        if (j + 1 < w && s[i][j + 1] == '.' && d[i][j + 1] == h * w) {
          q.push(std::make_pair(i, j + 1));
          d[i][j + 1] = std::min(d[i][j + 1], d[i][j] + 1);
        }
        if (0 < j - 1 && s[i][j - 1] == '.' && d[i][j - 1] == h * w) {
          q.push(std::make_pair(i, j - 1));
          d[i][j - 1] = std::min(d[i][j - 1], d[i][j] + 1);
        }
      }
    }
  }
  std::cout << ans << std::endl;
  return 0;
}
