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: Time Limit Exceeded)

#include<iostream>
#include<string>
#include<algorithm>
#include<vector>
#include<queue>
#include<map>
#include<math.h>
#include<iomanip>
#include<set>
#include<numeric>
#include<cstring>
#include<cstdio>
#include<functional>
#include<bitset>
#include<limits.h>
#include<cassert>

#define ll long long
#define int long long


using namespace std;


ll INF = 1e17;


typedef pair<int, int>P;//firstは距離、secondは頂点番号
struct Ver { int dist; set<int>company; };//頂点に、始点からの距離と最後に使った会社を持たせる
struct edge { int to, cmp; };//辺には行き先の頂点と会社を持たせる
Ver d[100010];
int V;//頂点数
int M;//辺の本数
vector<edge>G[100010];//グラフ
//int d[MAX];//始点からの距離
void dijkstra(int s) {
	priority_queue<P, vector<P>, greater<P>>que;
	//全点への距離をINFで初期化
	for (int i = 0; i < V + 1; i++) {
		d[i].dist = INF;
	}
	//始点への距離は0
	d[s].dist = 0;
	//始点をキューに入れる
	que.push(P(0, s));
	while (!que.empty()) {
		P p = que.top(); que.pop();
		int v = p.second;//今見ている頂点
		if (d[v].dist < p.first)continue;

		//今見ている頂点につながるすべての辺について距離を更新する
		for (int i = 0; i < G[v].size(); i++) {
			edge e = G[v][i];
			int cost = 1;
			//vに訪れるのに最後に使った会社(複数の場合もある)が今見ている辺の会社と同じならコストを0にする
			if (d[v].company.find(e.cmp) != d[v].company.end())cost = 0;
			//今見ている辺を使うことでe.toへの距離が小さくなるなら、距離を更新し、最後に使った会社をe.cmpとする
			if (d[e.to].dist > d[v].dist + cost) {
				set<int>st; st.insert(e.cmp);
				d[e.to] = { d[v].dist + cost, {e.cmp} };
				que.push(P(d[e.to].dist, e.to));
			}
			//今見ている辺を使っても距離が変わらない場合、最後に使った会社に(もしe.cmpがなかったら)e.cmpを追加する
			else if (d[e.to].dist == d[v].dist + cost) {
				if (d[e.to].company.find(e.cmp) == d[e.to].company.end()) {
					d[e.to].company.insert(e.cmp);
					que.push(P(d[e.to].dist, e.to));
				}

			}
		}
	}
}

signed main() {
	cin >> V >> M;
	for (int i = 0; i < M; i++) {
		int p, q, c; cin >> p >> q >> c;
		G[p].push_back({ q,c });
		G[q].push_back({ p,c });
	}
	dijkstra(1);
	//cout << "dijkstra" << endl;
	ll ans = d[V].dist;
	if (ans == INF) {
		cout << -1 << endl; return 0;
	}
	cout << ans << endl;;
}