#include <bits/stdc++.h>
using namespace std;
const int INF = 1e8;
int H, W;
int blankMap[20][20];
vector<pair<int, int>> steps = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
int bfs(int initX, int initY) {
  int highestCost = 0;
  int simulateMap[20][20];
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      simulateMap[i][j] = blankMap[i][j];
    }
  }
  queue<tuple<int, int, int>> route;
  route.push(make_tuple(0, initX, initY));
  while (!route.empty()) {
    int cost, x, y;
    tie(cost, x, y) = route.front();
    route.pop();
    simulateMap[y][x] = min(simulateMap[y][x], cost);
    highestCost = max(highestCost, cost);
    for (auto step : steps) {
      int dx = step.first;
      int dy = step.second;
      if (0 <= x + dx && x + dx < W && 0 <= y + dy && y + dy < H &&
          cost + 1 < simulateMap[y + dy][x + dx]) {
        route.push(make_tuple(cost + 1, x + dx, y + dy));
      }
    }
  }
  return highestCost;
}
int main() {
  cin >> H >> W;
  string S[H];
  for (int i = 0; i < H; i++) {
    cin >> S[i];
    for (int j = 0; j < W; j++) {
      blankMap[i][j] = (S[i][j] == '#') ? -1 : INF;
    }
  }
  int ans = 0;
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      if (S[i][j] == '#') continue;
      ans = max(ans, bfs(j, i));
    }
  }
  cout << ans << endl;
  return 0;
}
