#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1010, INF = 1000010;
char c[MAXN][MAXN];
int dx[] = {1, 0, -1, 0}, dy[] = {0, -1, 0, 1};
int dist[MAXN][MAXN][4];
struct node {
  int x, y, d;
  node(int _x = 0, int _y = 0, int _d = 0) : x(_x), y(_y), d(_d) {}
  int operator<(const node &a) const { return x < a.x; }
};
inline int valid(node &v, int n, int m) {
  return v.x >= 0 && v.x < n && v.y >= 0 && v.y < m;
}
vector<node> buc[1000100];
int main(void) {
  int n, m;
  scanf("%d%d", &n, &m);
  for (int i = 0; i < (n); ++i) scanf("%s", c[i]);
  for (int i = 0; i < (n); ++i) {
    for (int j = 0; j < (m); ++j) {
      for (int k = 0; k < (4); ++k) dist[i][j][k] = INF;
    }
  }
  dist[n - 1][m - 1][1] = 0;
  buc[0].push_back(node(n - 1, m - 1, 1));
  int B = 0;
  while (B < INF) {
    if (buc[B].empty()) {
      ++B;
      continue;
    }
    node v = buc[B].back();
    int cost = B;
    buc[B].pop_back();
    if (cost > dist[v.x][v.y][v.d]) continue;
    node w(v.x + dx[v.d], v.y + dy[v.d], v.d);
    if (valid(w, n, m) && dist[w.x][w.y][w.d] > cost) {
      dist[w.x][w.y][w.d] = cost;
      buc[cost].push_back(w);
    }
    if (c[v.x][v.y] == '#') {
      for (int i = 0; i < (4); ++i) {
        node w(v.x, v.y, i);
        if (dist[w.x][w.y][w.d] > cost + 1) {
          dist[w.x][w.y][w.d] = cost + 1;
          buc[cost + 1].push_back(w);
        }
      }
    }
  }
  printf("%d\n", dist[0][0][1] < INF ? dist[0][0][1] : -1);
  return 0;
}
