#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using Pii = pair<int, int>;
using Pll = pair<ll, ll>;
template <class T>
using Vvec = vector<vector<T> >;
class Edge {
 public:
  int from, to;
  long long cost;
  Edge() : from(0), to(0), cost(0){};
  Edge(int u, int v, long long w) : from(u), to(v), cost(w){};
  ~Edge(){};
};
void Warshall_Floyd(std::vector<Edge> &edge, int V,
                    std::vector<std::vector<long long> > &d) {
  int E = edge.size();
  const long long infty = 1e+16;
  d.clear();
  d.resize(V);
  for (int i = 0; i < V; i++) {
    for (int j = 0; j < V; j++) d[i].push_back(infty);
  }
  for (int i = 0; i < E; i++) {
    d[edge[i].from][edge[i].to] = edge[i].cost;
  }
  for (int i = 0; i < V; i++) d[i][i] = 0;
  for (int k = 0; k < V; k++) {
    for (int i = 0; i < V; i++) {
      for (int j = 0; j < V; j++)
        d[i][j] = std::min(d[i][j], d[i][k] + d[k][j]);
    }
  }
}
int main() {
  int H, W;
  cin >> H >> W;
  Vvec<char> S(H, vector<char>(W));
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) cin >> S[i][j];
  }
  vector<Edge> edge;
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W - 1; j++) {
      if (S[i][j] == '.' && S[i][j + 1] == '.') {
        edge.emplace_back(i * H + j, i * H + j + 1, 1);
        edge.emplace_back(i * H + j + 1, i * H + j, 1);
      }
    }
  }
  for (int i = 0; i < H - 1; i++) {
    for (int j = 0; j < W; j++) {
      if (S[i][j] == '.' && S[i + 1][j] == '.') {
        edge.emplace_back(i * H + j, (i + 1) * H + j, 1);
        edge.emplace_back((i + 1) * H + j, i * H + j, 1);
      }
    }
  }
  Vvec<ll> dist;
  Warshall_Floyd(edge, H * W, dist);
  ll ans = 0;
  for (int i = 0; i < H * W; i++) {
    for (int j = 0; j < H * W; j++) {
      if (dist[i][j] < 1e9) ans = max(ans, dist[i][j]);
    }
  }
  cout << ans << endl;
}
