#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using P = pair<long long, long long>;
using PP = pair<P, long long>;
struct mint {
  ll x;
  mint(ll x = 0) : x((x % 1000000007 + 1000000007) % 1000000007) {}
  mint operator-() const { return mint(-x); }
  mint& operator+=(const mint a) {
    if ((x += a.x) >= 1000000007) x -= 1000000007;
    return *this;
  }
  mint& operator-=(const mint a) {
    if ((x += 1000000007 - a.x) >= 1000000007) x -= 1000000007;
    return *this;
  }
  mint& operator*=(const mint a) {
    (x *= a.x) %= 1000000007;
    return *this;
  }
  mint operator+(const mint a) const { return mint(*this) += a; }
  mint operator-(const mint a) const { return mint(*this) -= a; }
  mint operator*(const mint a) const { return mint(*this) *= a; }
  mint pow(ll t) const {
    if (!t) return 1;
    mint a = pow(t >> 1);
    a *= a;
    if (t & 1) a *= *this;
    return a;
  }
  mint inv() const { return pow(1000000007 - 2); }
  mint& operator/=(const mint a) { return *this *= a.inv(); }
  mint operator/(const mint a) const { return mint(*this) /= a; }
};
istream& operator>>(istream& is, const mint& a) { return is >> a.x; }
ostream& operator<<(ostream& os, const mint& a) { return os << a.x; }
long long in() {
  long long x;
  cin >> x;
  return x;
}
string stin() {
  string s;
  cin >> s;
  return s;
}
long long H, W;
bool g[20][20];
bool visited[20][20];
void ResetVisited() {
  for (long long h = 0; h < H; ++h) {
    for (long long w = 0; w < W; ++w) {
      visited[h][w] = false;
    }
  }
}
long long GetDistance(long long start_y, long long start_x) {
  if (!g[start_y][start_x]) return 0;
  long long ret = 0;
  queue<PP> q;
  PP qt = PP(P(start_y, start_x), 0);
  q.push(qt);
  while (!q.empty()) {
    qt = q.front();
    long long curr_x = qt.first.second;
    long long curr_y = qt.first.first;
    long long curr_d = qt.second;
    q.pop();
    for (long long dy = -1; dy <= 1; ++dy) {
      for (long long dx = -1; dx <= 1; ++dx) {
        if (!dy && !dx) continue;
        if (abs(dy) + abs(dx) == 2) continue;
        long long next_x = curr_x + dx;
        long long next_y = curr_y + dy;
        long long next_d = curr_d + 1;
        if (next_x < 0 || next_x >= W) continue;
        if (next_y < 0 || next_y >= H) continue;
        if (!g[next_y][next_x]) continue;
        if (visited[next_y][next_x]) continue;
        ret = max(ret, next_d);
        q.push(PP(P(next_y, next_x), next_d));
        visited[next_y][next_x] = true;
      }
    }
  }
  return ret;
}
signed main() {
  cin >> H >> W;
  for (long long i = 0; i < (H); ++i) {
    for (long long j = 0; j < (W); ++j) {
      char c;
      cin >> c;
      g[i][j] = (c == '.');
    }
  }
  long long ans = 0;
  for (long long h = 0; h < H; ++h) {
    for (long long w = 0; w < W; ++w) {
      ans = max(ans, GetDistance(h, w));
      ResetVisited();
    }
  }
  cout << ans;
  cout << "\n";
  return 0;
}
