#include <bits/stdc++.h>
using namespace std;
using ll = long long;
string char_to_string(char val) { return string(1, val); }
int char_to_int(char val) { return val - '0'; }
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 vector_finder(std::vector<ll> vec, int number) {
  auto itr = std::find(vec.begin(), vec.end(), number);
  size_t index = std::distance(vec.begin(), itr);
  if (index != vec.size()) {
    return 1;
  } else {
    return 0;
  }
}
const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, -1, 0, 1};
int main() {
  int H, W;
  cin >> H >> W;
  vector<string> S(H);
  for (int i = 0, i_len = (H); i < i_len; ++i) cin >> S[i];
  int ans = 0;
  int cnt = 0;
  for (int i = 0, i_len = (H); i < i_len; ++i) {
    for (int k = 0, k_len = (W); k < k_len; ++k) {
      if (S[i][k] == '#') continue;
      vector<vector<int>> f(H, vector<int>(W, 0));
      auto p = make_pair(i, k);
      queue<pair<pair<int, int>, int>> Q;
      Q.push(make_pair(p, 0));
      while (!Q.empty()) {
        cnt++;
        if (cnt > pow(10, 7)) break;
        auto x = Q.front();
        Q.pop();
        f[x.first.first][x.first.second] = 1;
        for (int q = 0; q < 4; ++q) {
          int a = x.first.first + dx[q];
          int b = x.first.second + dy[q];
          if (a < 0 || a >= H) continue;
          if (b < 0 || b >= W) continue;
          if (S[a][b] == '#') continue;
          if (f[a][b] == 1) continue;
          auto p = make_pair(a, b);
          Q.push(make_pair(p, x.second + 1));
          if (ans < x.second + 1) ans = x.second + 1;
        }
      }
    }
  }
  cout << ans << endl;
}
