#include <bits/stdc++.h>
using namespace std;

#define REP(i,s,t) for(int i=s;i<=t;i++)
const int INF = 0x3f3f3f3f;
const int N = 1e6+5;
int n,m,cnt,tot;

int vis[N];

typedef pair<int,int>P;
map<P,int>mp;
int head[N];

struct Edge{ int to,val,nxt ;}e[N<<1];

struct Node{
	int loc,dist;
	bool operator < (const Node &tmp)const{
		return dist>tmp.dist;
	}
}node[N];

inline void init(){
	cnt=0;mp.clear();tot=n;
	memset(head,-1,sizeof(head));
}
inline void add(int u,int v,int w){
	e[++cnt]=(Edge){ v,w,head[u] };head[u]=cnt;
	e[++cnt]=(Edge){ u,w,head[v] };head[v]=cnt; 
}
inline int getNum(int u,int v){
	if(!mp[P(u,v)])return mp[P(u,v)]=++tot;
	return mp[P(u,v)];
}
inline void Dij(){
	priority_queue<Node>q;
	REP(i,1,tot+5){
		vis[i]=0,node[i].dist=INF,node[i].loc=i;
	}
	node[1].dist=0;
	q.push(node[1]);
	while(!q.empty()){
		int u=q.top().loc;q.pop();
		if(vis[u])continue;
		vis[u]=1;
		for(int i=head[u];~i;i=e[i].nxt){
			int v=e[i].to;
//			printf("u=%d,v=%d,e[i]=%d\n",u,v,e[i].val);
//			printf("node[%d].dist=%d\n",v,node[v].dist);
			if(node[v].dist>node[u].dist+e[i].val){
				node[v].dist=node[u].dist+e[i].val;
				q.push(node[v]);
			}
		}
	}
}
int main(){
	while(~scanf("%d%d",&n,&m)){
		init();
		REP(i,1,m){
			int u,v,c;scanf("%d%d%d",&u,&v,&c);
			int no1=getNum(u,c),no2=getNum(v,c);
//			printf("no1=%d,no2=%d\n",no1,no2);
			add(no1,no2,0);
			add(u,no1,1);
			add(v,no2,1);
		}
		Dij();
		if(node[n].dist==INF)puts("-1");
		else printf("%d\n",node[n].dist);
	}
}	