#include <algorithm>
#include <cassert>
#include <cmath>
#include <iostream>
#include <map>
#include <queue>
#include <stack>
#include <vector>

static const int IINF = 1 << 30;
static const long long LINF = 1LL << 60;
static const long long MOD = 1.0e+9 + 7;

template <typename T> std::vector<T> vectors(std::size_t n, T val) {
  return std::vector<T>(n, val);
}

template <typename T, typename... Args>
auto vectors(std::size_t n, Args... args) {
  return std::vector<decltype(vectors<T>(args...))>(n, vectors<T>(args...));
}

template <class T> inline bool chmin(T &a, const T &b) {
  return (a > b) ? a = b, true : false;
}

template <class T> inline bool chmax(T &a, const T &b) {
  return (a < b) ? a = b, true : false;
}

template <class T> inline void chadd(T &a, const T &b) {
  a += b, a %= MOD;
  // TODO minus case
}

template <class T>
std::ostream &operator<<(std::ostream &s, const std::vector<T> &v) {
  if (v.empty())
    return s;
  s << *v.begin();
  for (auto iter = v.begin() + 1; iter != v.end(); ++iter)
    if (std::is_fundamental<T>::value)
      s << " " << *iter;
    else
      s << std::endl << *iter;
  return s;
}

int main() {
  int H, W;
  std::cin >> H >> W;
  std::vector<std::vector<char>> S(H, std::vector<char>(W));
  for (int i = 0; i < H; ++i)
    for (int j = 0; j < W; ++j)
      std::cin >> S[i][j];
  // std::cout << S << std::endl;

  std::vector<std::vector<std::vector<std::vector<int>>>> dp;
  dp.resize(H);
  for (int i = 0; i < H; ++i) {
    dp[i].resize(W);
    for (int j = 0; j < W; ++j) {
      dp[i][j].resize(H);
      for (int h = 0; h < H; ++h) {
        dp[i][j][h].resize(W);
        for (int k = 0; k < W; ++k) {
          dp[i][j][h][k] = IINF / 2;
        }
      }
    }
  }

  const int dx[4] = {1, 0, -1, 0};
  const int dy[4] = {0, 1, 0, -1};

  // 初期値
  for (int i = 0; i < H; ++i) {
    for (int j = 0; j < W; ++j) {
      if (S[i][j] == '#')
        continue;
      dp[i][j][i][j] = 0;

      for (int dir = 0; dir < 4; ++dir) {
        int h = i + dx[dir];
        int k = j + dy[dir];
        if (h < 0 or H <= h or k < 0 or W <= k)
          continue;
        if (S[h][k] == '#')
          continue;
        dp[i][j][h][k] = 1;
      }
    }
  }

  // for (int i = 0; i < H; ++i) {
  //   for (int j = 0; j < W; ++j) {
  //     for (int h = 0; h < H; ++h) {
  //       for (int k = 0; k < W; ++k) {
  //         std::cout << i << " " << j << " " << h << " " << k
  //                   << ": " << dp[i][j][h][k] << std::endl;
  //       }
  //     }
  //   }
  // }
  // exit(1);

  for (int x = 0; x < H; ++x) {
    for (int y = 0; y < W; ++y) {
      for (int i = 0; i < H; ++i) {
        for (int j = 0; j < W; ++j) {
          for (int h = 0; h < H; ++h) {
            for (int k = 0; k < W; ++k) {
              // dp[i][j] = std::min(dp[i][j], dp[i][k] + dp[k][j]);
              dp[i][j][h][k] =
                  std::min(dp[i][j][h][k], dp[i][j][x][y] + dp[x][y][h][k]);
            }
          }
        }
      }
    }
  }


  // for (int i = 0; i < H; ++i) {
  //   for (int j = 0; j < W; ++j) {
  //     for (int h = 0; h < H; ++h) {
  //       for (int k = 0; k < W; ++k) {
  //         std::cout << i << " " << j << " " << h << " " << k
  //                   << ": " << dp[i][j][h][k] << std::endl;
  //       }
  //     }
  //   }
  // }
  // exit(1);


  int res = 0;
  for (int i = 0; i < H; ++i) {
    for (int j = 0; j < W; ++j) {
      for (int h = 0; h < H; ++h) {
        for (int k = 0; k < W; ++k) {
          if (dp[i][j][h][k] >= IINF / 3)
            continue;
          res = std::max(res, dp[i][j][h][k]);
        }
      }
    }
  }
  std::cout << res << std::endl;

  return 0;
}


Measured memory_bytes: 1152