#include <bits/stdc++.h>
using namespace std;
bool sBs(const pair<int, int> &a, const pair<int, int> &b) {
  return (a.second < b.second);
}
long long SUMD(long long n);
long long BS(vector<long long> &PS, long long s, long long e, long long ser);
long long MI(long long a, long long m);
bool P[150 + 1];
void Sieve(int n = 150);
long long Powb(long long b, long long n);
long long solve(vector<string> &G, int r, int c, int n, int m) {
  queue<pair<int, int> > Q;
  vector<vector<int> > L(n, vector<int>(m, 500000));
  L[r][c] = 0;
  Q.push({r, c});
  int ml = 0;
  while (!Q.empty()) {
    auto x = Q.front();
    Q.pop();
    r = x.first;
    c = x.second;
    if (r - 1 >= 0 and G[r - 1][c] == '.' and ((L[r - 1][c] + 1) > L[r][c])) {
      L[r - 1][c] = L[r][c] + 1;
      Q.push({r - 1, c});
      ml = max(ml, L[r][c] + 1);
    }
    if (r + 1 < n and G[r + 1][c] == '.' and ((L[r + 1][c] + 1) > L[r][c])) {
      L[r + 1][c] = L[r][c] + 1;
      Q.push({r + 1, c});
      ml = max(ml, L[r][c] + 1);
    }
    if (c - 1 >= 0 and G[r][c - 1] == '.' and ((L[r][c - 1] + 1) > L[r][c])) {
      L[r][c - 1] = L[r][c] + 1;
      Q.push({r, c - 1});
      ml = max(ml, L[r][c] + 1);
    }
    if (c + 1 < m and G[r][c + 1] == '.' and ((L[r][c + 1] + 1) > L[r][c])) {
      L[r][c + 1] = L[r][c] + 1;
      Q.push({r, c + 1});
      ml = max(ml, L[r][c] + 1);
    }
  }
  return ml;
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  ;
  long long q = 1, t;
  while (q--) {
    long long n, m, k, i, j, l, r, c = 0, b, a, g, counter = 0, u, v, d, e, p,
                                   x, y, flag = 1;
    cin >> n >> m;
    long long ans = 0;
    vector<string> G(n);
    for (i = 0; i < n; i++) cin >> G[i];
    for (i = 0; i < n; i++) {
      for (j = 0; j < m; j++) {
        if (G[i][j] == '.') ans = max(ans, solve(G, i, j, n, m));
      }
    }
    cout << ans;
  }
  return 0;
}
