#include <bits/stdc++.h>
#pragma GCC optimize("Ofast")
#pragma GCC target("avx,avx2,fma")
using namespace std;
using bigint = long long int;
using vi = vector<int>;
using vll = vector<long long int>;
char ch[30][30];
bool visited[30][30];
int dx[] = {1, -1, 0, 0};
int dy[] = {0, 0, 1, -1};
int dist[30][30];
int N, M;
bool isValid(int x, int y) {
  if (x > N || x < 1 || y > M || y < 1 || visited[x][y] || ch[x][y] == '#')
    return false;
  return true;
}
int ans;
void bfs(int x, int y) {
  queue<pair<int, int> > q;
  q.push({x, y});
  while (!q.empty()) {
    pair<int, int> p = q.front();
    q.pop();
    int X = p.first, Y = p.second;
    for (int i = 0; i < 4; i++) {
      if (isValid(X + dx[i], Y + dy[i])) {
        visited[X + dx[i]][Y + dy[i]] = 1;
        q.push({X + dx[i], Y + dy[i]});
        dist[X + dx[i]][Y + dy[i]] = dist[X][Y] + 1;
        ans = max(ans, dist[X][Y] + 1);
      }
    }
  }
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);
  ;
  cin >> N >> M;
  for (int i = 1; i <= N; i++) {
    for (int j = 1; j <= M; j++) {
      cin >> ch[i][j];
    }
  }
  for (int i = 1; i <= N; i++) {
    for (int j = 1; j <= M; j++) {
      if (ch[i][j] != '#') {
        bfs(i, j);
        memset(visited, 0, sizeof(visited));
        memset(dist, 0, sizeof(dist));
      }
    }
  }
  cout << ans << "\n";
  return 0;
}
