#include <bits/stdc++.h>
using namespace std;
void calcAllShortest(vector<vector<pair<int, long long>>>& G,
                     vector<vector<long long>>& d) {
  auto numV = (int)G.size();
  for (auto i = 0; i < numV; ++i) {
    d.push_back(vector<long long>(numV, LLONG_MAX));
    for (auto v : G[i]) {
      d[i][v.first] = v.second;
    }
  }
  for (auto k = 0; k < numV; ++k) {
    for (auto i = 0; i < numV; ++i) {
      for (auto j = 0; j < numV; ++j) {
        if (d[i][k] >= LLONG_MAX || d[k][j] >= LLONG_MAX) {
          continue;
        }
        auto kd = d[i][k] + d[k][j];
        if (d[i][j] > kd) {
          d[i][j] = kd;
        }
      }
    }
  }
}
int main() {
  int H, W;
  cin >> H >> W;
  vector<string> S(H);
  for (auto i = 0; i < H; ++i) {
    cin >> S[i];
  }
  int offset[4][2] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
  vector<vector<pair<int, long long>>> G(H * W);
  for (auto y = 0; y < H; ++y) {
    for (auto x = 0; x < W; ++x) {
      if (S[y][x] == '#') {
        continue;
      }
      auto& temp = G[y * W + x];
      for (auto i = 0; i < 4; ++i) {
        auto ny = y + offset[i][0];
        auto nx = x + offset[i][1];
        if (ny < 0 || ny >= H || nx < 0 || nx >= W) {
          continue;
        }
        if (S[ny][nx] == '#') {
          continue;
        }
        temp.push_back({ny * W + nx, 1});
      }
    }
  }
  vector<vector<long long>> d;
  calcAllShortest(G, d);
  auto result = 0ll;
  for (auto y = 0; y < H; ++y) {
    for (auto x = 0; x < W; ++x) {
      for (auto gy = 0; gy < H; ++gy) {
        for (auto gx = 0; gx < W; ++gx) {
          auto temp = d[y * W + x][gy * W + gx];
          if (temp <= H * W) {
            result = max(result, temp);
          }
        }
      }
    }
  }
  cout << result << endl;
  return 0;
}
