#include <cstdio>
#include <cstdint>
#include <vector>
#include <algorithm>
#include <utility>
#include <numeric>
#include <set>
#include <map>
#include <string>
#include <tuple>
#include <queue>

constexpr intmax_t  operator ""_jd(unsigned long long n) { return n; }
constexpr uintmax_t operator ""_ju(unsigned long long n) { return n; }
constexpr size_t    operator ""_zu(unsigned long long n) { return n; }
// constexpr ptrdiff_t operator ""_td(unsigned long long n) { return n; }

namespace detail {
template <typename Tp, size_t N>
std::vector<Tp> make_vector(
    std::vector<size_t>& sizes,
    typename std::enable_if<(N == 1), Tp const&>::type x
) {
  return std::vector<Tp>(sizes[0], x);
}
template <typename Tp, size_t N>
auto make_vector(
    std::vector<size_t>& sizes,
    typename std::enable_if<(N > 1), Tp const&>::type x
) {
  size_t size = sizes[N-1];
  sizes.pop_back();
  return std::vector<decltype(make_vector<Tp, N-1>(sizes, x))>(
      size, make_vector<Tp, N-1>(sizes, x)
  );
}
}  // detail::

template <typename Tp, size_t N>
auto make_vector(size_t const(&sizes)[N], Tp const& x = Tp()) {
  std::vector<size_t> s(N);
  for (size_t i = 0; i < N; ++i) s[i] = sizes[N-i-1];
  return detail::make_vector<Tp, N>(s, x);
}

constexpr size_t di[] = {-1_zu, 0, 1, 0};
constexpr size_t dj[] = {0, -1_zu, 0, 1};

int f(std::vector<std::string> const& s, size_t si, size_t sj) {
  size_t h = s.size();
  size_t w = s[0].length();
  auto dp = make_vector<int>({h, w}, 1e9);
  using zahyo = std::pair<size_t, size_t>;
  std::queue<zahyo> q;
  q.emplace(si, sj);
  dp[si][sj] = 0;
  while (!q.empty()) {
    size_t i, j;
    std::tie(i, j) = q.front();
    q.pop();
    for (size_t k = 0; k < 4; ++k) {
      size_t ni = i + di[k];
      size_t nj = j + dj[k];
      if (!(ni < h && nj < w)) continue;
      if (s[ni][nj] == '#') continue;
      if (dp[ni][nj] > dp[i][j] + 1) {
        dp[ni][nj] = dp[i][j] + 1;
        q.emplace(ni, nj);
      }
    }
  }

  int res = 0;
  for (size_t i = 0; i < h; ++i)
    for (size_t j = 0; j < w; ++j)
      if (s[i][j] == '.')
        res = std::max(res, dp[i][j]);

  return res;
}

int main() {
  size_t h, w;
  scanf("%zu %zu", &h, &w);

  std::vector<std::string> s(h);
  for (size_t i = 0; i < h; ++i) {
    char buf[32];
    scanf("%s", buf);
    s[i] = buf;
  }

  int res = 0;
  for (size_t i = 0; i < h; ++i)
    for (size_t j = 0; j < w; ++j)
      res = std::max(res, f(s, i, j));

  printf("%d\n", res);
}
