#include <bits/stdc++.h>
using namespace std;
using Graph = vector<vector<int>>;
struct Corr {
  long long x;
  long long y;
  long long depth;
};
long long w, h;
long long s_y, s_x, g_y, g_x;
long long x, y, depth;
long long cnt;
long long ma;
vector<vector<char>> vec(20, vector<char>(20));
vector<vector<char>> moto(20, vector<char>(20));
vector<vector<long long>> suu(20, vector<long long>(20));
queue<Corr> q;
vector<long long> x_vec = {0, 0, -1, +1};
vector<long long> y_vec = {-1, +1, 0, 0};
long long bfs() {
  while (!q.empty()) {
    Corr now = q.front();
    q.pop();
    x = now.x, y = now.y, depth = now.depth;
    for (long long i = 0; i < 4; ++i) {
      Corr next = {x + x_vec[i], y + y_vec[i], depth + 1};
      if (0 <= next.y && next.y <= w - 1 && 0 <= next.x && next.x <= h - 1 &&
          vec[next.x][next.y] == '.') {
        vec[next.x][next.y] = '#';
        suu[next.x][next.y] = next.depth;
        q.push(next);
      }
    }
  }
  return 0;
}
int main() {
  cin >> h >> w;
  for (int i = 0; i < (int)(h); i++) {
    for (int j = 0; j < (int)(w); j++) {
      cin >> vec[i][j];
      moto[i][j] = vec[i][j];
    }
  }
  for (int i = 0; i < (int)(h); i++) {
    for (int j = 0; j < (int)(w); j++) {
      if (vec[i][j] == '.') {
        Corr start = {i, j, 0};
        q.push(start);
        bfs();
        for (int k = 0; k < (int)(h); k++) {
          for (int l = 0; l < (int)(w); l++) {
            ma = max(ma, suu[k][l]);
          }
        }
        for (int k = 0; k < (int)(h); k++) {
          for (int l = 0; l < (int)(w); l++) {
            vec[k][l] = moto[k][l];
            suu[k][l] = 0;
          }
        }
      }
    }
  }
  cout << ma << endl;
}
