#include <bits/stdc++.h>
using namespace std;
using point = pair<int, int>;
int64_t BFS(vector<string>& maze, int h, int w, int H, int W) {
  queue<point> q;
  q.push(make_pair(h, w));
  set<pair<int, int>> s;
  int dist = -1;
  while (!q.empty()) {
    vector<point> points;
    while (!q.empty()) {
      point p = q.front();
      q.pop();
      if (maze[p.first][p.second] == '#') continue;
      points.push_back(p);
    }
    if (points.empty()) break;
    ++dist;
    for (point p : points) {
      s.insert(p);
      if (p.first != 0) {
        point p2 = make_pair(p.first - 1, p.second);
        if (s.count(p2) == 0) {
          q.push(p2);
        }
      }
      if (p.first != H - 1) {
        point p2 = make_pair(p.first + 1, p.second);
        if (s.count(p2) == 0) {
          q.push(p2);
        }
      }
      if (p.second != 0) {
        point p2 = make_pair(p.first, p.second - 1);
        if (s.count(p2) == 0) {
          q.push(p2);
        }
      }
      if (p.second != W - 1) {
        point p2 = make_pair(p.first, p.second + 1);
        if (s.count(p2) == 0) {
          q.push(p2);
        }
      }
    }
  }
  return dist;
}
int main() {
  int H, W;
  cin >> H >> W;
  vector<string> maze(H);
  for (size_t i = 0; i < H; ++i) {
    cin >> maze[i];
  }
  int64_t res = 0;
  for (size_t h = 0; h < H; ++h) {
    for (size_t w = 0; w < W; ++w) {
      if (maze[h][w] == '.') {
        int64_t dist = BFS(maze, h, w, H, W);
        res = max(res, dist);
      }
    }
  }
  cout << res << endl;
  return 0;
}
