#include <bits/stdc++.h>
void read_from_cin() {}
template <typename T, typename... Ts>
void read_from_cin(T& value, Ts&... args) {
  std::cin >> value;
  read_from_cin(args...);
}
template <typename T>
void write_to_cout(const T& value) {
  std::cout << value << std::endl;
}
template <typename T, typename... Ts>
void write_to_cout(const T& value, const Ts&... args) {
  std::cout << value << ' ';
  write_to_cout(args...);
}
using ll = long long;
using namespace std;
template <typename T>
class Grid {
  template <typename U>
  using pqueue = std::priority_queue<U, std::vector<U>, std::greater<U>>;

 public:
  Grid(int height, int width) : grid_(height, std::vector<T>(width)) {}
  void Set(int row, int col, T value) { grid_[row][col] = value; }
  T Distance(int src_row, int src_col) {
    if (grid_[src_row][src_col] < 0) {
      return -1;
    }
    pqueue<std::tuple<T, int, int>> que;
    que.push({0, src_row, src_col});
    std::map<std::pair<int, int>, T> visited;
    visited[{src_row, src_col}] = 0;
    T ret = 0;
    while (!que.empty()) {
      T dist;
      int row, col;
      std::tie(dist, row, col) = que.top();
      que.pop();
      ret = max(ret, dist);
      int dr[] = {1, -1, 0, 0};
      int dc[] = {0, 0, 1, -1};
      for (int i = 0; i < 4; ++i) {
        int nrow = row + dr[i];
        int ncol = col + dc[i];
        if (nrow < 0 || grid_.size() <= nrow || ncol < 0 ||
            grid_[0].size() <= ncol || grid_[nrow][ncol] < 0) {
          continue;
        }
        int ndist = dist + grid_[nrow][ncol];
        const auto it = visited.find({nrow, ncol});
        if (it != visited.end() && it->second <= ndist) {
          continue;
        }
        visited[{nrow, ncol}] = ndist;
        que.push(make_tuple(ndist, nrow, ncol));
      }
    }
    return ret;
  }

 private:
  std::vector<std::vector<T>> grid_;
};
int main() {
  int H, W;
  read_from_cin(H, W);
  ;
  vector<string> m(H);
  for (int i = 0; i < (int)(H); ++i) cin >> m[i];
  int ans = 0;
  for (int sr = 0; sr < (int)(H); ++sr)
    for (int sc = 0; sc < (int)(W); ++sc) {
      Grid<int> grid(H, W);
      for (int r = 0; r < (int)(H); ++r)
        for (int c = 0; c < (int)(W); ++c)
          grid.Set(r, c, m[r][c] == '.' ? 1 : -1);
      ans = max(ans, grid.Distance(sr, sc));
    }
  write_to_cout(ans);
  ;
}
