#include <bits/stdc++.h>
using namespace std;
int bfs(vector<vector<char>> s, int h, int w, int i, int j) {
  vector<vector<int>> visited(h, vector<int>(w, -1));
  int cost = -1;
  int max_cost;
  queue<tuple<int, int, int>> q;
  q.push(make_tuple(i, j, cost));
  while (!q.empty()) {
    int y, x, cost;
    tie(y, x, cost) = q.front();
    q.pop();
    cost++;
    visited.at(y).at(x) = cost;
    if (y - 1 >= 0 && s.at(y - 1).at(x) == '.' &&
        visited.at(y - 1).at(x) == -1) {
      q.push(make_tuple(y - 1, x, cost));
    }
    if (y + 1 < h && s.at(y + 1).at(x) == '.' &&
        visited.at(y + 1).at(x) == -1) {
      q.push(make_tuple(y + 1, x, cost));
    }
    if (x - 1 >= 0 && s.at(y).at(x - 1) == '.' &&
        visited.at(y).at(x - 1) == -1) {
      q.push(make_tuple(y, x - 1, cost));
    }
    if (x + 1 < w && s.at(y).at(x + 1) == '.' & visited.at(y).at(x + 1) == -1) {
      q.push(make_tuple(y, x + 1, cost));
    }
    if (q.empty()) max_cost = cost;
  }
  return max_cost;
}
int main() {
  int h, w;
  cin >> h >> w;
  vector<vector<char>> s(h, vector<char>(w));
  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      cin >> s.at(i).at(j);
    }
  }
  int ans = 0;
  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      if (s.at(i).at(j) == '.') {
        ans = max(ans, bfs(s, h, w, i, j));
      }
    }
  }
  cout << ans << endl;
  return 0;
}
