#include <bits/stdc++.h>
using namespace std;
using lint = long long;
const int INF = 1e9;
const lint LINF = 1e18;
const lint MOD = 1e9 + 7;
const double EPS = 1e-10;
int dx[4] = {1, 0, -1, 0}, dy[4] = {0, 1, 0, -1};
int main() {
  int h, w;
  cin >> h >> w;
  vector<string> G(h);
  for (int i = (int)(0); i < (int)(h); i++) {
    cin >> G[i];
  }
  int ma = 0;
  for (int x = 0; x < h; x++) {
    for (int y = 0; y < w; y++) {
      if (G[x][y] == '#') {
        continue;
      } else {
        queue<pair<int, int>> q;
        vector<vector<int>> dist(h, vector<int>(w, -1));
        vector<vector<int>> check(h, vector<int>(w, -1));
        dist[x][y] = 0;
        q.push(make_pair(x, y));
        while (!q.empty()) {
          pair<int, int> node = q.front();
          q.pop();
          for (int i = 0; i < 4; i++) {
            pair<int, int> n_node =
                make_pair(node.first + dx[i], node.second + dy[i]);
            if (0 <= n_node.first and n_node.first < h and
                0 <= n_node.second and n_node.second < w and
                G[n_node.first][n_node.second] == '.' and
                check[n_node.first][n_node.second] == -1) {
              q.push(n_node);
              check[n_node.first][n_node.second] = 1;
              dist[n_node.first][n_node.second] =
                  dist[node.first][node.second] + 1;
              q.push(n_node);
            }
          }
        }
        int mma = -1;
        for (int i = 0; i < h; i++) {
          for (int j = 0; j < w; j++) {
            mma = max(dist[i][j], mma);
          }
        }
        ma = max(ma, mma);
      }
    }
  }
  cout << ma << endl;
  return 0;
}
