//インクルード(アルファベット順)
#include<algorithm>//sort,二分探索,など
#include<bitset>//固定長bit集合
#include<chrono>//実行時間計測
#include<cmath>//pow,logなど
#include<complex>//複素数
#include<deque>//両端アクセスのキュー
#include<functional>//sortのgreater
#include<iomanip>//setprecision(浮動小数点の出力の誤差)
#include<iostream>//入出力
#include<iterator>//集合演算(積集合,和集合,差集合など)
#include<map>//map(辞書)
#include<numeric>//iota(整数列の生成),gcdとlcm,accumulate
#include<queue>//キュー
#include<set>//集合
#include<stack>//スタック
#include<string>//文字列
#include<unordered_map>//順序保持しないmap
#include<unordered_set>//順序保持しないset
#include<utility>//pair
#include<vector>//可変長配列

using namespace std;
typedef long long ll;

//マクロ
//forループ
//引数は、(ループ内変数,動く範囲)か(ループ内変数,始めの数,終わりの数)、のどちらか
//Dがついてないものはループ変数は1ずつインクリメントされ、Dがついてるものはループ変数は1ずつデクリメントされる
#define REP(i,n) for(ll i=0;i<ll(n);i++)
#define REPD(i,n) for(ll i=n-1;i>=0;i--)
#define FOR(i,a,b) for(ll i=a;i<=ll(b);i++)
#define FORD(i,a,b) for(ll i=a;i>=ll(b);i--)
//xにはvectorなどのコンテナ
#define ALL(x) x.begin(),x.end() 
#define SIZE(x) ll(x.size()) 
//定数
#define INF 1000000000000 //10^12:∞
#define MOD 1000000007 //10^9+7:合同式の法
#define MAXR 100000 //10^5:配列の最大のrange
//略記
#define PB push_back //挿入
#define MP make_pair //pairのコンストラクタ
#define F first //pairの一つ目の要素
#define S second //pairの二つ目の要素

#define int long long

template<typename A, size_t N, typename T>

void Fill(A (&array)[N], const T &val){
    std::fill( (T*)array, (T*)(array+N), val );
}


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//ここにグローバル変数宣言
int H,W;
queue<pair<int,int> > q;

pair<int,int> p;
string maze[55]; //maze[X][Y]

int dist[55][55];

int sx=0,sy=0;
int x=sx,y=sy;
int vx[4]={0,1,0,-1};
int vy[4]={1,0,-1,0};

int d;
int gx,gy;
bool ok=true;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//ここに関数宣言

void bfs(){

	//初期位置
	p.first=0;
	p.second=0;
	q.push(p);

	dist[0][0]=1;

	




	while(!q.empty()){

		//現在地の座標をキューから取得して設定
		x=q.front().first;
		y=q.front().second;
		q.pop();
		for (int i = 0; i < 4; ++i)
		{
			//現在地から進む予定の座標
			int nx=x+vx[i];
			int ny=y+vy[i];

			if(nx>=0 && ny>=0 && nx<W && ny<H && maze[ny][nx]=='.' && dist[ny][nx]==-1)//そこが壁じゃなければ
			{
				dist[ny][nx]=dist[y][x]+1;
				p.first=nx;
				p.second=ny;
				q.push(p);
				
			}
			if (nx==gx && ny==gy)//４方のうちそこがゴールならば
			{
				d=dist[ny][nx]+1;
				return ;
			}
		}
	}
	ok=false;

}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
signed main(){
    //入力の高速化用のコード
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

cin>>H>>W;

int black=0,white=0;  //black='#' で、　white='.'

REP(i,H){
	cin >> maze[i];
}

REP(i,H)REP(j,W){ //初期状態の色のカウント
	if(maze[i][j]=='#'){black++;}
	if(maze[i][j]=='.'){white++;}
}


Fill(dist,-1);


 gx=W-1;
 gy=H-1;



bfs();


//int ans=dist[gx][gy];
if (!ok)
{
	cout<<-1<<endl;return 0;
}

cout<<white-d +1<<endl;

}

Measured memory_bytes: 3668