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: Wrong Answer)

#include <iostream>
#include <algorithm>
#include <math.h>
#include <string.h>
#include <cstdio>
#include <vector>
#include <set>
#include <cassert>
#include <cstdlib>
#include <complex>
#include <cctype>
#include <cmath>
#include <ctime>
#include <deque>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <sstream>
#include <functional>
#include <iomanip>
//#include <windows.h>  //Should be deleted when using AtCoder&POJ
using namespace std;

#define ll long long
#define pii pair<int,int>
/**==Info==
*Program:2
*Problem:すぬけ君の地下鉄旅行 / Snuke's Subway Trip
*Date:2018-7-14
*Algorithm:Dsu
*Stats:Unknown*/

bool debug=false;

const int A=2e5+2;
const int B=2e6+2;

int n,m;
int dsu[B];
vector<pii> q[B];
int id[B];
bool use[B];

int stpos;

vector<int> nei[B];

int dis[200005];

int getFa(int num){
	if(dsu[num]==num){
		return num;
	}
	return dsu[num]=getFa(dsu[num]);
}

void Unite(int a,int b){
	if(getFa(a)==getFa(b)){
		return;
	}
	dsu[getFa(a)]=getFa(b);
}

void initize(int a){
	dsu[a]=a;
}


void Add(int p){
	if(use[p]){
		return;
	}
	
	use[p]=true;
	int r=getFa(p);
	if(id[r]==-1){
		id[r]=stpos;
		stpos++;
	}
	
	nei[p].push_back(id[r]);
	nei[id[r]].push_back(p);
}

int main(int argc,char* argv[]){
	scanf("%d%d",&n,&m);
	
	for(int i=0;i<m;i++){
		int a,b,c;
		scanf("%d%d%d",&a,&b,&c);
		a--;b--;c--;
		
		q[c].push_back(make_pair(a,b));
	}
	
	stpos=n;
	
	for(int i=0;i<1000000;i++){
		if(q[i].empty()){
			continue;
		}
		
		//Init
		for(int j=0;j<q[i].size();j++){
			initize(q[i][j].first);
			initize(q[i][j].second);
			id[q[i][j].first]=-1;
			id[q[i][j].second]=-1;
			use[q[i][j].first]=false;
			use[q[i][j].second]=false;
		}
		
		//Unite
		for(int j=0;j<q[i].size();j++){
			Unite(q[i][j].first,q[i][j].second);
		}
		
		//Check
		for(int j=0;j<q[i].size();j++){
			Add(q[i][j].first);
			Add(q[i][j].second);
		}
		
		
	}
	
	//Solve
	queue<int> q;
	
	fill(dis,dis+2*n,-2);
	dis[0]=0;
	q.push(0);
	while(!q.empty()){
		int last=q.front();
		q.pop();
		
		for(int i=0;i<nei[last].size();i++){
			if(dis[nei[last][i]]==-2){
				dis[nei[last][i]]=dis[last]+1;
				q.push(nei[last][i]);
			}
		}
	}
	
	cout<<dis[n-1]/2;
	return 0;
}