#include <bits/stdc++.h>
using namespace std;
const long long INF = 1LL << 60;
long long gcd(long long a, long long b) {
  if (b == 0) return a;
  return gcd(b, a % b);
}
template <class T>
inline bool chmin(T& a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
template <class T>
inline bool chmax(T& a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
long long modpow(long long a, long long n, long long mod) {
  long long res = 1;
  while (n > 0) {
    if (n & 1) res = res * a % mod;
    a = a * a % mod;
    n >>= 1;
  }
  return res;
}
int maze[40][40] = {0};
int d1[40][40];
int d2[40][40];
int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  int H, W;
  cin >> H >> W;
  string S;
  int start_i;
  int start_j;
  for (int i = 0; i < 40; i++) {
    for (int j = 0; j < 40; j++) {
      maze[i][j] = 0;
    }
  }
  for (int i = 1; i <= H; i++) {
    cin >> S;
    for (int j = 1; j <= W; j++) {
      if (S[j - 1] == '.') {
        maze[i][j] = 1;
        start_i = i;
        start_j = j;
      } else {
        maze[i][j] = 0;
      }
    }
  }
  for (int i = 0; i < 40; i++) {
    for (int j = 0; j < 40; j++) {
      d1[i][j] = -1;
      d2[i][j] = -1;
    }
  }
  d1[start_i][start_j] = 0;
  queue<pair<int, int>> q;
  q.push(make_pair(start_i, start_j));
  while (!q.empty()) {
    auto next = q.front();
    int ni = next.first;
    int nj = next.second;
    q.pop();
    if (maze[ni + 1][nj] == 1) {
      if (d1[ni + 1][nj] == -1) {
        d1[ni + 1][nj] = d1[ni][nj] + 1;
        q.push(make_pair(ni + 1, nj));
      }
    }
    if (maze[ni - 1][nj] == 1) {
      if (d1[ni - 1][nj] == -1) {
        d1[ni - 1][nj] = d1[ni][nj] + 1;
        q.push(make_pair(ni - 1, nj));
      }
    }
    if (maze[ni][nj + 1] == 1) {
      if (d1[ni][nj + 1] == -1) {
        d1[ni][nj + 1] = d1[ni][nj] + 1;
        q.push(make_pair(ni, nj + 1));
      }
    }
    if (maze[ni][nj - 1] == 1) {
      if (d1[ni][nj - 1] == -1) {
        d1[ni][nj - 1] = d1[ni][nj] + 1;
        q.push(make_pair(ni, nj - 1));
      }
    }
  }
  int starti2;
  int startj2;
  int dmax = -1;
  for (int i = 1; i <= H; i++) {
    for (int j = 1; j <= W; j++) {
      if (chmax(dmax, d1[i][j])) {
        starti2 = i;
        startj2 = j;
        break;
      }
    }
  }
  q.push(make_pair(starti2, startj2));
  d2[starti2][startj2] = 0;
  while (!q.empty()) {
    auto next = q.front();
    int ni = next.first;
    int nj = next.second;
    q.pop();
    if (maze[ni + 1][nj] == 1) {
      if (d2[ni + 1][nj] == -1) {
        d2[ni + 1][nj] = d2[ni][nj] + 1;
        q.push(make_pair(ni + 1, nj));
      }
    }
    if (maze[ni - 1][nj] == 1) {
      if (d2[ni - 1][nj] == -1) {
        d2[ni - 1][nj] = d2[ni][nj] + 1;
        q.push(make_pair(ni - 1, nj));
      }
    }
    if (maze[ni][nj + 1] == 1) {
      if (d2[ni][nj + 1] == -1) {
        d2[ni][nj + 1] = d2[ni][nj] + 1;
        q.push(make_pair(ni, nj + 1));
      }
    }
    if (maze[ni][nj - 1] == 1) {
      if (d2[ni][nj - 1] == -1) {
        d2[ni][nj - 1] = d2[ni][nj] + 1;
        q.push(make_pair(ni, nj - 1));
      }
    }
  }
  int ans = -1;
  for (int i = 1; i <= H; i++) {
    for (int j = 1; j <= W; j++) {
      chmax(ans, d2[i][j]);
    }
  }
  cout << ans << endl;
  return 0;
}
