#include <bits/stdc++.h>
using namespace std;
using ll = long long;
vector<string> maps;
int H, W;
const int dx[4] = {1, -1, 0, 0};
const int dy[4] = {0, 0, 1, -1};
void view(vector<string> field, int h) {
  for (int i = 0; i < h; i++) {
    cout << field.at(i) << endl;
  }
  cout << endl;
}
int search(vector<string> field, int h, int w) {
  queue<pair<vector<int>, int>> que;
  vector<int> b1 = {h, w};
  field.at(h).at(w) = 's';
  que.push(make_pair(b1, 0));
  int count = 0;
  int ans = 0;
  while (!que.empty()) {
    pair<vector<int>, int> buf = que.front();
    que.pop();
    count = buf.second + 1;
    for (int i = 0; i < 4; i++) {
      int yy = buf.first.at(0) + dy[i];
      int xx = buf.first.at(1) + dx[i];
      if (yy < 0 || xx < 0 || yy >= H || xx >= W) {
        continue;
      } else {
        if (field.at(yy).at(xx) == '.') {
          vector<int> b2 = {yy, xx};
          que.push(make_pair(b2, count));
          ans = max(ans, count);
          field.at(yy).at(xx) = 's';
        }
      }
    }
  }
  return ans;
}
int main() {
  cin >> H >> W;
  maps = vector<string>(H);
  for (int i = 0; i < H; i++) {
    cin >> maps.at(i);
  }
  int ans = 0;
  for (int h = 0; h < H; h++) {
    for (int w = 0; w < W; w++) {
      ans = max(ans, search(maps, h, w));
    }
  }
  cout << ans << endl;
}
