#include <bits/stdc++.h>
using namespace std;
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;
}
using ll = long long;
const ll mod = 1e9 + 7;
int INF = INT_MAX;
ll LLINF = 1LL << 60;
const vector<int> d8x = {1, 0, -1, 0, 1, -1, -1, 1};
vector<int> d8y = {0, 1, 0, -1, 1, 1, -1, -1};
const vector<int> d4x = {1, 0, -1, 0};
vector<int> d4y = {0, 1, 0, -1};
ll h, w;
vector<vector<char>> maze(21, vector<char>(21));
vector<vector<ll>> dist(21, vector<ll>(21));
vector<vector<bool>> seen(21, vector<bool>(21));
ll bfs(ll s1, ll s2) {
  for (int i = (0); i < (int)(h); i++)
    for (int j = (0); j < (int)(w); j++) {
      dist[i][j] = -INF;
      seen[i][j] = false;
    }
  queue<pair<ll, ll>> que;
  dist[s1][s2] = 0;
  que.push({s1, s2});
  while (!que.empty()) {
    pair<ll, ll> p = que.front();
    que.pop();
    ll y = p.first;
    ll x = p.second;
    seen[y][x] = true;
    for (int i = (0); i < (int)(4); i++) {
      ll nx = x + d4x[i];
      ll ny = y + d4y[i];
      if (0 <= ny && ny < h && 0 <= nx && nx < w && (seen[ny][nx] == false) &&
          (maze[ny][nx] != '#')) {
        que.push({ny, nx});
        dist[ny][nx] = dist[y][x] + 1;
      }
    }
  }
  ll temp = 0;
  for (int i = (0); i < (int)(h); i++)
    for (int j = (0); j < (int)(w); j++) temp = max(temp, dist[i][j]);
  return temp;
}
int main() {
  cin >> h >> w;
  for (int i = (0); i < (int)(h); i++)
    for (int j = (0); j < (int)(w); j++) cin >> maze[i][j];
  ll ans = 0;
  for (int i = (0); i < (int)(h); i++)
    for (int j = (0); j < (int)(w); j++)
      if (maze[i][j] != '#') ans = max(ans, bfs(i, j));
  cout << ans << endl;
}
