#include <bits/stdc++.h>
void debug_out() { std::cerr << std::endl; }
template <typename Head, typename... Tail>
void debug_out(Head h, Tail... t) {
  std::cerr << " " << h;
  debug_out(t...);
}
template <typename T1, typename T2>
std::ostream& operator<<(std::ostream& os, std::pair<T1, T2> pa) {
  return os << pa.first << " " << pa.second;
}
template <typename T>
std::ostream& operator<<(std::ostream& os, std::vector<T> vec) {
  for (int i = 0; i < vec.size(); i++)
    os << vec[i] << (i + 1 == vec.size() ? "" : " ");
  return os;
}
template <typename T1, typename T2>
inline bool chmax(T1& a, T2 b) {
  return a < b && (a = b, true);
}
template <typename T1, typename T2>
inline bool chmin(T1& a, T2 b) {
  return a > b && (a = b, true);
}
long long pow_mod(long long a, long long b, long long mod = -1) {
  if (b == 0) return 1;
  if ((a == 0) || (mod != -1 && (a + mod) % mod == 0)) {
    return 0;
  }
  long long x = 1;
  while (b > 0) {
    if (b & 1) {
      x = (mod != -1) ? (x * a) % mod : x * a;
    }
    a = (mod != -1) ? (a * a) % mod : a * a;
    b >>= 1;
  }
  return x;
}
const long long MOD = 1e9 + 7;
using ll = long long;
using P = std::pair<long long, long long>;
ll gcd(ll a, ll b) {
  if (a % b == 0) return b;
  return gcd(b, a % b);
}
ll dx[4] = {0, 1, 0, -1}, dy[4] = {1, 0, -1, 0};
int main() {
  std::cin.tie(0);
  std::ios::sync_with_stdio(false);
  ll h, w;
  std::cin >> h >> w;
  std::vector<std::vector<ll>> cost(h * w, std::vector<ll>(h * w, MOD));
  for (long long(i) = (0); i < (h * w); i++) cost[i][i] = 0;
  std::vector<std::string> maze(h);
  for (long long(i) = (0); i < (h); i++) std::cin >> maze[i];
  for (long long(i) = (0); i < (h); i++) {
    for (long long(j) = (0); j < (w); j++) {
      if (!maze[i][j] != '#') {
        for (long long(k) = (0); k < (4); k++) {
          if (0 <= i + dx[k] && i + dx[k] < h && 0 <= j + dy[k] &&
              j + dy[k] < w) {
            if (maze[i + dx[k]][j + dy[k]] == '.') {
              cost[i * w + j][(i + dx[k]) * w + j + dy[k]] = 1;
            }
          }
        }
      }
    }
  }
  for (long long(k) = (0); k < (h * w); k++) {
    for (long long(i) = (0); i < (h * w); i++) {
      for (long long(j) = (0); j < (h * w); j++) {
        chmin(cost[i][j], cost[i][k] + cost[k][j]);
      }
    }
  }
  ll max = 0;
  for (long long(i) = (0); i < (h * w); i++) {
    for (long long(j) = (0); j < (h * w); j++) {
      if (cost[i][j] != MOD) chmax(max, cost[i][j]);
    }
  }
  std::cout << max << "\n";
  return 0;
}
