#include<bits/stdc++.h>
using namespace std;
#define rep(i,n) for (int i = 0; i < (n); ++i)
#define ALL(x) (x).begin(), (x).end()
typedef long long ll;
typedef pair<int, int> pii;
const int INF = 1e9;
const int MOD = 1000000007;
const double PI = acos(-1);
int dx[4] = {0,1,0,-1};
int dy[4] = {1,0,-1,0};

void solve() {
	int h, w;
	cin >> h >> w;
	vector<string> v(h);
	rep(i,h) cin >> v[i];
	vector<vector<int>> d(h, vector<int>(w, INF));
	queue<pii> q;
	auto update = [&](int y, int x, int nd) {
		if (d[y][x] != INF) return;
		d[y][x] = nd;
		q.push(pii(y, x));
	};

	update(0, 0, 1);
	while (!q.empty()) {
		auto p = q.front(); q.pop();
		rep(i,4) {
			int ny = p.first + dy[i];
			int nx = p.second + dx[i];
			if (nx < 0 || nx >= w || ny < 0 || ny >= h) continue;
			if (v[ny][nx] == '#') continue;
			update(ny, nx, d[p.first][p.second] + 1);
		}
	}
	if (d[h-1][w-1] == INF) {
		cout << -1 << endl;
	} else {
		int cs = 0;
		rep(i,h) rep(j,w) if (v[i][j] == '#') cs++;
		// cout << h * w << " " << cs << " " << d[h-1][w-1] << endl;
		cout << h * w - (cs + d[h-1][w-1]) << endl;
	}
}

int main() {
	solve();
	return 0;
}
#include <algorithm>
#include <bitset>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <queue>
#include <unordered_map>
#include <unordered_set>
#include <vector>

#define rep(i, n) for (int i = 0; i < n; ++i)
#define debug(s, param) std::cerr << s << param << std::endl;

using namespace std;
using ll = long long;

const ll MOD = 1000000007;

int bfs(const vector<string>& grids, int h, int w) {
  vector<vector<int>> deltas{{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
  vector<vector<bool>> visit(h, vector<bool>(w, false));
  queue<pair<int, int>> q;
  auto isAvailable = [h, w](int row, int col) { return (row >= 0 && row < h && col >= 0 && col < w); };
  q.emplace(0, 0);
  visit[0][0] = true;
  int steps = 0;
  while (!q.empty()) {
    int size = (int)q.size();
    rep (i, size) {
      int row = q.front().first, col = q.front().second;
      if (row == h - 1 && col == w - 1) return steps;
      q.pop();
      for (const auto& delta : deltas) {
        int nextRow = row + delta[0], nextCol = col + delta[1];
        if (isAvailable(nextRow, nextCol) && grids[nextRow][nextCol] == '.' && !visit[nextRow][nextCol]) {
          visit[nextRow][nextCol] = true;
          q.emplace(nextRow, nextCol);
        }
      }
    }
    ++steps;
  }
  return -1;
}

int main() {
  int h, w;
  cin >> h >> w;
  int blackNums = 0;
  vector<string> grids(h, "");
  rep (i, h) {
    cin >> grids[i];
    rep (j, w) if (grids[i][j] == '#') ++blackNums;
  }
  int res = bfs(grids, h, w);
  if (res == -1) cout << -1 << endl;
  else  cout << h * w - (blackNums + res + 1) << endl;
  return 0;
}