#include <bits/stdc++.h>
using namespace std;
int main() {
  int H, W;
  cin >> H >> W;
  vector<vector<char>> field(H, vector<char>(W));
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      char c;
      cin >> c;
      field[i][j] = c;
    }
  }
  vector<vector<int>> directions = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
  int cost_max = 0;
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      vector<vector<int>> visited(H, vector<int>(W));
      pair<int, int> s(i, j);
      if (field[i][j] == '#') continue;
      queue<pair<int, pair<int, int>>> que;
      pair<int, pair<int, int>> p_(0, s);
      que.push(p_);
      while (que.size() > 0) {
        pair<int, pair<int, int>> q = que.front();
        que.pop();
        int cost = q.first;
        pair<int, int> pos = q.second;
        int x = pos.first;
        int y = pos.second;
        visited[x][y] = 1;
        for (int k = 0; k < directions.size(); k++) {
          vector<int> direction = directions[k];
          int dx = direction[0];
          int dy = direction[1];
          int nx = x + dx;
          int ny = y + dy;
          int ncost = cost + 1;
          if (nx < 0 || nx >= H || ny < 0 || ny >= W) continue;
          if (field[nx][ny] == '#') continue;
          if (field[nx][ny] == '.' && visited[nx][ny] == 0) {
            pair<int, int> np(nx, ny);
            pair<int, pair<int, int>> p(ncost, np);
            if (cost_max < ncost) cost_max = ncost;
            que.push(p);
          }
        }
      }
    }
  }
  cout << cost_max << endl;
}
