#include <bits/stdc++.h>
using namespace std;
template <class T>
inline bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T>
inline bool chmin(T &a, const T &b) {
  if (b < a) {
    a = b;
    return 1;
  }
  return 0;
}
const long long INF = 1ll << 60;
const long long MOD = 1e9 + 7ll;
const double PI = 3.14159265358979323846;
const int MAX_V = 500009;
vector<pair<int, long long> > d(MAX_V);
vector<vector<pair<int, long long> > > graph(MAX_V);
void dijkstra(int s) {
  priority_queue<pair<int, long long>, vector<pair<int, long long> >,
                 greater<pair<int, long long> > >
      que;
  for (int i = 0; i < d.size(); ++i) {
    d.at(i) = pair<int, long long>(-1, INF);
  }
  que.push(make_pair(s, 0ll));
  d.at(s) = pair<int, long long>(s, 0);
  while (!que.empty()) {
    pair<int, long long> p = que.top();
    que.pop();
    int v = p.first;
    if (p.second > d.at(v).second) continue;
    for (int i = 0; i < graph.at(v).size(); ++i) {
      pair<int, long long> edge = graph.at(v).at(i);
      if (d.at(edge.first).second > d.at(v).second + edge.second) {
        d.at(edge.first).second = d.at(v).second + edge.second;
        d.at(edge.first).first = v;
        que.push(make_pair(edge.first, d.at(edge.first).second));
      }
    }
  }
}
int main() {
  int H, W;
  cin >> H >> W;
  vector<string> s(H);
  for (int i = 0; i < H; i++) {
    cin >> s.at(i);
  }
  int start;
  int count = 0;
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      if (s[i][j] == '#') continue;
      if (i >= 1) {
        if (s[i - 1][j] == '.')
          graph[i * W + j].emplace_back((i - 1) * W + j, 1ll);
      }
      if (i < H - 1) {
        if (s[i + 1][j] == '.')
          graph[i * W + j].emplace_back((i + 1) * W + j, 1ll);
      }
      if (j >= 1) {
        if (s[i][j - 1] == '.')
          graph[i * W + j].emplace_back(i * W + j - 1, 1ll);
      }
      if (j < W - 1) {
        if (s[i][j + 1] == '.')
          graph[i * W + j].emplace_back(i * W + j + 1, 1ll);
      }
      start = i * W + j;
      count++;
    }
  }
  dijkstra(start);
  int restart;
  int distance = 0;
  for (int i = 0; i < H * W; i++) {
    if (distance < d[i].second && d[i].second < INF) {
      restart = i;
      distance = d[i].second;
    }
  }
  dijkstra(restart);
  distance = 0;
  for (int i = 0; i < H * W; i++) {
    if (distance < d[i].second && d[i].second < INF) distance = d[i].second;
  }
  cout << distance << endl;
  return 0;
}
