#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using vll = vector<ll>;
using vllvll = vector<vll>;
using pll = pair<ll, ll>;
template <class T>
void print1d(T x, ll n = -1) {
  if (n == -1) n = x.size();
  for (long long i = 0; i < n; ++i) {
    cout << x[i] << ' ';
  }
  cout << '\n';
}
template <class T>
void print2d(T x, ll r = -1, ll c = -1) {
  if (r == -1) r = x.size();
  if (c == -1) c = x[0].size();
  for (long long i = 0; i < r; ++i) print1d(x[i], c);
}
template <class T, class U>
bool haskey(T mp, U key) {
  return mp.find(key) != mp.end();
}
template <class T, class U>
bool isin(T el, U container) {
  return find((container).begin(), (container).end(), el) != container.end();
}
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 <class T>
ld deg2rad(T deg) {
  return M_PI * deg / 180.0;
}
template <class T>
ld rad2deg(T rad) {
  return 180.0 * rad / M_PI;
}
ll intpow(ll a, ll n) {
  ll p = 1;
  while (n) {
    if (n & 1) p *= a;
    a *= a;
    n >>= 1;
  }
  return p;
}
const long double pi = M_PI;
const long long big = 1LL << 50;
const long long inf = 1LL << 60;
const long long mod = 1e9 + 7;
class Grid {
 public:
  ll row, col, val;
  Grid() {}
  Grid(ll row, ll col, ll val) : row{row}, col{col}, val{val} {}
};
long long MAX = 1000;
vector<vector<Grid> > G(MAX, vector<Grid>(MAX));
ll H;
ll W;
vllvll dist;
ll FREE = 123456;
ll WALL = 123457;
void gridbfs(Grid start) {
  for (long long i = 0; i < H; ++i)
    for (long long j = 0; j < W; ++j) dist[i][j] = inf;
  dist[start.row][start.col] = 0;
  queue<Grid> q;
  q.push(start);
  while (!q.empty()) {
    Grid now = q.front();
    q.pop();
    ll y = now.row;
    ll x = now.col;
    if (0 <= y - 1 and y - 1 < H) {
      if (dist[y - 1][x] == inf and G[y - 1][x].val == FREE) {
        q.push(G[y - 1][x]);
        dist[y - 1][x] = dist[y][x] + 1;
      }
    }
    if (0 <= y + 1 and y + 1 < H) {
      if (dist[y + 1][x] == inf and G[y + 1][x].val == FREE) {
        q.push(G[y + 1][x]);
        dist[y + 1][x] = dist[y][x] + 1;
      }
    }
    if (0 <= x - 1 and x - 1 < W) {
      if (dist[y][x - 1] == inf and G[y][x - 1].val == FREE) {
        q.push(G[y][x - 1]);
        dist[y][x - 1] = dist[y][x] + 1;
      }
    }
    if (0 <= x + 1 and x + 1 < W) {
      if (dist[y][x + 1] == inf and G[y][x + 1].val == FREE) {
        q.push(G[y][x + 1]);
        dist[y][x + 1] = dist[y][x] + 1;
      }
    }
  }
}
int main() {
  cin >> H >> W;
  dist.resize(H, vll(W));
  char tmp;
  pair<ll, ll> st;
  for (long long i = 0; i < H; ++i) {
    for (long long j = 0; j < W; ++j) {
      cin >> tmp;
      if (tmp == '.') G[i][j] = Grid(i, j, FREE);
      if (tmp == '#') G[i][j] = Grid(i, j, WALL);
    }
  }
  ll mx = -1;
  for (long long i = 0; i < H; ++i) {
    for (long long j = 0; j < W; ++j) {
      gridbfs(Grid(i, j, FREE));
      for (long long i = 0; i < H; ++i) {
        for (long long j = 0; j < W; ++j) {
          if (dist[i][j] > 1000) {
            dist[i][j] = -1000;
          }
        }
      }
      for (long long i = 0; i < H; ++i) {
        for (long long j = 0; j < W; ++j) {
          chmax(mx, dist[i][j]);
        }
      }
    }
  }
  cout << mx << endl;
}
