#include <bits/stdc++.h>
using namespace std;
inline int toInt(string s) {
  int v;
  istringstream sin(s);
  sin >> v;
  return v;
}
template <class T>
inline string toString(T x) {
  ostringstream sout;
  sout << x;
  return sout.str();
}
template <class T>
inline T sqr(T x) {
  return x * x;
}
const double EPS = 1e-10;
const double PI = acos(-1.0);
const long long INF = 1000000007;
template <class T>
inline bool chmax(T& a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <class T>
inline bool chmin(T& a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
int main(void) {
  int H, W;
  cin >> H >> W;
  char S[H][W];
  for (int i = (0); i < (H); ++i)
    for (int j = (0); j < (W); ++j) cin >> S[i][j];
  int node[H][W], n = 0;
  for (int i = (0); i < (H); ++i)
    for (int j = (0); j < (W); ++j) node[i][j] = n++;
  long long dist[n][n];
  for (int i = (0); i < (n); ++i)
    for (int j = (0); j < (n); ++j) dist[i][j] = INF;
  for (int i = (0); i < (n); ++i) dist[i][i] = 0;
  for (int i = (0); i < (H); ++i)
    for (int j = (0); j < (W); ++j) {
      if (i > 0) {
        if (S[i - 1][j] == '.') dist[node[i][j]][node[i - 1][j]] = 1;
      }
      if (i < H - 1) {
        if (S[i + 1][j] == '.') dist[node[i][j]][node[i + 1][j]] = 1;
      }
      if (j > 0) {
        if (S[i][j - 1] == '.') dist[node[i][j]][node[i][j - 1]] = 1;
      }
      if (i < W - 1) {
        if (S[i][j + 1] == '.') dist[node[i][j]][node[i][j + 1]] = 1;
      }
    }
  for (int k = (0); k < (n); ++k)
    for (int i = (0); i < (n); ++i)
      for (int j = (0); j < (n); ++j)
        chmin(dist[i][j], dist[i][k] + dist[k][j]);
  long long ans = 0;
  for (int i = (0); i < (n); ++i)
    for (int j = (0); j < (n); ++j)
      if (ans < INF) chmax(ans, dist[i][j]);
  cout << ans << endl;
  return 0;
}
