#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
#include <climits>
#define INF INT_MAX
using namespace std;

typedef pair<int, pair<int,int> > tri;

struct put
{
	int dokle,kakav;
};

struct Graph
{
	int n;
	vector<vector<put> > adj;
	vector<bool> visited;
	vector<int> dist;	
};

void init_graph(Graph &g, int n)
{
	g.n=n;
	g.adj.resize(n);
	g.visited.resize(n,false);
	g.dist.resize(n,INF);
}

void addEdge(Graph &g, int u,int v,int k)
{
	put pom;
	pom.dokle=v;
	pom.kakav=k;
	g.adj[u].push_back(pom);
	pom.dokle=u;
	g.adj[v].push_back(pom);
}

int Dijk(Graph &g,int start,int end)
{
	priority_queue<tri, vector<tri>, greater<tri> > pq;
	
	pq.push(make_pair(0, make_pair(start,0)));
    g.dist[start] = 0;
	
	while(!pq.empty())
	{
		int val=pq.top().first;
		int u=pq.top().second.first;
		int kak=pq.top().second.second;
		pq.pop();
		if(!g.visited[u])
		{
			//cout <<u<<"\n";
			if(u==end)
			{
				return val;
			}
			g.visited[u]=true;
			for(int i=0;i<g.adj[u].size();i++)
			{
				if(g.adj[u][i].kakav!=kak)
				{	
					if(g.dist[g.adj[u][i].dokle]>val)
					{
						pq.push(make_pair(val+1, make_pair(g.adj[u][i].dokle,g.adj[u][i].kakav)));
    					g.dist[g.adj[u][i].dokle] = val+1;
    				}
				}
				else
				{
					if(g.dist[g.adj[u][i].dokle]>val)
					{
						pq.push(make_pair(val, make_pair(g.adj[u][i].dokle,kak)));
    					g.dist[g.adj[u][i].dokle] = val;
					}
				}
			}
			
		}
	}
	return -1;
}



int main(int argc, char** argv) {
	ios_base::sync_with_stdio(false);
	
	int n,q;
	cin >>n>>q;
	Graph g;
	init_graph(g,n);
	
	for(int i=0;i<q;i++)
	{
		int u,v,k;
		cin >>u>>v>>k;
		u--;
		v--;
		addEdge(g,u,v,k);
	}
	int start,end;
	cin >>start>>end;
	
	cout <<Dijk(g,start-1,end-1)<<"\n";
	return 0;
}