#include <bits/stdc++.h>

#define all(x) (x).begin(),(x).end()
#define init() \
  ios::sync_with_stdio(false); \
  cin.tie(0)

using namespace std;

using ll = long long;
using ull = unsigned long long;

template<typename M, typename N>
constexpr common_type_t<M, N> gcd(M a, N b) {
  return a == 0 ? b
    : b == 0 ? a
    : gcd(b, a % b);
}

template <typename M, typename N>
constexpr common_type_t<M, N> lcm(M a, N b) {
  return a * b / gcd(a, b);
}
  
int h,w;

int search(vector<string> m, int sx, int sy)
{
  queue<tuple<int, int, int>> next;

  next.push({sx, sy, 0});

  int res = 0;
  while (!next.empty()) {
    int x = get<0>(next.front());
    int y = get<1>(next.front());
    int d = get<2>(next.front());
    next.pop();

    if (x < 0 || x >= w || y < 0 || y >= h) {
      continue;
    }

    if (m[y][x] == '.') {
      m[y][x] = '#';
      next.push({x + 1, y, d + 1});
      next.push({x - 1, y, d + 1});
      next.push({x, y + 1, d + 1});
      next.push({x, y - 1, d + 1});
      res = max(res, d);
    } else {
      continue;
    }
  }

  return res;
}

int main() {
  init();

  cin >> h >> w;

  vector<string> m(h);
  for (int i = 0; i < h; i++)
  {
    string s;
    cin >> s;
    m[i] = s;
  }
  
  int mx = 0;
  for (int y = 0; y < h; y++)
  {
    for (int x = 0; x < h; x++)
    {
      mx = max(search(m, x, y), mx);
    }
  }

  cout << mx << '\n';

  return 0;
}
