#include <bits/stdc++.h>
const int INF = 1000;
using namespace std;
using P = pair<int, pair<int, int> >;
bool wall[20][20];
int H, W;
int distMaze(int sx, int sy) {
  if (wall[sy][sx] == true) {
    return -1;
  }
  priority_queue<P, vector<P>, greater<P> > que;
  int d[H][W];
  for (int y = 0; y < H; y++) {
    for (int x = 0; x < W; x++) {
      d[y][x] = INF;
    }
  }
  d[sy][sx] = 0;
  que.push(make_pair(0, make_pair(sx, sy)));
  while (!que.empty()) {
    P p = que.top();
    que.pop();
    auto pos = p.second;
    int cur_x = pos.first;
    int cur_y = pos.second;
    if (d[cur_y][cur_x] < p.first) continue;
    int dx[] = {0, 0, -1, 1};
    int dy[] = {1, -1, 0, 0};
    for (int i = 0; i < 4; i++) {
      int next_x = dx[i] + cur_x;
      int next_y = dy[i] + cur_y;
      if (wall[next_y][next_x] == true) continue;
      if (next_y < 0 || next_y >= H || cur_x < 0 || cur_x >= W) continue;
      if (d[next_y][next_x] > d[cur_y][cur_x] + 1) {
        d[next_y][next_x] = d[cur_y][cur_x] + 1;
        que.push(make_pair(d[next_y][next_x], make_pair(next_x, next_y)));
      }
    }
  }
  int ans = 0;
  for (int y = 0; y < H; y++) {
    for (int x = 0; x < W; x++) {
      int cur = d[y][x];
      if (cur < INF) {
        if (ans < cur) {
          ans = cur;
        }
      }
    }
  }
  return ans;
}
int main() {
  cin >> H >> W;
  for (int y = 0; y < H; y++) {
    string s;
    cin >> s;
    for (int x = 0; x < W; x++) {
      if (s.at(x) == '.') {
        wall[y][x] = false;
      } else {
        wall[y][x] = true;
      }
    }
  }
  int max = 0;
  for (int y = 0; y < H; y++) {
    for (int x = 0; x < W; x++) {
      int cur = distMaze(x, y);
      cout << "x:" << x << " y:" << y << "cur:" << cur << endl;
      if (cur > max) {
        max = cur;
      }
    }
  }
  cout << max << endl;
  return 0;
}
