#include <bits/stdc++.h>
int makeXY(int x, int y) { return y * 100 + x; };
void check(int H, int W, const char maze[22][22], int maze2[22][22],
           int& startX, int& startY, int* mazeP) {
  std::list<int> open;
  bool search = startX < 0;
  int sX = 0;
  int sY = 0;
  for (int i = 0; i <= H + 1; ++i) {
    for (int j = 0; j <= W + 1; ++j) {
      if (maze[i][j] == '#') {
        maze2[i][j] = 200000000;
      } else {
        sX = j;
        sY = i;
        maze2[i][j] = 100000000;
      }
    }
  }
  if (search == false) {
    sX = startX;
    sY = startY;
  }
  maze2[sY][sX] = 0;
  open.push_back(makeXY(sX, sY));
  auto update = [&maze2](int x, int y, int length) {
    if (maze2[y][x] == 200000000) {
    } else if (maze2[y][x] > length) {
      maze2[y][x] = length;
      return true;
    }
    return false;
  };
  while (open.size() > 0) {
    std::list<int> nextOpen;
    for (auto it : open) {
      int x = it % 100;
      int y = it / 100;
      int length = maze2[y][x] + 1;
      if (update(x, y - 1, length)) nextOpen.push_back(makeXY(x, y - 1));
      if (update(x, y + 1, length)) nextOpen.push_back(makeXY(x, y + 1));
      if (update(x - 1, y, length)) nextOpen.push_back(makeXY(x - 1, y));
      if (update(x + 1, y, length)) nextOpen.push_back(makeXY(x + 1, y));
    }
    open = std::move(nextOpen);
  }
  memcpy(maze2, mazeP, sizeof(int) * 22 * 22);
}
int main() {
  int H, W;
  scanf("%d %d", &H, &W);
  char maze[22][22] = {0};
  memset(maze, '#', 22);
  memset(maze[H + 1], '#', 22);
  for (int i = 0; i < H; ++i) {
    maze[i + 1][0] = '#';
    scanf("%s", &maze[i + 1][1]);
    maze[i + 1][W + 1] = '#';
  }
  int sX = -1;
  int sY = -1;
  int maze2[22][22] = {0};
  check(H, W, maze, maze2, sX, sY, &maze2[0][0]);
  int maxPos = 0;
  int maxLenght = 0;
  for (int i = 1; i <= H; ++i) {
    for (int j = 1; j <= W; ++j) {
      if (maze2[i][j] == 200000000) {
        continue;
      }
      if (maxLenght < maze2[i][j]) {
        maxLenght = maze2[i][j];
        maxPos = makeXY(j, i);
      }
    }
  }
  int maze3[22][22] = {0};
  int nX = maxPos % 100;
  int nY = maxPos / 100;
  check(H, W, maze, maze3, nX, nY, &maze3[0][0]);
  maxPos = 0;
  maxLenght = 0;
  for (int i = 1; i <= H; ++i) {
    for (int j = 1; j <= W; ++j) {
      if (maze3[i][j] == 200000000) {
        continue;
      }
      if (maxLenght < maze3[i][j]) {
        maxLenght = maze3[i][j];
        maxPos = makeXY(j, i);
      }
    }
  }
  printf("%d", maxLenght);
}
