#include <bits/stdc++.h>
using namespace std;
int dr1[] = {-1, 0, 1, 0};
int dc1[] = {0, 1, 0, -1};
const int MOD = 1000000007;
const int INF = 1000000007;
long long modx(long long a) { return (a % MOD + MOD) % MOD; }
long long times(long long a, long long b) { return modx(modx(a) * modx(b)); }
long long add(long long a, long long b) { return modx(modx(a) + modx(b)); }
long long sub(long long a, long long b) {
  return modx(MOD + modx(a) - modx(b));
}
long long fastExp(long long base, long long exp) {
  if (exp == 0LL) {
    return 1LL;
  }
  if (exp % 2 == 0) {
    return fastExp(times(base, base), exp / 2);
  } else {
    return times(base, fastExp(times(base, base), exp / 2));
  }
}
const int MAXN = (int)1e5 + 1;
int N, dist[441][441];
char grid[21][21];
int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  int H, W;
  cin >> H >> W;
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      cin >> grid[i][j];
    }
  }
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      for (int k = 0; k < H; k++) {
        for (int l = 0; l < W; l++) {
          dist[W * i + j][W * k + l] = INF;
        }
      }
    }
  }
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      for (int k = 0; k < 4; k++) {
        int r = i + dr1[k];
        int c = j + dc1[k];
        if (r < 0 || r >= H || c < 0 || c >= W) continue;
        if (grid[i][j] == '#' || grid[r][c] == '#') continue;
        dist[W * i + j][W * r + c] = 1;
      }
    }
  }
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      for (int k = 0; k < H; k++) {
        for (int l = 0; l < W; l++) {
          if (grid[i][j] == '#' || grid[k][l] == '#') continue;
          for (int a = 0; a < H; a++) {
            for (int b = 0; b < W; b++) {
              if (grid[a][b] == '#') continue;
              dist[W * k + l][W * a + b] =
                  min(dist[W * k + l][W * a + b],
                      dist[W * k + l][W * i + j] + dist[W * i + j][W * a + b]);
            }
          }
        }
      }
    }
  }
  int ans = 0;
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      for (int k = 0; k < H; k++) {
        for (int l = 0; l < W; l++) {
          if (grid[i][j] == '#' || grid[k][l] == '#') continue;
          ans = max(ans, dist[W * i + j][W * k + l]);
        }
      }
    }
  }
  cout << ans;
  return 0;
}
