#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <limits>
#include <queue>
#include <iomanip>
#include <set>

template<typename T> bool chmax(T &a,T b){
    if(a<b){
        a=b;
        return true;
    }
    return false;
}

template<typename T> bool chmin(T &a,T b){
    if(a>b){
        a=b;
        return true;
    }
    return false;
}

using namespace std;
#define ALL(X) X.begin(),X.end()
using ll = long long int;
typedef vector<ll> vll;
typedef vector<vll> vvll;
typedef vector<vvll> vvvll;
const int MOD=1000000007;
//const int MOD=998244353;
const int INTMAX=1001001000;
const ll LLMAX=1010010010010010000;

template <typename T>class my_PQ{
public:
    vector<T> q;
    my_PQ(){}
    my_PQ(ll N){q.resize(N);}
    my_PQ(ll N,T a){q.resize(N);for(ll i=0;i<N;i++)q[i]=a;}
    size_t size(){return q.size();}
    typename vector<T>::iterator begin(){return q.begin();}
    typename vector<T>::iterator end(){return q.end();}
    void resize(ll N){q.resize(N);}
    T& operator[](ll n)&{return q[n];}
    const T& operator[](ll n)const&{return q[n];}
    void push_back(T&& x){q.push_back(x);}
    void clear(){q.clear();}
    void erase(ll i){q.erase(q.begin()+i);}
    ll insert(T x,bool (*comp)(T a,T b)){
        ll left = -1;
        ll right = (ll)q.size();
        while (right - left > 1) {
            ll mid = left + (right - left) / 2;
            if (!comp(q[mid],x)) right = mid;
            else left = mid;
        }
        q.insert(q.begin()+right,x);
        return right;
    }
};


ll GOAL[2];

bool comp(vll a,vll b){
    return abs(a[0]-GOAL[0])+abs(a[1]-GOAL[1])+a[2]<abs(b[0]-GOAL[0])+abs(b[1]-GOAL[1])+b[2];
}


int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    
    ll H,W;
    cin>>H>>W;
    ll count=0;
    vector<vector<bool>> s(H,vector<bool>(W));
    for(ll i=0;i<H;i++){
        for(ll j=0;j<W;j++){
            char c;
            cin>>c;
            if(c=='#')s[i][j]=true;
            else {
                s[i][j]=false;
                count++;
            }
        }
    }
    GOAL[0]=H-1;
    GOAL[1]=W-1;
    
    if(s[0][0]){
        cout<<-1<<endl;
        return 0;
    }
    
    my_PQ<vll> open;
    open.push_back(vll{0,0,1});
    vector<vector<bool>> done(H,vector<bool>(W,false));
    done[0][0]=true;
    
    while(open.size()>0){
        vll node=open[0];
        open.erase((ll)0);
        if(node[0]==GOAL[0] && node[1]==GOAL[1]){
            cout<<count-node[2]<<endl;
            return 0;
        }
        
        if(node[0]>0 && !done[node[0]-1][node[1]] && !s[node[0]-1][node[1]]){
            open.insert(vll{node[0]-1,node[1],node[2]+1},comp);
            done[node[0]-1][node[1]]=true;
        }
        if(node[0]<H-1 && !done[node[0]+1][node[1]] && !s[node[0]+1][node[1]]){
            open.insert(vll{node[0]+1,node[1],node[2]+1},comp);
            done[node[0]+1][node[1]]=true;
        }
        if(node[1]>0 && !done[node[0]][node[1]-1] && !s[node[0]][node[1]-1]){
            open.insert(vll{node[0],node[1]-1,node[2]+1},comp);
            done[node[0]][node[1]-1]=true;
        }
        if(node[1]<W-1 && !done[node[0]][node[1]+1] && !s[node[0]][node[1]+1]){
            open.insert(vll{node[0],node[1]+1,node[2]+1},comp);
            done[node[0]][node[1]+1]=true;
        }
    }
    cout<<-1<<endl;
    
    
    return 0;
}


Measured memory_bytes: 256