#include <bits/stdc++.h>
#pragma gcc optimize("Ofast")
using namespace std;
using ll = long long;
const long long MOD = 1000000007;
const long long INF = 1061109567;
const double EPS = 1e-10;
const double PI = acos(-1.0);
long long h, w;
signed main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  cin >> h >> w;
  long long step = 0;
  vector<vector<string>> s(h, vector<string>(w));
  for (long long i = 0; i < (h); ++i) {
    for (long long j = 0; j < (w); ++j) {
      cin >> s[i][j];
    }
  }
  vector<vector<long long>> d(h * w + 1, vector<long long>(h * w + 1, INF));
  long long newcnt1 = 0;
  long long newcnt2 = 0;
  for (long long i = 0; i < (h); ++i) {
    for (long long j = 0; j < (w); ++j) {
      if (s[i][j] == "#") continue;
      newcnt1++;
      newcnt2 = 0;
      for (long long a = 0; a < (h); ++a) {
        for (long long b = 0; b < (w); ++b) {
          if (s[a][b] == "#") continue;
          newcnt2++;
          if (i == a && j == b) {
            d[newcnt1][newcnt2] = 0;
          } else {
            bool tate = (i == a) && (abs(j - b) == 1);
            bool yoko = (abs(i - a) == 1) && (j == b);
            if (tate || yoko) {
              d[newcnt1][newcnt2] = 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) {
        d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
      }
    }
  }
  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) {
        d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
      }
    }
  }
  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) {
        d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
      }
    }
  }
  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) {
        d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
      }
    }
  }
  for (long long k = 0; k < (h * w + 1); ++k) {
    for (long long i = 0; i < (h * w + 1); ++i) {
      for (long long j = 0; j < (h * w + 1); ++j) {
        if (d[i][j] == INF) d[i][j] = -1;
      }
    }
  }
  long long maxi = 0;
  for (long long i = 0; i < (h * w); ++i) {
    maxi = max(maxi, (long long)*max_element(d[i].begin(), d[i].end()));
  }
  cout << maxi << '\n';
}
