#include <bits/stdc++.h>
using namespace std;
using ll = long long;
struct P {
  int x;
  int y;
};
int maxstep(P start, vector<vector<string>> field) {
  vector<P> move = {
      {-1, 0},
      {1, 0},
      {0, -1},
      {0, 1},
  };
  vector<vector<int>> step(field.size(), vector<int>(field[0].size(), 0));
  queue<P> q;
  q.push(start);
  int r = 0;
  while (!q.empty()) {
    P cur = q.front();
    q.pop();
    for (auto m : move) {
      P next = P{cur.x + m.x, cur.y + m.y};
      if (next.x < 0 || field.size() <= next.x || next.y < 0 ||
          field[0].size() <= next.y) {
        continue;
      }
      if (field[next.x][next.y] == "#") {
        continue;
      }
      if (step[next.x][next.y]) {
        continue;
      }
      step[next.x][next.y] = step[cur.x][cur.y] + 1;
      q.push(P{next.x, next.y});
      r = max(r, step[next.x][next.y]);
    }
  }
  return r;
}
int main() {
  int h, w;
  cin >> h >> w;
  vector<vector<string>> field(h, vector<string>(w));
  for (int i = 0; i < h; ++i) {
    string s;
    cin >> s;
    for (int j = 0; j < w; ++j) {
      field[i][j] = s[j];
    }
  }
  int r = 0;
  for (int i = 0; i < h; ++i) {
    for (int j = 0; j < w; ++j) {
      if (field[i][j] == "#") {
        continue;
      }
      int mstep;
      mstep = maxstep(P{i, j}, field);
      r = max(r, mstep);
    }
  }
  cout << r;
}
