#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vi = vector<int>;
using vvi = vector<vi>;
using vll = vector<ll>;
using vvll = vector<vll>;
using pii = pair<int, int>;
using ul = unsigned long;
template <class T>
inline bool chmax(T& a, T b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T>
inline bool chmin(T& a, T b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}
ll GCD(ll a, ll b) { return b ? GCD(b, a % b) : a; }
ll LCM(ll a, ll b) { return a / GCD(a, b) * b; }
const int dy[] = {0, 1, 0, -1, -1, 1, 1, -1};
const int dx[] = {1, 0, -1, 0, 1, 1, -1, -1};
inline bool inside(int y, int x, int H, int W) {
  return (y >= 0 && x >= 0 && y < H && x < W);
}
const int INF = 1e9;
const int MOD = 1e9 + 7;
const ll LINF = 1e18;
int h, w;
vector<string> g(25);
int bfs(int y, int x) {
  int cost[25][25];
  for (int i = (int)(0); i < (int)(h); ++i)
    for (int j = (int)(0); j < (int)(w); ++j) cost[i][j] = 10000;
  cost[y][x] = 0;
  queue<pii> q;
  q.push(pii(y, x));
  int res = 0;
  while (!q.empty()) {
    pii now = q.front();
    q.pop();
    for (int i = (int)(0); i < (int)(4); ++i) {
      int ny = now.first + dy[i];
      int nx = now.second + dx[i];
      if (inside(ny, nx, h, w) && g[ny][nx] == '.' &&
          cost[ny][nx] >= cost[now.first][now.second]) {
        q.push(pii(ny, nx));
        cost[ny][nx] = cost[now.first][now.second] + 1;
        chmax(res, cost[ny][nx]);
      }
    }
  }
  return res;
}
signed main() {
  cin >> h >> w;
  for (int i = (int)(0); i < (int)(h); ++i) cin >> g[i];
  int ans = 0;
  for (int i = (int)(0); i < (int)(h); ++i) {
    for (int j = (int)(0); j < (int)(w); ++j) {
      if (g[i][j] == '#') continue;
      chmax(ans, bfs(i, j));
    }
  }
  cout << ans << endl;
}
