#include <bits/stdc++.h>
using namespace std;
const int N = 405;
int h, w;
vector<int> adj[N];
int grid[25][25];
pair<int, int> bfs(int node) {
  queue<int> q;
  vector<int> visited(N, -1);
  q.push(node);
  visited[node] = 0;
  while (!q.empty()) {
    auto x = q.front();
    q.pop();
    for (auto y : adj[x]) {
      if (visited[y] == -1) {
        visited[y] = 1 + visited[x];
        q.push(y);
      }
    }
  }
  int max_ans = 0;
  int at = -1;
  for (int i = 0; i < N; ++i) {
    if (visited[i] > max_ans) {
      max_ans = visited[i];
      at = i;
    }
  }
  return {at, max_ans};
}
void getDiameter() {
  int start = -1;
  for (int i = 0; i < N; ++i) {
    if (!adj[i].empty()) {
      start = i;
      break;
    }
  }
  pair<int, int> farthest = bfs(start);
  cout << bfs(farthest.first).second << '\n';
}
bool isValid(int i, int j) {
  if (i < 0 or i >= h or j < 0 or j >= w) {
    return false;
  }
  if (grid[i][j] == 1) {
    return false;
  }
  return true;
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cin >> h >> w;
  for (int i = 0; i < h; ++i) {
    string x;
    cin >> x;
    for (int j = 0; j < w; ++j) {
      if (x[j] == '.') {
        grid[i][j] = 0;
      } else {
        grid[i][j] = 1;
      }
    }
  }
  for (int i = 0; i < h; ++i) {
    for (int j = 0; j < w; ++j) {
      if (grid[i][j] == 0) {
        int pt = i * h + j;
        vector<int> dx = {1, -1, 0, 0};
        vector<int> dy = {0, 0, 1, -1};
        for (int k = 0; k < 4; ++k) {
          if (isValid(i + dx[k], j + dy[k])) {
            adj[pt].push_back((i + dx[k]) * h + (j + dy[k]));
            adj[(i + dx[k]) * h + (j + dy[k])].push_back(pt);
          }
        }
      }
    }
  }
  getDiameter();
  return 0;
}
