Problem:
Score : 600 points

Problem Statement

Snuke's town has a subway system, consisting of N stations and M railway lines. The stations are numbered 1 through N. Each line is operated by a company. Each company has an identification number.

The i-th ( 1 \leq i \leq M ) line connects station p_i and q_i bidirectionally. There is no intermediate station. This line is operated by company c_i.

You can change trains at a station where multiple lines are available.

The fare system used in this subway system is a bit strange. When a passenger only uses lines that are operated by the same company, the fare is 1 yen (the currency of Japan). Whenever a passenger changes to a line that is operated by a different company from the current line, the passenger is charged an additional fare of 1 yen. In a case where a passenger who changed from some company A's line to another company's line changes to company A's line again, the additional fare is incurred again.

Snuke is now at station 1 and wants to travel to station N by subway. Find the minimum required fare.

Constraints

2 \leq N \leq 10^5

0 \leq M \leq 2×10^5

1 \leq p_i \leq N (1 \leq i \leq M)

1 \leq q_i \leq N (1 \leq i \leq M)

1 \leq c_i \leq 10^6 (1 \leq i \leq M)

p_i \neq q_i (1 \leq i \leq M)

Input

The input is given from Standard Input in the following format:

N M
p_1 q_1 c_1
:
p_M q_M c_M

Output

Print the minimum required fare. If it is impossible to get to station N by subway, print -1 instead.

Sample Input 1

3 3
1 2 1
2 3 1
3 1 2

Sample Output 1

1

Use company 1's lines: 1 → 2 → 3. The fare is 1 yen.

Sample Input 2

8 11
1 3 1
1 4 2
2 3 1
2 5 1
3 4 3
3 6 3
3 7 3
4 8 4
5 6 1
6 7 5
7 8 5

Sample Output 2

2

First, use company 1's lines: 1 → 3 → 2 → 5 → 6. Then, use company 5's lines: 6 → 7 → 8. The fare is 2 yen.

Sample Input 3

2 0

Sample Output 3

-1

Solution in C++14 (GCC 5.4.1) (judge verdict: Accepted)

/*----------------by syr----------------*/
#include<algorithm>
#include<bitset>
#include<cctype>
#include<cstring>
#include<cstdlib>
#include<deque>
#include<fstream>
#include<functional>
#include<iomanip>
#include<iostream>
#include<iterator>
#include<limits>
#include<list>
#include<map>
#include<math.h>
#include<queue>
#include<set>
#include<stack>
#include<stdio.h>
#include<sstream>
#include<string>
#include<time.h>
#include<utility>
#include<vector>

using namespace std;

const int INF=1e9+7;

int n,m,c;
int dis[1000005],iter[100005];
int vis[100005];
vector<int> have[1000005],g[1000005];
vector<pair<int,int> > ve[100005];

int main(){
	scanf("%d%d",&n,&m);
	for(int i=0;i<m;i++){
		int u,v,w;
		scanf("%d%d%d",&u,&v,&w);
		ve[u].push_back(make_pair(w,v));
		ve[v].push_back(make_pair(w,u));
		have[w].push_back(u);
		have[w].push_back(v);
		c=max(c,w);
	}
	for(int i=1;i<=n;i++) sort(ve[i].begin(),ve[i].end());
	for(int i=1;i<=c;i++){
		if(!have[i].size()) continue;
		sort(have[i].begin(),have[i].end());
		have[i].erase(unique(have[i].begin(),have[i].end()),have[i].end());
	}
	int nn=n;
	memset(vis,0,sizeof(vis));
	for(int i=1;i<=c;i++){
		for(int j=0;j<have[i].size();j++){
			int s=have[i][j];
			if(vis[s]==c) continue;
			queue<int> q;
			vector<int> vec;
			q.push(s);
			vis[s]=i;
			while(!q.empty()){
				int u=q.front();q.pop();
				vec.push_back(u);
				for(int &k=iter[u];k<ve[u].size()&&ve[u][k].first==i;k++){
					int v=ve[u][k].second;
					if(vis[v]==i) continue;
					vis[v]=i;
					q.push(v);
				}
			}
			nn++;
//			printf("%d\n",i);
			for(int k=0;k<vec.size();k++){
//				printf("%d ",vec[k]);
				g[vec[k]].push_back(nn);
				g[nn].push_back(vec[k]);
			}
//			puts("");
		}
//		puts("OK");
	}
/*	for(int i=1;i<=nn;i++){
		for(int j=0;j<g[i].size();j++) printf("%d ",g[i][j]);
		puts("");
	}
*/	queue<int> q;
	memset(dis,-1,sizeof(dis));
	dis[1]=0;q.push(1);
	while(!q.empty()){
		int u=q.front();q.pop();
		for(int i=0;i<g[u].size();i++){
			int v=g[u][i];
			if(dis[v]!=-1) continue;
			dis[v]=dis[u]+1;
			q.push(v);
		}
	}
	if(dis[n]==-1) puts("-1");
	else printf("%d\n",dis[n]/2);
	return 0;
}