#include <bits/stdc++.h>
using namespace std;
/*
  左上走到右下
  1、所在位置必须有色
     c=1黄色 c=0红色  
  2、同色移动不需金币
  3、不同色移动花1个
  4、花2个金币变色,魔法不能连用,变色走过恢复
  求最少需要多少金币 
*/
//方向数组 
int fx[4] = {-1,0,1,0};
int fy[4] = {0,-1,0,1};
//存储每个点的最优解 
int f[110][110];
//存储棋盘 
int mp[110][110];
int m,n,ans = INT_MAX;

//深搜
//sum:到x,y最少花多少金币 magic:到该点是否使用魔法 
void dfs(int x,int y,int sum,bool magic){
	//修剪掉3种无效的情况
	//越界 
	if(x < 1 || y < 1 || x > m || y > m) return; 
	if(mp[x][y] == 0) return; //无色区域
	if(sum >= f[x][y]) return;//不是最优解,比最优解大
	
	f[x][y] = sum;
	if(x == m && y == m){
		if(sum < ans) ans = sum;//更新最优解
		return; 
	} 
	
	//尝试4个方向
	for(int i = 0;i < 4;i++){
		int tx = x + fx[i];
		int ty = y + fy[i];
		//如果下一格有色
		if(mp[tx][ty] != 0){
			//同色计算 
			if(mp[tx][ty] == mp[x][y]) dfs(tx,ty,sum,false);
			else dfs(tx,ty,sum+1,false); 
		}else{
			//如果下一格无色
			//如果到本格没有使用魔法 
			if(magic == false){
				mp[tx][ty] = mp[x][y];//使用魔法变为同色
				dfs(tx,ty,sum+2,true);
				mp[tx][ty] = 0;//递归回来,魔法失效 
			} 
		} 
	} 
} 

int main(){
	int i,j,x,y,c;
	cin>>m>>n;
	for(i = 1;i <= m;i++){
		for(j = 1;j <= m;j++) f[i][j] = INT_MAX;
	}
	for(i = 1;i <= n;i++){
		cin>>x>>y>>c;
		//1红色 2黄色 0无色 
		mp[x][y] = c + 1;
	}
	dfs(1,1,0,false);
//	for(i = 1;i <= m;i++){
//		for(j = 1;j <= m;j++){
//			cout<<f[i][j]<<" "; 
//		}
//		cout<<endl;
//	}
	
	cout<<((ans == INT_MAX)?-1:ans)<<endl;	
}

/**************************************************************
	Problem: 1483
	User: admin
	Language: C++
	Result: Accepted
	Time:114 ms
	Memory:2168 kb
****************************************************************/