#include <bits/stdc++.h>
using namespace std;
template <class Type_a, class Type_b>
void chmax(Type_a &a, const Type_b &b) {
  if (a < b) a = b;
}
template <class Type_a, class Type_b>
void chmin(Type_a &a, const Type_b &b) {
  if (a > b) a = b;
}
template <class Type>
Type igcd(Type x, Type y) {
  if (x == 0 or y == 0) return (x > y) ? x : y;
  return (y % x) ? igcd(y % x, x) : x;
}
template <class Type>
Type ilcm(Type x, Type y) {
  return x / igcd(x, y) * y;
}
template <class Type>
void line(const Type &a) {
  int cnt = 0;
  for (const auto &elem : a) {
    if (cnt++) cout << ' ';
    cout << elem;
  }
  cout << endl;
}
int h, w;
vector<string> s;
int dx[] = {0, -1, 1, 0};
int dy[] = {-1, 0, 0, 1};
int bfs(int y, int x) {
  int res = 0;
  vector<vector<int> > cnt(h, vector<int>(w, -1));
  cnt[y][x] = 0;
  queue<pair<int, int> > q;
  q.push(pair<int, int>(y, x));
  while (!q.empty()) {
    pair<int, int> tmp = q.front();
    q.pop();
    for (int i = 0; i < (4); ++i) {
      int ny = tmp.first + dy[i];
      int nx = tmp.second + dx[i];
      if (ny < 0 or h <= ny or nx < 0 or w <= nx) continue;
      if (s[ny][nx] == '#') continue;
      if (cnt[ny][nx] != -1) continue;
      q.push(pair<int, int>(ny, nx));
      cnt[ny][nx] = cnt[tmp.first][tmp.second] + 1;
      chmax(res, cnt[ny][nx]);
    }
  }
  cerr << "y"
       << ": " << (y) << endl;
  cerr << "x"
       << ": " << (x) << endl;
  for (int i = 0; i < (h); ++i) line(cnt[i]);
  return res;
}
int main() {
  cin >> h >> w;
  s.resize(h);
  for (int i = 0; i < (h); ++i) cin >> s[i];
  int ans = 0;
  for (int i = 0; i < (h); ++i)
    for (int j = 0; j < (w); ++j) {
      chmax(ans, bfs(i, j));
    }
  cout << ans << endl;
}
