#include <bits/stdc++.h>
using namespace std;

typedef pair<int, int> P;
const int N = (int)1e5 + 50, INF = (int)1e9;

int n, m;
map<int, vector<int> > G[N];
set<int> rem[N];
int dis[N];

deque<P> que;

void dfs(int v, int color, int d) {
//    printf("in %d , color: %d\n", v, color);
    rem[v].erase(color);
    if(d < dis[v]) {
        dis[v] = d;
        que.push_back({v, color});
    }
    for(int nxt : G[v][color]) {
        if(rem[nxt].find(color) != rem[nxt].end()) {
//            printf("from %d to %d\n", v, nxt);
            dfs(nxt, color, d);
        }
    }
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(NULL);

    cin >> n >> m;
    fill(dis, dis + n, INF);
    for(int i = 0; i < m; i++) {
        int a, b, c; cin >> a >> b >> c; a--, b--, c--;
        G[a][c].push_back(b);
        G[b][c].push_back(a);
        rem[a].insert(c);
        rem[b].insert(c);
    }
    while(!rem[0].empty()) dfs(0, *rem[0].begin(), 1);
//    for(int i = 0; i < n; i++) {
//        printf("dis %d: %d\n", i + 1, dis[i]);
//    }
    while(!que.empty()) {
        P p = que.front();
        int v = p.first, c = p.second;
        que.pop_front();
        while(!rem[v].empty()) {
            dfs(v, *rem[v].begin(), dis[v] + 1);
        }
    }
    if(dis[n-1] == INF) dis[n-1] = -1;
    cout << dis[n - 1] << endl;
}
#include<iostream>
#include<algorithm>
#include<vector>
#include<set>
using namespace std;

static const int MAX = 100000;

int n, num;
vector<int> V[MAX];
int prenum[MAX], lowest[MAX], parent[MAX];
bool B[MAX];

void dfs(int cur, int pre) { //dfs??¨?????????prenum, lowest, parent????¨????
	prenum[cur] = lowest[cur] = num++;
	B[cur] = true;

	int next;
	for (int i = 0; i < V[cur].size(); i++) {
		next = V[cur][i];
		if (!B[next]) {
			parent[next] = cur;
			dfs(next, cur);
			lowest[cur] = min(lowest[cur], lowest[next]); //?????????????°?????????????????°????????????°??????
		} else if (next != pre) {
			lowest[cur] = min(lowest[cur], prenum[next]); //back-edge
		}
	}
}

void artPoint() {
	set<int> ap;
	int np = 0;
	for (int i = 1; i < n; i++) {
		int p = parent[i];
		if (p == 0) np++; //root?????\?¶???????????????°
		else if (prenum[p] <= lowest[i]) {
			ap.insert(p);
		}
	}
	if (np > 1) ap.insert(0);
	for (set<int>::iterator it = ap.begin(); it != ap.end(); it++) {
		cout << *it << endl;
	}
}

int main() {
	int e;
	cin >> n >> e;
	int s, t;
	for (int i = 0; i < e; i++)	{
		cin >> s >> t;
		V[s].push_back(t);
		V[t].push_back(s);
	}

	for (int i = 0; i < n; i++)	{
		B[i] =  false;
	}

	num = 1;
	dfs(0, -1); //next?????¶???prev???????????????

	artPoint();

	return 0;
}