#include <bits/stdc++.h>

using namespace std;

#define countof(a) (sizeof(a)/sizeof(*a))

#define vi vector<int>
#define vvi vector<vector<int> >
#define vpi vector<pi >
#define pi pair<int,int>
#define mp make_pair
#define fi first
#define se second
#define all(n) n.begin(), n.end()

#define FROMTO(var, from, to) for (register int var = (from), var##down = ((int)(to)) < ((int)(from));var##down ? (var >= (int)(to)) : (var <= (int)(to));var##down ? var-- : var++)
#define UPTO(var, from, to)   for (register int var = (from); var <= ((int)to); var++)
#define DOWNTO(var, from, to) for (register int var = (from); var >= ((int)to); var--)
#define FOR(var, to)          UPTO(var, 0, (to)-1)
#define DOWN(var, from)       DOWNTO(var, (from)-1, 0) 

#define INIT(var, val) FOR(i,countof(var)) var[i] = val
#define INPUT(var) FOR(i,countof(var)) cin >> var[i]
#define INPUT1(var) FOR(i,countof(var)) cin >> var[i], var[i]--

#define SORT(v) qsort(v,countof(v),sizeof(*v),int_less)
#define SORTT(v) qsort(v,countof(v),sizeof(*v),int_greater)
#define QSORT(v,b) qsort(v,countof(v),sizeof(*v),b)

#define MOD 1000000007
#define INF ((1 << 30)-1)
#define LINF ((1LL << 62)-1)

typedef uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;
typedef uint64_t u64;
typedef int8_t s8;
typedef int16_t s16;
typedef int32_t s32;
typedef int64_t s64;

struct Comb {
    vector<vector<s64> > data;
    Comb(int n) { // O(n^2)
        data = vector<vector<s64> >(n+1,vector<s64>(n+1,1));
        UPTO(i,1,n) {
            FOR(j,i+1) {
                if (!j || j == i) data[i][j] = 1;
                else data[i][j] = data[i-1][j-1] + data[i-1][j];
            }
        }
    }
    
    s64 ncr(int n, int r) {
        return data[n][r];
    }
};

int int_less(const void *a, const void *b) {
  return (*((const int*)a) - *((const int*)b));
}
int int_greater(const void *a, const void *b) {
  return (*((const int*)b) - *((const int*)a));
}

struct UnionFind{
    vi data;
    UnionFind(int size):data(size,-1){}
    bool unite(int x,int y) {
        x=root(x);y=root(y);
        if(x!=y){
            if(data[y]<data[x])swap(x,y);
            data[x]+=data[y];data[y]=x;
        }
        return x!=y;
    }
    bool find(int x,int y) {
        return root(x)==root(y);
    }
    int root(int x) {
        return data[x]<0?x:data[x]=root(data[x]);
    }
    int size(int x) {
        return -data[root(x)];
    }
    // added by QCFium
    bool united() {
        int comroot = -1;
        FOR(i,data.size()) {
            if (comroot != -1 && root(i) != comroot) return false;
            comroot = root(i);
        }
        return true;
    }
};


#define mygc(c) (c)=getchar()
int ri() {
	int k,m=0;int x=0;
	for(;;){mygc(k);if(k=='-'){m=1;break;}if('0'<=k&&k<='9'){x=k-'0';break;}}for(;;){mygc(k);if(k<'0'||k>'9')break;x=x*10+k-'0';}if(m)x=-x;
	return x;
}

int main() {
	int n = ri();
	int m = ri();
	UnionFind uni(n);
	map<int, vector<pair<int,int> > > ma;
 	int a[m];
	int b[m];
	int c[m];
	FOR(i,m) {
		a[i] = ri()-1, b[i] = ri()-1, c[i] = ri()-1;
		ma[c[i]].push_back({a[i],b[i]});
		uni.unite(a[i],b[i]);
	}
	if (!uni.find(0,n-1)) {
		cout << -1 << endl;
		return 0;
	}
	
	vector<set<int> > sets;
	for (auto& i : ma) {
		set<int> nds;
		for (auto& j : i.se) nds.insert(j.fi), nds.insert(j.se);
		map<int,int> dec;
		map<int,int> com;
		int num = 0;
		for (auto& j : nds) dec[j] = num, com[num++] = j;
		
		UnionFind uni(num);
		for (auto& j : i.se) uni.unite(dec[j.fi], dec[j.se]);
		map<int,set<int> > re;
		FOR(j, num) re[uni.root(j)].insert(com[j]);
		for (auto& j : re) sets.push_back(j.se);
	}
	
	set<int> se_n[n];
	bool goal[sets.size()];
	FOR(i,sets.size()) goal[i] = 0;
	set<int> start;
	FOR(i, sets.size()) {
		for (auto& j : sets[i]) {
			se_n[j].insert(i);
			if (j == n-1) goal[i] = true;
			if (!j) start.insert(i);
		}
	}
	
	int res[sets.size()];
	FOR(i,sets.size()) res[i] = INF;
	for (auto i : start) res[i] = 1;
	
	int ans = INF;
	
	queue<int> que;
	for (auto i : start) que.push(i);
	while (1) {
		int cur = -1;
		unordered_set<int> tmp;
		unordered_set<int> next;
		while (que.size()) {
			auto i = que.front(); que.pop();
			if (!~cur) cur = res[i];
			if (goal[i]) {
				ans = cur;
				break;
			}
			for (auto j : sets[i])
				tmp.insert(j);
		}
		if (ans != INF) break;
		for (auto i : tmp) {
			for (auto j : se_n[i]) next.insert(j);
		}
		for (auto i : next) {
			if (res[i] > cur+1) {
				res[i] = cur+1;
				que.push(i);
			}
		}
	}
	
	if (ans == INF) cout << -1 << endl;
	else cout << ans << endl;
	
    return 0;
}


Measured memory_bytes: 85800