// Slower C++ solution:
#include <bits/stdc++.h>

#define rep(i,m,n) for(i=m;i<=n;i++)

#define rsp(it,s) for(set<int>::iterator it=s.begin();it!=s.end();it++)

#define mod 1000000007

#define inf 0x3f3f3f3f

#define vi vector<int>

#define pb push_back

#define mp make_pair

#define fi first

#define se second

#define ll long long

#define pi acos(-1.0)

#define pii pair<int,int>

#define Lson L, mid, rt<<1

#define Rson mid+1, R, rt<<1|1

const int maxn = 1e5 + 10;

using namespace std;

int n, m, k, t, h[maxn], tot, ans[maxn];

set<int>comp[maxn];

struct node

{

        int to, nxt, com;

} e[maxn << 2];

void add(int x, int y, int z)

{

        tot++;

        e[tot].to = y;

        e[tot].com = z;

        e[tot].nxt = h[x];

        h[x] = tot;

}

priority_queue<pair<int, int> >p;

int main()

{

        int i, j;

        while (scanf("%d %d", &n, &m) == 2)

        {

                //cout << n << " " << m << endl;

                for (int i = 1; i <= n; i++)

                {

                        h[i] = 0;

                        ans[i] = inf;

                        comp[i].clear();

                }

                tot = 0;

                while (m--)

                {

                        int a, b, c;

                        scanf("%d%d%d", &a, &b, &c);

                        add(a, b, c);

                        add(b, a, c);

                }

                p.push({0, 1});

                ans[1] = 0;

                while (!p.empty())

                {

                        int now = p.top().se, ca = -p.top().fi;

                        p.pop();

                        if (ans[now] < ca)

                        {

                                continue;

                        }

                        for (i = h[now]; i; i = e[i].nxt)

                        {

                                int to = e[i].to, to_com = e[i].com;

                                int to_ca = ca + (!comp[now].count(to_com));

                                if (ans[to] > to_ca)

                                {

                                        ans[to] = to_ca;

                                        p.push({ -to_ca, to});

                                        comp[to].clear();

                                        comp[to].insert(to_com);

                                }

                                else if (ans[to] == to_ca)

                                {

                                        comp[to].insert(to_com);

                                }

                        }

                }

                printf("%d\n", ans[n] == inf ? -1 : ans[n]);

        }

        return 0;

}

// Faster C++ solution for the same problem (measured speedup: 6.300279019094975x):
#include<cstdio>

#include<iostream>

#include<cstring>

#include<queue>

#include<map>

#define RG register

using namespace std;

const int N=1e5+10, M=2e5+10;

const long long mod=15131;

struct dabt{

	int next,to,dis;

}e[M*6],hsh[N*2];

struct node{

	int u,dis;

	bool operator < (const node&x)const{return x.dis<dis;}

};

int n,m,head[N+2*M],k,dist[N+2*M],st[2*M],ed[2*M],cnt,kk;

int kh,h[mod+1];

bool vis[N+2*M];

template<typename I> inline void read(I &ot){

	I ch=getchar(), x=0, f=1;

	while(ch<'0' || ch>'9'){if(ch=='-') f=-1; ch=getchar();	}

	while(ch>='0' && ch<='9'){x=x*10+ch-'0'; ch=getchar();	}

	ot=x*f;}

template<typename I, typename... U> inline void read(I &x,U&... y){read(x); read(y...);}

inline void add(int from,int to,int d){

	e[++k]=(dabt){head[from],to,d}; head[from]=k;

	e[++k]=(dabt){head[to],from,d}; head[to]=k;

}

inline void adde(int from,int to,int d){hsh[++kh]=(dabt){h[from],to,d}; h[from]=kh;}

/*inline int id(int a,int b){

	int ss=((long long)a*n%mod+b)%mod;

	for(int i=h[ss];i;i=hsh[i].next)

	{

		int v=hsh[i].to;

		if(st[v]==a && ed[v]==b) return hsh[i].dis;

	}

	st[++kk]=a; ed[kk]=b;

	adde(ss,kk,++cnt);

	return cnt;

}*/

map<pair<int,int>,int> P;

int id(int u,int c) {

    if(P.find(make_pair(u,c))!=P.end())

        return P[make_pair(u,c)];

    return P[make_pair(u,c)]=++cnt;

}

inline void dij()

{

	priority_queue<node> pn;

	while(!pn.empty()) pn.pop();

	for(int i=1;i<=n+m*2;i++) dist[i]=2e9;

	pn.push((node){1,0}); dist[1]=0;

	while(!pn.empty())

	{

		node u=pn.top(); pn.pop();

		int x=u.u; vis[x]=1;

		for(int i=head[x];i;i=e[i].next)

		{

			int v=e[i].to;

			if(dist[v]>dist[x]+e[i].dis)

			{

				dist[v]=dist[x]+e[i].dis;

				if(!vis[v]) pn.push((node){v,dist[v]});

			}

		}

	}

}

int main()

{

//	freopen("Snuke's Subway Trip.in","r",stdin);

//	freopen(". out","w",stdout);

	read(n,m); cnt=n;

	for(int i=1,a,b,c;i<=m;i++)

	{

		read(a,b,c);

		int id1=id(a,c), id2=id(b,c);

		add(a,id1,1); add(id1,id2,0); add(id2,b,1);

	}

	dij();

	printf("%d\n",dist[n]==2e9 ? -1 : dist[n]/2);

//	for(int i=1;i<=9;i++) printf("%d\n",dist[i]);

	//fclose(stdin); fclose(stdout);

	return 0;

}