#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using edge = struct {
  int to;
  ll cost;
};
long long combination[10001][10001];
int ans = 0;
void solve() {
  int h, w;
  char maze[100][100];
  bool mazeVisit[100][100];
  int mazeDis[100][100];
  queue<pair<int, int>> mazeQ;
  vector<pair<int, int>> starts;
  cin >> h >> w;
  int ans = 0;
  for (int i = 0; i <= h + 1; i++)
    for (int j = 0; j <= w + 1; j++) {
      mazeVisit[i][j] = true;
      maze[i][j] = '#';
    }
  for (int i = 1; i <= h; i++)
    for (int j = 1; j <= w; j++) {
      char s;
      cin >> s;
      maze[i][j] = s;
      if (s == '.') starts.push_back(make_pair(i, j));
    }
  for (auto start : starts) {
    for (auto road : starts) {
      int i = road.first, j = road.second;
      mazeDis[i][j] = 0;
      mazeVisit[i][j] = false;
    }
    int i, j;
    mazeQ.push(make_pair(start.first, start.second));
    while (!mazeQ.empty()) {
      auto now = mazeQ.front();
      mazeQ.pop();
      i = now.first, j = now.second;
      mazeVisit[i][j] = true;
      if (!mazeVisit[i + 1][j]) mazeQ.push(make_pair(i + 1, j));
      mazeDis[i + 1][j] = mazeDis[i][j] + 1;
      if (!mazeVisit[i - 1][j]) mazeQ.push(make_pair(i - 1, j));
      mazeDis[i - 1][j] = mazeDis[i][j] + 1;
      if (!mazeVisit[i][j + 1]) mazeQ.push(make_pair(i, j + 1));
      mazeDis[i][j + 1] = mazeDis[i][j] + 1;
      if (!mazeVisit[i][j - 1]) mazeQ.push(make_pair(i, j - 1));
      mazeDis[i][j - 1] = mazeDis[i][j] + 1;
    }
    ans = max(ans, mazeDis[i][j]);
  }
  cout << ans << "\n";
}
int main() {
  solve();
  return 0;
}
