#include <bits/stdc++.h>
using namespace std;
struct Point {
  int x;
  int y;
};
const char WALL = '#';
const char ROAD = '.';
const vector<int> dx = {-1, 0, 1, 0};
const vector<int> dy = {0, -1, 0, 1};
int max_dist(vector<vector<char>> maze, Point start) {
  vector<vector<int>> dists(maze.size(), vector<int>(maze.at(0).size(), -1));
  dists.at(start.y).at(start.x) = 0;
  int max_dist = 0;
  queue<Point> q;
  q.push(start);
  while (!q.empty()) {
    Point a = q.front();
    q.pop();
    int ad = dists.at(a.y).at(a.x);
    for (int i = 0; i < (4); ++i) {
      Point p = {a.x + dx.at(i), a.y + dy.at(i)};
      if (maze.at(p.y).at(p.x) == ROAD) {
        int pd = dists.at(p.y).at(p.x);
        if (pd < 0 || pd > ad + 1) {
          dists.at(p.y).at(p.x) = ad + 1;
          max_dist = max(max_dist, ad + 1);
          q.push(p);
        }
      }
    }
  }
  return max_dist;
}
int main() {
  int H, W;
  cin >> H >> W;
  vector<vector<char>> maze(H + 2, vector<char>(W + 2, WALL));
  for (int y = 1; y <= (H); ++y) {
    string s;
    cin >> s;
    for (int x = 1; x <= (W); ++x) maze.at(y).at(x) = s.at(x - 1);
  }
  int ans = 0;
  for (int i = 1; i <= (H); ++i) {
    for (int j = 1; j <= (W); ++j) {
      Point p = {j, i};
      int d = max_dist(maze, p);
      ans = max(ans, d);
    }
  }
  cout << ans << endl;
  return 0;
}
