#include <bits/stdc++.h>
using namespace std;
template <typename T, typename U>
bool chmin(T &a, const U &b) {
  return (a > b ? a = b, true : false);
}
template <typename T, typename U>
bool chmax(T &a, const U &b) {
  return (a < b ? a = b, true : false);
}
const long long INF = 1000000000;
int dx[5] = {1, -1, 0, 0};
int dy[5] = {0, 0, 1, -1};
int h, w;
char maze[20][20];
int judge[20][20];
int ans = 0;
int cnt[20][20];
void inite() {
  for (int i = 0; i < 20; i++) {
    for (int j = 0; j < 20; j++) {
      cnt[i][j] = INF;
      judge[i][j] = true;
    }
  }
}
void dfs(int y, int x) {
  for (int i = 0; i < 4; i++) {
    int nx = x + dx[i];
    int ny = y + dy[i];
    if (nx >= 0 && nx < w && ny >= 0 && ny < h && maze[ny][nx] != '#' &&
        judge[ny][nx]) {
      cnt[ny][nx] = min(cnt[ny][nx], cnt[y][x] + 1);
      judge[ny][nx] = false;
      dfs(ny, nx);
    }
  }
  return;
}
int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  cin >> h >> w;
  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      cin >> maze[i][j];
    }
  }
  int ans = 0;
  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      inite();
      if (maze[i][j] != '#') {
        cnt[i][j] = 0;
        dfs(i, j);
        for (int i = 0; i < h; i++) {
          for (int j = 0; j < w; j++) {
            if (cnt[i][j] != INF) ans = max(ans, cnt[i][j]);
          }
        }
      }
    }
  }
  cout << ans << "\n";
  ;
}
