#include <bits/stdc++.h>
using namespace std;
long long gcd(long long a, long long b) { return b ? gcd(b, a % b) : a; }
const long long dx[4] = {1, 0, -1, 0};
const long long dy[4] = {0, 1, 0, -1};
template <typename T>
istream& operator>>(istream& is, vector<T>& vec) {
  for (T& x : vec) is >> x;
  return is;
}
template <typename T, typename U>
ostream& operator<<(ostream& os, pair<T, U>& pair_var) {
  os << "(" << pair_var.first << ", " << pair_var.second << ")";
  return os;
}
template <typename T>
ostream& operator<<(ostream& os, const vector<T>& vec) {
  os << "{";
  for (long long i = 0; i < vec.size(); i++) {
    os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
  }
  os << "}";
  return os;
}
template <typename T, typename U>
ostream& operator<<(ostream& os, map<T, U>& map_var) {
  os << "{";
  for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
    os << *itr;
    itr++;
    if (itr != map_var.end()) os << ", ";
    itr--;
  }
  os << "}";
  return os;
}
template <typename T>
ostream& operator<<(ostream& os, set<T>& set_var) {
  os << "{";
  for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
    os << *itr;
    itr++;
    if (itr != set_var.end()) os << ", ";
    itr--;
  }
  os << "}";
  return os;
}
void dump_func() { cerr << endl; }
template <class Head, class... Tail>
void dump_func(Head&& head, Tail&&... tail) {
  cerr << head;
  if (sizeof...(Tail) > 0) {
    cerr << ", ";
  }
  dump_func(std::move(tail)...);
}
long long H, W;
long long sh, sw;
char s[22][22];
long long d[22][22];
void bfs() {
  queue<pair<long long, long long> > que;
  for (long long h = 1; h <= H; h++)
    for (long long w = 1; w <= W; w++) d[h][w] = (1LL << 60);
  que.push(pair<long long, long long>(sh, sw));
  d[sh][sw] = 0;
  while (que.size() > 0) {
    pair<long long, long long> p = que.front();
    que.pop();
    for (long long i = 0; i < 4; i++) {
      long long ny = p.first + dy[i], nx = p.second + dx[i];
      if (s[ny][nx] == '.' && d[ny][nx] == (1LL << 60)) {
        que.push(pair<long long, long long>(ny, nx));
        d[ny][nx] = d[p.first][p.second] + 1;
      }
    }
  }
}
signed main() {
  cin >> H >> W;
  for (long long h = 1; h <= H; h++)
    for (long long w = 1; w <= W; w++) cin >> s[h][w];
  long long ans = 0;
  sh = 1;
  sw = 1;
  for (sh = 1; sh <= H; sh++) {
    for (sw = 1; sw <= W; sw++) {
      if (s[sh][sw] == '.') {
        bfs();
        goto label;
      }
    }
  }
label:
  long long dist = -(1LL << 60);
  for (long long h = 1; h <= H; h++)
    for (long long w = 1; w <= W; w++) {
      if (d[h][w] != (1LL << 60) && d[h][w] > dist) {
        dist = d[h][w];
        sh = h;
        sw = w;
      }
    }
  bfs();
  for (long long h = 1; h <= H; h++)
    for (long long w = 1; w <= W; w++) {
      if (d[h][w] != (1LL << 60) && d[h][w] > dist) {
        dist = d[h][w];
        sh = h;
        sw = w;
      }
    }
  bfs();
  for (long long h = 1; h <= H; h++)
    for (long long w = 1; w <= W; w++) {
      if (d[h][w] != (1LL << 60) && d[h][w] > dist) {
        dist = d[h][w];
        sh = h;
        sw = w;
      }
    }
  bfs();
  for (long long h = 1; h <= H; h++)
    for (long long w = 1; w <= W; w++) {
      if (d[h][w] != (1LL << 60) && d[h][w] > dist) {
        dist = d[h][w];
        sh = h;
        sw = w;
      }
    }
  bfs();
  for (long long h = 1; h <= H; h++)
    for (long long w = 1; w <= W; w++) {
      if (d[h][w] != (1LL << 60) && d[h][w] >= dist) {
        dist = d[h][w];
        sh = h;
        sw = w;
      }
    }
  bfs();
  for (long long h = 1; h <= H; h++)
    for (long long w = 1; w <= W; w++) {
      if (d[h][w] != (1LL << 60) && d[h][w] >= dist) {
        dist = d[h][w];
        sh = h;
        sw = w;
      }
    }
  cout << dist << endl;
  return 0;
}
