#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const ll MOD = 1000000007;
vector<vector<char>> maze;
vector<int> dx = {1, 0, -1, 0};
vector<int> dy = {0, 1, 0, -1};
struct node {
  int x, y;
  node(int _x, int _y) {
    x = _x;
    y = _y;
  }
};
int H, W;
int bfs(queue<node> q, vector<vector<int>> shortest_move, int max_count) {
  node now = q.front();
  q.pop();
  if (shortest_move[now.x][now.y] > max_count) {
    max_count = shortest_move[now.x][now.y];
  }
  for (int i : {0, 1, 2, 3}) {
    int x = now.x + dx[i];
    int y = now.y + dy[i];
    bool cond1 = 0 <= x && x < H;
    bool cond2 = 0 <= y && y < W;
    if (cond1 && cond2 && maze[x][y] == '.' && shortest_move[x][y] == -1) {
      shortest_move[x][y] = shortest_move[now.x][now.y] + 1;
      q.push(node(x, y));
    }
  }
  if (q.empty()) {
    return max_count;
  } else {
    return bfs(q, shortest_move, max_count);
  }
}
int main() {
  cin >> H >> W;
  for (int i = 0; i < (int)H; i++) {
    maze.push_back({});
    for (int j = 0; j < (int)W; j++) {
      char temp;
      cin >> temp;
      maze[i].push_back(temp);
    }
  }
  int ans = -1;
  for (int i = 0; i < (int)H; i++) {
    for (int j = 0; j < (int)W; j++) {
      node start = node(i, j);
      if (maze[start.x][start.y]) {
        queue<node> q;
        q.push(start);
        vector<vector<int>> shortest_move(H, vector<int>(W, -1));
        shortest_move[start.x][start.y] = 0;
        int max_count = bfs(q, shortest_move, 0);
        if (max_count > ans) {
          ans = max_count;
        }
      }
    }
  }
  cout << ans << endl;
}
