#include <bits/stdc++.h>
using namespace std;
template <class T>
bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T>
bool chmin(T &a, const T &b) {
  if (b < a) {
    a = b;
    return 1;
  }
  return 0;
}
template <typename T>
std::string printVector(const std::vector<T> &data) {
  std::stringstream ss;
  std::ostream_iterator<T> out_it(ss, ", ");
  ss << "[";
  std::copy(data.begin(), data.end() - 1, out_it);
  ss << data.back() << "]";
  return ss.str();
}
template <typename T>
void print_array(const T &ary, int size) {
  for (int i = (0); i < (size); ++i) {
    cout << ary[i] << " ";
  }
  cout << endl;
}
const int MOD = 1e9 + 7;
const long long LINF = 1001002003004005006ll;
const int INF = 1001001001;
const double EPS = (1e-10);
int maze[25][25] = {};
template <typename T>
struct edge {
  int src, to;
  T cost;
  edge(int to, T cost) : src(-1), to(to), cost(cost) {}
  edge(int src, int to, T cost) : src(src), to(to), cost(cost) {}
  edge &operator=(const int &x) {
    to = x;
    return *this;
  }
  operator int() const { return to; }
};
template <typename T>
using Edges = vector<edge<T> >;
template <typename T>
using WeightedGraph = vector<Edges<T> >;
using UnWeightedGraph = vector<vector<int> >;
template <typename T>
using Matrix = vector<vector<T> >;
template <typename T>
void warshall_floyd(Matrix<T> &g, T INF) {
  for (int k = 0; k < g.size(); k++) {
    for (int i = 0; i < g.size(); i++) {
      for (int j = 0; j < g.size(); j++) {
        if (g[i][k] == INF || g[k][j] == INF) continue;
        g[i][j] = min(g[i][j], g[i][k] + g[k][j]);
      }
    }
  }
}
int dx[] = {0, 0, -1, 1};
int dy[] = {-1, 1, 0, 0};
signed main(int argc, char const *argv[]) {
  cin.tie(0);
  ios::sync_with_stdio(false);
  cout << setprecision(12);
  int H, W;
  cin >> H >> W;
  for (int i = (0); i < (H); ++i) {
    string s;
    cin >> s;
    for (int j = (0); j < (W); ++j) {
      if (s[j] == '#') maze[i][j] = 1;
    }
  }
  Matrix<int> g(H * W, vector<int>(H * W, INF));
  for (int i = (0); i < (H); ++i)
    for (int j = (0); j < (W); ++j) {
      if (maze[i][j] == 1) continue;
      int id = i * W + j;
      for (int k = (0); k < (4); ++k) {
        int ni = i + dx[k];
        int nj = j + dy[k];
        if (ni < 0 || ni >= H || nj < 0 || nj >= W) continue;
        if (maze[ni][nj] == 1) continue;
        int nid = ni * W + nj;
        g[id][nid] = 1;
        g[nid][id] = 1;
      }
    }
  warshall_floyd(g, INF);
  int ans = -1;
  for (int i = (0); i < (H * W); ++i)
    for (int j = (0); j < (H * W); ++j) {
      if (g[i][j] >= INF) continue;
      chmax(ans, g[i][j]);
    }
  cout << ans << endl;
}
