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)

#define _CRT_SECURE_NO_DEPRECATE

#pragma warning(disable:4996)
//#pragma comment(linker, "/STACK:512000000")

//190647WR

#include <algorithm>
#include <bitset>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <ctime>
#include <cstdlib>
#include <deque>
#include <fstream>
#include <functional>
#include <iterator>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <vector>
#include <set>
#include <string>

#define ISO11
#define myDEBUG

#ifdef ISO11
#include <unordered_map>
#include <unordered_set>
#endif

#ifdef myDEBUG

#define assert(x) \
	if(!x){\
		cerr<<"\n\nERROR!\tFailed: "<<x;\
		cerr<<"\nLine: "<<__LINE__;\
		cerr<<"\nFile: "<<__FILE__;\
		cerr<<"\nTime: "<<__TIME__;\
		cerr<<"\nDate: "<<__DATE__;\
	}\

#define err(x) assert(x)
#define warn(x) assert(x)

#endif

#define F first
#define S second
#define read(x) scanf("%d", &x);
#define readln(x) scanf("%d\n", &x);
#define write(x) printf("%d ", x);
#define writeln(x) printf("%d\n", x);
#define MEM(x, y) memset(x, y, sizeof(x));
#define forn(i, n) for(int i = 0; i < n; ++i)
#define mp make_pair
#define pb push_back
#define is insert
#define runtime clock() * 1.0 / CLOCKS_PER_SEC
#define pii pair<int, int>

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
const ll INF = (1ll << 63) - 1ll;
const ld INFd = 28e14;
const ll inf = (1 << 31) - 1;
const ld EPS = 1e-8;

const ld PI = acos(-1.0);

using namespace std;

//#include <chrono>
//using namespace std::chrono;
//cerr << "Nanosec:" << duration_cast<nanoseconds>(end_time - start_time).count() << endl;
//time_point<steady_clock> start_time, end_time;
//start_time = high_resolution_clock::now();
//end_time = high_resolution_clock::now();

void OUT(bool f) { if (f) cout << "YES" << endl; else cout << "NO" << endl; }
void Out(bool f) { if (f) cout << "Yes" << endl; else cout << "No" << endl; }
void out(bool f) { if (f) cout << "yes" << endl; else cout << "no" << endl; }

inline int next_rand() { return abs(rand() * rand() + rand()); }

#ifdef GEOM
typedef double T;
const T eps = 1e-8;
bool equal(T a, T b) { return fabs(a - b) < eps; }
T sqr(T arg) { return arg * arg; }
struct PV {
	T x, y;
	PV() { x = y = 0; }
	PV(T x, T y) :x(x), y(y) { ; }
	PV(const PV& a, const PV& b) :x(a.x - b.x), y(a.y - b.y) { ; }
	PV turn_conrt_clock() { PV ans; ans.x = -y; ans.y = x; return ans; }
	PV turn_on_clock() { PV ans; ans.x = y; ans.y = -x; return ans; }
	PV setlen(T s = 1) { PV ans; ans.x = x; ans.y = y; s /= sqrt(x * x + y * y); ans.x *= s; ans.y *= s; return ans; }
	T len() { return sqrt(sqr(x) + sqr(y)); }
};

PV operator+ (PV lhs, const PV& rhs) { lhs.x += rhs.x; lhs.y += rhs.y; return lhs; }
PV operator- (PV lhs, const PV& rhs) { lhs.x -= rhs.x; lhs.y -= rhs.y; return lhs; }
T operator% (const PV& lhs, const PV& rhs) { return lhs.x * rhs.x + lhs.y * rhs.y; }
T operator* (const PV& lhs, const PV& rhs) { return lhs.x * rhs.y - lhs.y * rhs.x; }
T Po(const PV& lhs, const PV& rhs) { return sqrt(sqr(lhs.x - rhs.x) + sqr(lhs.y - rhs.y)); }
struct Line {
	T a, b, c;
	Line() { a = b = c = 0; }
	void set(PV A, PV B, bool iCV = true) {
		if (iCV)
			b = b + a;
		a = A.y - B.y;
		b = -(A.x - B.x);
		c = -B.x * a + B.y * -b;
	}
	Line(PV A, PV B, bool iCV = true) { set(A, B, iCV); }
	void multC(T s = 1) { a *= s; b *= s; c *= s; }
};
bool state_ = true;
PV operator*(Line lhs, Line rhs) {
	state_ = true;
	if (equal(lhs.a / rhs.a, lhs.b / rhs.b)) {
		state_ = false;
		return PV(0, 0);
	}
	T e = lhs.a * rhs.a;
}
#endif

struct __debug__ {
	__debug__(string filename, bool f = false) {
#ifdef _DEBUG
		freopen("input.txt", "r", stdin);
		freopen("output.txt", "w", stdout);
#endif		
		if (filename == "") return;
		ios_base::sync_with_stdio(0);
		cin.tie(0);
		cout.tie(0);
		string filein = filename + ".in";
		string fileout = filename + ".out";
		freopen(filein.c_str(), "r", stdin);
		freopen(fileout.c_str(), "w", stdout);
#ifdef _DEBUG
		freopen("input.txt", "r", stdin);
		freopen("output.txt", "w", stdout);
#endif
	}
	~__debug__() {
#ifdef _DEBUG
		freopen("CON", "r", stdin);
		freopen("CON", "w", stdout);
		cerr << "\n\nTIME: \t" << runtime << endl;
		system("pause");
#endif
	}
};

__debug__ DEBUG("");

//#define STRESS
void gen();
void solve();


//#define GEOM


int main() {
	srand('M' + 'A' + 'S' + 'L' + '0' + 'F');
	srand(time(0));
#ifdef STRESS
	gen();
#endif
	/// zahijoja
	/// aawnrjn6
	/// fml31-p08
	/// shop-3
	/// yedetayiro
	/// afesivuda
	/// ivisuzedu
	/// ugesetacuz
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	solve();
}

const int maxn = 100500;	
int n, m;
int d[maxn];
set<int> pred[maxn];
vector<pii> e[maxn];
deque<int> q;
void solve() {
	cin >> n >> m;
	forn(i, m) {
		int a, b, c;
		cin >> a >> b >> c;
		--a; --b;
		e[a].pb(mp(b, c));
		e[b].pb(mp(a, c));
	}
	pred[0].is(-1);
	d[0] = 1;
	q.push_back(0);
	while (!q.empty()) {
		int b = q.front();
		q.pop_front();
		for (auto i : e[b]) {
			if(d[i.first] == 0)
				if (pred[b].find(i.second) != pred[b].end()) {
					d[i.first] = d[b];
					q.push_front(i.first);
					pred[i.first].is(i.second);
				}
		}

		for (auto i : e[b]) {
			if (d[i.first] == 0)
				if (pred[b].find(i.second) == pred[b].end()) {
					d[i.first] = d[b] + 1;
					q.push_back(i.first);
					pred[i.first].is(i.second);
				}
		}
	}
	cout << d[n - 1] - 1 << endl;
}