// C++ 14
#include <iostream>
#include <string>
#include <vector>
#include <list>
#include <algorithm>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <unordered_map>
#include <math.h>
#include <sstream>
#include <unistd.h>

#define ll long long
#define Int int
#define loop(x, start, end) for(Int x = start; x < end; x++)
#define loopdown(x, start, end) for(int x = start; x > end; x--)
#define rep(n) for(int x = 0; x < n; x++)
#define span(a,x,y) a.begin()+x,a.begin()+y
#define span_all(a) a.begin(),a.end()
#define len(x) (x.size())
#define last(x) (*(x.end()-1))

using namespace std;

#define EPS 0.0000000001
#define MOD 1000000007

class Vector2 {
public:
  double x, y;
  
  Vector2(double x = 0, double y = 0): x(x), y(y) {}
  
  Vector2 operator + (Vector2 v) { return Vector2(x + v.x, y + v.y); }
  Vector2 operator - (Vector2 v) { return Vector2(x - v.x, y - v.y); }
  Vector2 operator * (double k) { return Vector2(x * k, y * k); }
  Vector2 operator / (double k) { return Vector2(x / k, y / k); }
  
  double length() { return sqrt(norm()); }
  double norm() { return x * x + y * y; }
  double dot (Vector2 v) { return x * v.x + y * v.y; }
  double cross (Vector2 v) { return x * v.y - y * v.x; }
  
  bool operator < (const Vector2 &v) const {
    return x != v.x ? x < v.x : y < v.y;
  }
  
  bool operator == (const Vector2 &v) const {
    return fabs(x - v.x) < EPS && fabs(y - v.y) < EPS;
  }
};

ostream & operator << (ostream & out, Vector2 const & v) { 
  out<< "Vector2(" << v.x << ", " << v.y << ')';
  return out;
}

istream & operator >> (istream & in, Vector2 & v) { 
  double x, y;
  in >> x;
  in >> y;
  v.x = x;
  v.y = y;
  return in;
}

#define MAX_H 50
#define INFTY (MAX_H*MAX_H)

Int H, W, N, sx, sy, gx, gy;
char c_;
vector<bool> M(MAX_H * MAX_H, true);
vector<bool> done(MAX_H * MAX_H, false);

void input() {
  cin >> H >> W;
  gx = W -1, gy = H - 1;
  sx = sy = 0;
  loop(h,0,H) {
    loop(w,0,W) {
      cin >> c_;
      if (c_ == '#') M[h*W+w] = false;
    }
  }
  M.resize(H * W);
  done.resize(H * W);
}

vector<Vector2> bfs(Int sx, Int sy) {
  queue<vector<Vector2> > Q;
  vector<Vector2> path;
  path.push_back(Vector2(sx, sy));
  Q.push(path);
  done[sy*W+sx] = true;

  while (Q.size()) {
    vector<Vector2> us = Q.front(); Q.pop();
    Vector2 u = last(us);
    loop(dx,-1,2) {
      loop(dy,-1,2) {
        if (dx != 0 && dy != 0) continue;
        Vector2 next = u + Vector2(dx, dy);
        if (next.x < 0 || next.x >= W || next.y < 0 || next.y >= H) continue;
        if (!M.at(next.y*W+next.x)) continue;
        if (done.at(next.y*W+next.x)) continue;
        vector<Vector2> copy = us;
        copy.push_back(next);
        done[next.y*W+next.x] = true;
        if (next.x == gx && next.y == gy) {
          return copy;
        }
        Q.push(copy);
      }
    }
  }

  vector<Vector2> empty;
  return empty;
}

void solve() {
  vector<Vector2> path = bfs(sx, sy);
  if (!path.size()) {
    cout << -1 << endl;
    return;
  }

  for (auto v: path) {
    M[v.y*W+v.x] = false;
  }

  Int counter = 0;
  loop(h,0,H) {
    loop(w,0,W) {
      if (M[h*W+w]) counter++;
    }
  }

  cout << counter << endl;
}

int main(void) {
  input();
  solve();
  return 0;
}


Measured memory_bytes: 256