#include <bits/stdc++.h>
using namespace std;
const long long INF = 1LL << 60;
const long long MOD = 1000000007;
template <class T>
inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
template <class T>
inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
int main() {
  int h, w;
  cin >> h >> w;
  vector<vector<char>> v(h + 2, vector<char>(w + 2, '#'));
  for (long long i = 0; i < h; i++) {
    for (long long j = 0; j < w; j++) {
      cin >> v[i + 1][j + 1];
    }
  }
  int max = 0;
  for (long long i = 0; i < h; i++) {
    for (long long j = 0; j < w; j++) {
      int a = i + 1;
      int b = j + 1;
      if (v[a][b] == '#') {
        continue;
      }
      vector<vector<bool>> ans(h + 2, vector<bool>(w + 2, false));
      queue<int> qx;
      queue<int> qy;
      queue<int> q;
      if (v[a][b - 1] == '.') {
        qx.push(a);
        qy.push(b - 1);
        q.push(1);
        ans[a][b - 1] = true;
      }
      if (v[a][b + 1] == '.') {
        qx.push(a);
        qy.push(b + 1);
        q.push(1);
        ans[a][b + 1] = true;
      }
      if (v[a - 1][b] == '.') {
        qx.push(a - 1);
        qy.push(b);
        q.push(1);
        ans[a - 1][b] = true;
      }
      if (v[a + 1][b - 1] == '.') {
        qx.push(a + 1);
        qy.push(b);
        q.push(1);
        ans[a + 1][b] = true;
      }
      int tmp = 0;
      ans[a][b] = true;
      while (!q.empty()) {
        int x = qx.front();
        int y = qy.front();
        qx.pop();
        qy.pop();
        int kazu = q.front();
        q.pop();
        tmp = kazu;
        kazu++;
        if (v[x][y - 1] == '.' && !ans[x][y - 1]) {
          qx.push(x);
          qy.push(y - 1);
          q.push(kazu);
          ans[x][y - 1] = true;
        }
        if (v[x][y + 1] == '.' && !ans[x][y + 1]) {
          qx.push(x);
          qy.push(y + 1);
          q.push(kazu);
          ans[x][y + 1] = true;
        }
        if (v[x - 1][y] == '.' && !ans[x - 1][y]) {
          qx.push(x - 1);
          qy.push(y);
          q.push(kazu);
          ans[x - 1][y] = true;
        }
        if (v[x + 1][y - 1] == '.' && !ans[x + 1][y]) {
          qx.push(x + 1);
          qy.push(y);
          q.push(kazu);
          ans[x + 1][y] = true;
        }
      }
      if (max < tmp) {
        max = tmp;
      }
    }
  }
  cout << max << endl;
}
