#include <iostream>
#include <cstring>
#include <cmath>
#include <vector>
#include <algorithm>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <set>
#include <map>
#include <iterator>
#include <stack>
#include <string.h>
#include <cstdlib>
#include <queue>
#include <list>
#include <string>

using namespace std;

int H,W;
char f[51][51];
bool reach[51][51] = {0};
int vx[4] = {1,0,-1,0};
int vy[4] = {0,1,0,-1};
int white = 0;
int check = -1;

struct corr{
    int x;
    int y;
    int d;
};

queue<corr> Q;

int bfs()
{
    while (!(Q.empty())){
        corr now = Q.front();
        Q.pop();
        int nowx = now.x;
        int nowy = now.y;
        int nowd = now.d;
        
        if (nowx == H-1 && nowy == W-1){
            check = nowd;
            break;
        }
        else {
            for (int i = 0;i < 4;i++){
                corr next;
                next.x = nowx+vx[i];
                next.y = nowy+vy[i];
                next.d = nowd+1;
                if (0 <= next.x && next.x < H && 0 <= next.y && next.y < W && f[next.x][next.y] == '.' && reach[next.x][next.y] == 0){
                    reach[next.x][next.y] = 1;
                    Q.push(next);
                }
            }
        }
    }
    if (check == -1){
        return -1;
    }
    else {
        return check;
    }
}


int main()
{
    cin >> H >> W;
    for (int i = 0;i < H;i++){
        for (int j = 0;j < W;j++){
            cin >> f[i][j];
            if (f[i][j] == '.'){
                white++;
            }
        }
    }
    
    corr start = {0,0,0};
    Q.push(start);
    reach[0][0] = 1;
    
    if (bfs() == -1){
        cout << -1 << endl;
    }
    else {
        cout << white - 1 - bfs() << endl;
    }
}
 

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> P;
typedef pair<int,P> P1;
typedef pair<P,P> P2;
#define pu push
#define pb push_back
#define mp make_pair
#define eps 1e-7
#define INF 1000000000
#define mod 1000000007
#define fi first
#define sc second
#define rep(i,x) for(int i=0;i<x;i++)
#define repn(i,x) for(int i=1;i<=x;i++)
#define SORT(x) sort(x.begin(),x.end())
#define ERASE(x) x.erase(unique(x.begin(),x.end()),x.end())
#define POSL(x,v) (lower_bound(x.begin(),x.end(),v)-x.begin())
#define POSR(x,v) (upper_bound(x.begin(),x.end(),v)-x.begin())
int n,m;
vector<P>vec;
int p[200005],q[200005],c[200005];
vector<P>edge[600105];
int dist[600105];
bool used[600105];
int main(){
	scanf("%d%d",&n,&m);
	for(int i=0;i<m;i++){
		scanf("%d%d%d",&p[i],&q[i],&c[i]);
		vec.pb(mp(p[i],c[i]));
		vec.pb(mp(q[i],c[i]));
	}
	SORT(vec); ERASE(vec);
	for(int i=0;i<vec.size();i++){
		int v = vec[i].fi;
		int ty = vec[i].sc;
		edge[v+500050].pb(mp(i,1));
		edge[i].pb(mp(v+500050,1));
	}
	for(int i=0;i<m;i++){
		int A = POSL(vec,mp(p[i],c[i]));
		int B = POSL(vec,mp(q[i],c[i]));
		edge[A].pb(mp(B,0));
		edge[B].pb(mp(A,0));
	}
	fill(dist,dist+600105,INF);
	dist[500051] = 0;
	deque<int>deq;
	deq.pb(500051);
	while(deq.size()){
		int q = deq.front(); deq.pop_front();
		if(used[q]) continue;
		used[q] = 1;
		for(int i=0;i<edge[q].size();i++){
			if(used[edge[q][i].fi]) continue;
			if(dist[edge[q][i].fi] > dist[q]+edge[q][i].sc){
			    dist[edge[q][i].fi] = dist[q]+edge[q][i].sc;
    			if(edge[q][i].sc == 0){
    				deq.push_front(edge[q][i].fi);
    			}
    			else{
    				deq.push_back(edge[q][i].fi);
    			}
			}
		}
	}
	if(dist[500050+n] == INF) cout << -1 << endl;
	else cout << (2+dist[500050+n])/2-1 << endl;
}