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 <bits/stdc++.h>

using namespace std;

typedef pair<int, int> P;
typedef vector< vector<P> > graph;

const int INF = 10000000;
const int NONE = -1;

struct Node {
    int at;
    int cost; 
    int prev;
    Node(int at, int cost, int prev) : at(at), cost(cost), prev(prev) {}
    bool operator>(const Node &s) const {
        return cost > s.cost;
    }
};

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    int n, m;
    scanf("%d %d", &n, &m);
    graph e(n);
    for (int i = 0; i < m; i++) {
        int p, q, c;
        scanf("%d %d %d", &p, &q, &c);
        p--;
        q--;
        e[p].emplace_back(q, c);
        e[q].emplace_back(p, c);
    }
    set<P> memo;
    priority_queue<Node, vector<Node>, greater<Node> > pq;
    pq.push(Node(0, 0, NONE));
    //P g(n - 1, NONE);
    while (!pq.empty()) {
        Node x = pq.top();
        pq.pop();
        P key(x.at, x.prev);
        if (memo.find(key) != memo.end()) continue;
        if (x.at == n - 1) {
            cout << x.cost << "\n";
            return 0;
        }
        memo.insert(key);
        for (auto i = e[x.at].begin(), f = e[x.at].end(); i != f; ++i) {            
            if (memo.find(*i) != memo.end()) continue;
            int c = (*i).second;
            int cost = x.cost + (x.prev != c);
            pq.push(Node(i->first, cost, c));
        }
    }
    cout << "-1\n";
    return 0;
}