#include <bits/stdc++.h>
using namespace std;
const long long INF = 1e18L + 1;
int main() {
  int H, W;
  cin >> H >> W;
  vector<string> maze;
  for (int i = 0; i < (H); ++i) {
    string t;
    cin >> t;
    maze.push_back(t);
  }
  auto bfs = [&](pair<int, int> start, pair<int, int> goal) {
    queue<pair<int, int> > q;
    queue<pair<int, int> > next;
    vector<vector<bool> > visited(H, vector<bool>(W, false));
    int dx[] = {1, 0, -1, 0}, dy[] = {0, -1, 0, 1};
    next.push(start);
    int level = 0;
    while (next.size()) {
      while (next.size()) {
        q.push(next.front());
        next.pop();
      }
      while (q.size()) {
        pair<int, int> p = q.front();
        q.pop();
        if (p == goal) break;
        for (int m = 0; m < 4; m++) {
          if (p.first + dy[m] >= 0 && p.first + dy[m] < H &&
              p.second + dx[m] >= 0 && p.second + dx[m] < W &&
              maze[p.first + dy[m]][p.second + dx[m]] == '.' &&
              !visited[p.first + dy[m]][p.second + dx[m]]) {
            next.push(pair<int, int>(p.first + dy[m], p.second + dx[m]));
            visited[p.first + dy[m]][p.second + dx[m]] = true;
          }
        }
      }
      level++;
    }
    return --level;
  };
  int ans = 0;
  for (int i = 0; i < (H); ++i) {
    for (int j = 0; j < (W); ++j) {
      if (maze[i][j] == '#') continue;
      for (int k = 0; k < (H); ++k)
        for (int l = 0; l < (W); ++l) {
          int result = bfs(pair<int, int>(i, j), pair<int, int>(k, l));
          ans = max(ans, result);
        }
    }
  }
  cout << ans << endl;
  return 0;
}
