#include <bits/stdc++.h>
using namespace std;
long long INFl = (long long)1e+18 + 1;
int INF = 1e+9 + 1;
int dp[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
int main() {
  int H, W;
  char S[25][25];
  cin >> H >> W;
  for (int i = 0; i < H; i++) {
    scanf("%s", S[i + 1] + 1);
  }
  for (int j = 0; j < W + 2; j++) {
    S[0][j] = '#';
    S[H + 1][j] = '#';
  }
  for (int i = 0; i < H + 2; i++) {
    S[i][0] = '#';
    S[i][W + 1] = '#';
  }
  for (int i = 0; i < H + 2; i++) {
    for (int j = 0; j < W + 2; j++) {
      printf("%c", S[i][j]);
    }
    cout << endl;
  }
  int ans = 0;
  for (int i = 1; i <= H; i++) {
    for (int j = 1; j <= W; j++) {
      if (S[i][j] == '.') {
        int dis[25][25];
        fill(dis[0], dis[24], INF);
        dis[i][j] = 0;
        vector<pair<int, int> > record;
        record.push_back({i, j});
        for (int count = 1; count <= INF; count++) {
          vector<pair<int, int> > before = record;
          record.clear();
          for (auto z : before) {
            int y = z.first, x = z.second;
            for (int k = 0; k < 4; k++) {
              int nexty = y + dp[k][0], nextx = x + dp[k][1];
              if (S[nexty][nextx] == '.' && dis[nexty][nextx] > count) {
                dis[nexty][nextx] = count;
                ans = max(ans, count);
                record.push_back({nexty, nextx});
              }
            }
          }
          if (record.empty()) break;
        }
      }
    }
  }
  cout << ans << endl;
  return 0;
}
