#include <bits/stdc++.h>
using namespace std;
int H, W;
int Two2One(int x, int y) { return y * W + x; }
pair<int, int> One2Two(int pos) {
  int x = pos % W;
  int y = pos / W;
  return make_pair(x, y);
}
inline int BFS(vector<vector<bool>> &s, int xs, int ys, int xe, int ye) {
  if (xs == xe && ys == ye) return 0;
  vector<pair<int, int>> proceed;
  proceed.emplace_back(make_pair(-1, 0));
  proceed.emplace_back(make_pair(1, 0));
  proceed.emplace_back(make_pair(0, -1));
  proceed.emplace_back(make_pair(0, 1));
  unordered_set<int> passed;
  queue<pair<int, int>> q;
  q.push(make_pair(Two2One(xs, ys), 0));
  while (!q.empty()) {
    auto curInfo = q.front();
    q.pop();
    int cur = curInfo.first;
    int distance = curInfo.second;
    auto pos = One2Two(cur);
    for (auto &elem : proceed) {
      int newX = pos.first + elem.first;
      int newY = pos.second + elem.second;
      if (newX < 0 || newY < 0 || newX >= W || newY >= H) continue;
      if (passed.find(Two2One(newX, newY)) != passed.end()) continue;
      if (!s[newY][newX]) continue;
      if (newX == xe && newY == ye) {
        return distance + 1;
      }
      passed.emplace(Two2One(newX, newY));
      q.push(make_pair(Two2One(newX, newY), distance + 1));
    }
  }
  return 0;
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cin >> H >> W;
  vector<vector<bool>> S(H, vector<bool>(W, false));
  for (int i = 0; i < H; i++) {
    string temp;
    cin >> temp;
    for (int j = 0; j < W; j++) S[i][j] = (temp[j] == '.');
  }
  int maxDistance = 0;
  for (int s = 0; s < H * W; s++) {
    auto pos_s = One2Two(s);
    if (!S[pos_s.second][pos_s.first]) continue;
    for (int e = s; e < H * W; e++) {
      auto pos_e = One2Two(e);
      if (!S[pos_e.second][pos_e.first]) continue;
      int distance =
          BFS(S, pos_s.first, pos_s.second, pos_e.first, pos_e.second);
      maxDistance = max(maxDistance, distance);
    }
  }
  cout << maxDistance;
  return 0;
}
