#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, count;
  node(int _x, int _y, int _count) {
    x = _x;
    y = _y;
    count = _count;
  }
};
int H, W;
int bfs(queue<node> q, node goal) {
  node now = q.front();
  q.pop();
  if (now.x == goal.x && now.y == goal.y) {
    return now.count;
  }
  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] == '.') {
      q.push(node(x, y, now.count + 1));
    }
  }
  return bfs(q, goal);
}
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++) {
      for (int k = 0; k < (int)H; k++) {
        for (int l = 0; l < (int)W; l++) {
          node start = node(i, j, 0);
          node goal = node(k, l, 0);
          if (maze[start.x][start.y] == '.' && maze[goal.x][goal.y] == '.') {
            queue<node> q;
            q.push(start);
            int solution = bfs(q, goal);
            if (solution > ans) {
              ans = solution;
            }
          }
        }
      }
    }
  }
  cout << ans << endl;
}
