#include <bits/stdc++.h>
using namespace std;
const int MOD = 1000000007;
const int INF = 2002002002;
const long long LLINF = 9009009009009009009;
bool dis(int w, int h, int nx, int ny) {
  if (nx < 0)
    return false;
  else if (nx >= w)
    return false;
  else if (ny < 0)
    return false;
  else if (ny >= h)
    return false;
  return true;
}
struct Mp {
  int x, y, c;
  Mp(int x_, int y_, int c_) {
    x = x_;
    y = y_;
    c = c_;
  }
};
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  int h, w;
  cin >> h >> w;
  vector<vector<char>> m(h, vector<char>(w)), m_copy;
  for (int i = 0; i < h; ++i) {
    for (int j = 0; j < w; ++j) {
      cin >> m[i][j];
    }
  }
  m_copy = m;
  int nx, ny, nc;
  int total_c = 0;
  int dir[4][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
  queue<Mp> q;
  for (int i = 0; i < w; ++i) {
    for (int j = 0; j < h; ++j) {
      m = m_copy;
      int sx = i, sy = j;
      if (m[sy][sx] == '#') continue;
      while (!q.empty()) q.pop();
      q.emplace(sx, sy, 0);
      while (!q.empty()) {
        for (auto d : dir) {
          nx = q.front().x + d[0];
          ny = q.front().y + d[1];
          nc = q.front().c + 1;
          if (dis(w, h, nx, ny)) {
            if (m[ny][nx] == '.') {
              q.emplace(nx, ny, nc);
              m[ny][nx] = '#';
            }
          }
        }
        q.pop();
      }
      total_c = max(total_c, nc - 1);
    }
  }
  cout << total_c << endl;
  return 0;
}
