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

// Loops
#define FOR(n)              for(int i=0;i<n;i++)
#define FORJ(n)             for(int j=0;j<n;j++)
#define FORN(n,x)           for(int x=0;i<n;i++)
#define RFOR(n)             for(int i=n-1;i>=0;i--)
#define RFORJ(n)            for(int j=n-1;j>=0;j--)
#define RFORN(n,x)          for(int x=n-1;x>=0;x--)
#define ODD_FOR(n)          for(int i=1;i<n;i+=2)
#define EVEN_FOR(n)         for(int i=2;i<n;i+=2)
#define FROM(n,m)           for(int i=n;i<m;i++)
#define FROMJ(n,m)          for(int j=n;j<m;j++)
#define RFROM(n,m)          for(int i=n-1;i>=m;i--)
#define RFROMJ(n,m)         for(int j=n-1;j>=m;j--)
#define STL_FOR(a)          for(auto i=a.begin();i!=a.end();i++)
#define STL_FORJ(a)         for(auto j=a.begin();j!=a.end();j++)
#define STL_FORN(a,x)       for(auto x=a.begin();x!=a.end();x++)
#define STL_FROM(a,n,m)     for(auto i=n;i!=m;i++)
#define STL_FROMJ(n,m)      for(auto j=n;j!=m;j++)
#define RSTL_FOR(a)         for(auto i=a.rbegin();i!=a.rend();i++)
#define RSTL_FORJ(a)        for(auto j=a.rbegin();j!=a.rend();j++)

// Types
#define ll                 long long
#define ull       unsigned long long
//#define vec                   vector
#define veci             vector<int>
#define pb                 push_back
#define pf                push_front
#define fi                     first
#define se                    second
#define umap           unordered_map
#define ummap     unordered_multimap
#define mmap                multimap
#define mset                multiset
#define uset           unordered_set
#define umset     unordered_multiset
#define endl                    '\n'
#define sz(a)               a.size()
#define all(a)    a.begin(), a.end()

// I/O
void read() {}
template<typename type, typename... types>
void read(type& arg, types&... args) { cin >> arg; read(args...); }

void write() { cout << endl; }
template<typename type, typename... types>
void write(type arg, types... args) { cout << arg << ' '; write(args...); }

#define dbg(x) cerr<<#x<<" = "<<x<<endl;

int dist[200000];

struct Pair {
    int first, second;
};
bool operator> (const Pair& a, const Pair& b) {
    //dbg(a.fi);
    return dist[a.fi]>dist[b.fi];
}

struct graph {
    int n;

    list<Pair>* adj;

    graph(int n): n(n) {
        adj=new list<Pair>[n+1];
        memset(dist, INT_MAX, (n+1)*4);
    }

    void add_edge(int node, int edge, int weight) {
        adj[node].push_back({edge, weight});
        adj[edge].push_back({node, weight});
    }
    

    void shortest_dist(int s, int d) {

        //list<pair<int, int>> q;
        priority_queue<Pair, vector<Pair>, greater<Pair> > q;
        q.push({s, 0});
        dist[s]=0;

        while(!q.empty()) {
            auto node=q.top();
            q.pop();
            //dbg(node.fi);
            //dbg(dist[node.fi]);
            for(Pair p:adj[node.fi]) {
                //dbg(dist[p.fi]);
                if(dist[p.fi]==-1 || dist[p.fi] > (dist[node.fi] + (node.se != p.se))) {
                    dist[p.fi]= dist[node.fi] + (node.se != p.se);
                    q.push(p);
                }
            }
        }
        cout<<dist[d]<<endl;
    }
};

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

    int n, m;
    cin>>n>>m;
    graph g(n);

    int node, edge, weight;
    FOR(m) {
        cin>>node>>edge>>weight;
        g.add_edge(node, edge, weight);
    }
    int s, d;
    cin>>s>>d;
    g.shortest_dist(s, d);
}
/*
*/