#include <bits/stdc++.h>
using namespace std;
using ll = int64_t;
array<pair<int, int>, 4> dirs = {make_pair(0, -1), {-1, 0}, {1, 0}, {0, 1}};
void bfs(vector<string>& Sss) {}
struct pos_t {
  int x;
  int y;
  int cost;
};
void main_() {
  ll H, W;
  cin >> H >> W;
  vector<string> Sss;
  Sss.emplace_back(W + 2, '#');
  for (ll i = 0; i < H; ++i) {
    string s;
    cin >> s;
    Sss.push_back('#' + s + '#');
  }
  Sss.emplace_back(W + 2, '#');
  vector<vector<int>> cost(H + 2, vector<int>(W + 2, -1));
  queue<pos_t> que;
  que.push({1, 1, 0});
  Sss[1][1] = 'q';
  while (!que.empty()) {
    auto pos = que.front();
    que.pop();
    cost[pos.y][pos.x] = pos.cost;
    int next_count = 0;
    for (auto&& d : dirs) {
      int nx = pos.x + d.first;
      int ny = pos.y + d.second;
      if (Sss[ny][nx] == '.') {
        que.push({nx, ny, pos.cost + 1});
        Sss[ny][nx] = 'q';
      }
      if (Sss[ny][nx] == 'q') {
        next_count++;
      }
    }
    if (next_count == 0) {
      Sss[pos.y][pos.x] = 'x';
    } else {
      Sss[pos.y][pos.x] = '*';
    }
  }
  vector<int> dists;
  for (ll i = 1; i <= H; ++i) {
    for (ll j = 1; j <= W; ++j) {
      if (Sss[i][j] == 'x') {
        dists.push_back(cost[i][j]);
      }
    }
  }
  if (dists.size() == 1) {
    cout << dists[0] << endl;
  } else {
    nth_element(begin(dists), begin(dists) + 2, end(dists), greater<int>());
    cout << dists[0] + dists[1] << endl;
  }
}
int main() {
  cin.tie(nullptr);
  cout.tie(nullptr);
  ios_base::sync_with_stdio(false);
  main_();
  return 0;
}
