#include <vector>
#include <iostream>
#include <unordered_set>
#include <unordered_map>

enum EdgeState {
    Ice = 0,
    Water
};
class Iceberg {
private:
    std::unordered_set<Iceberg*> m_Water;
    std::unordered_set<Iceberg*> m_Ice;
public:
    bool BridgeWater(Iceberg*);
    bool BridgeIce(Iceberg*);
    std::unordered_set<Iceberg*> Neighbours(EdgeState) const;
    std::unordered_set<Iceberg*> WaterNeighbours() const;
    std::unordered_set<Iceberg*> IceNeighbours() const;
};
class Family {
private:
    EdgeState m_Edges;
    std::unordered_set<Iceberg*> m_Nodes;
public:
    Family(EdgeState);
public:
    bool Add(Iceberg*);
};
class Node {
private:
    Family* m_SubGraph;
    std::unordered_set<Node*> m_Neighbours;
public:
    Node(Family*);
public:
    bool AddNeighbour(Node*);
    std::unordered_set<Node*> GetNeighbours() const;
};

template<typename T>
void Merge2Left(std::unordered_set<T>& left, const std::unordered_set<T>& right, const std::unordered_set<T>& exclusionSet) {
    for (auto& val : right) {
        if (left.find(val) != left.end() || exclusionSet.find(val) != exclusionSet.end()) {
            continue;
        }
        left.insert(val);
    }
}
std::vector<Family*> GenerateFamilies(const std::vector<Iceberg*>& nodes, std::unordered_map<Iceberg*, std::pair<Family*, Family*>>& familyMemberships) {
    std::vector<Family*> families;
    for (int i = 0; i < 2; ++i) {
        EdgeState edgeType = (EdgeState) i;
        Family* current = new Family(edgeType);
        std::unordered_set<Iceberg*> joined;
        std::unordered_set<Iceberg*> queued = { nodes[0] };
        int progress = 1;
        while (progress < nodes.size()) {
            if (!queued.size()) {
                if (joined.find(nodes[progress]) == joined.end()) {
                    families.push_back(current);
                    current = new Family(edgeType);
                    queued = { nodes[progress] };
                }
                ++progress;
            }
            std::unordered_set<Iceberg*> newQueue;
            for (auto& node : queued) {
                if (joined.find(node) != joined.end()) {
                    continue;
                }
                current->Add(node);
                Merge2Left(newQueue, node->Neighbours(edgeType), joined);
                if (!i) {
                    familyMemberships.insert({ node, { current, nullptr } });
                }
                else {
                    familyMemberships[node].second = current;
                }
                joined.insert(node);
            }
            queued = newQueue;
        } 
        families.push_back(current);
    }
    return families;
}
int ShortestPath(Node* from, Node* to) {
    int depth = 0;
    std::unordered_set<Node*> traversed;
    std::unordered_set<Node*> queued = { from };
    while (queued.size()) {
        if (queued.find(to) != queued.end()) {
            return depth;
        }
        std::unordered_set<Node*> newQueue;
        for (auto& node : queued) {
            if (traversed.find(node) != traversed.end()) {
                continue;
            }
            Merge2Left(newQueue, node->GetNeighbours(), traversed);
            traversed.insert(node);
        }
        ++depth;
        queued = newQueue;
    }
    return -1;
}
void OptimiseIO() {
    std::ios_base::sync_with_stdio(false);
    std::cout.tie(0);
    std::cerr.tie(0);
    std::cin.tie(0);
}

int main() {
    OptimiseIO();
    int n;
    int m;
    int mika;
    int laza;
    std::cin >> n >> m;
    std::vector<Iceberg*> northPole(n);
    std::vector<Family*> icebergFamilies;
    std::unordered_map<Iceberg*, std::pair<Family*, Family*>> node2families;
    for (auto& iceberg : northPole) {
        iceberg = new Iceberg();
    }
    for (int i = 0; i < m; ++i) {
        int a;
        int b;
        int pathType;
        std::cin >> a >> b >> pathType;
        --a;
        --b;
        pathType ? northPole[a]->BridgeIce(northPole[b]) : northPole[a]->BridgeWater(northPole[b]); 
        pathType ? northPole[b]->BridgeIce(northPole[a]) : northPole[b]->BridgeWater(northPole[a]); 
    } 
    std::cin >> mika >> laza;
    --mika;
    --laza;
    icebergFamilies = GenerateFamilies(northPole, node2families);
    std::unordered_map<Family*, Node*> familyGraph;
    for (auto& family : icebergFamilies) {
        familyGraph.insert({ family, new Node(family) });
    }
    for (auto& node : northPole) {
        familyGraph[node2families[node].first]->AddNeighbour(familyGraph[node2families[node].second]);
        familyGraph[node2families[node].second]->AddNeighbour(familyGraph[node2families[node].first]);
    }
    Node* mikaIce = familyGraph[node2families[northPole[mika]].first];
    Node* mikaWater = familyGraph[node2families[northPole[mika]].second];
    Node* lazaIce = familyGraph[node2families[northPole[laza]].first];
    Node* lazaWater = familyGraph[node2families[northPole[laza]].second];
    int waterIce = ShortestPath(mikaWater, lazaIce);
    int waterWater = ShortestPath(mikaWater, lazaWater);
    int min = INT32_MAX;
    if (waterIce < min && waterIce > -1) {
        min = waterIce;
    }
    if (waterWater < min && waterWater > -1) {
        min = waterWater;
    }
    if (min == INT32_MAX) {
        min = -1;
    }
    std::cout << min << std::endl;
    return 0;
}


// Iceberg: Methods
bool Iceberg::BridgeIce(Iceberg* iceberg) {
    if (m_Ice.find(iceberg) != m_Ice.end()) {
        return false;
    }
    m_Ice.insert(iceberg);
    return true;
}
bool Iceberg::BridgeWater(Iceberg* iceberg) {
    if (m_Water.find(iceberg) != m_Water.end()) {
        return false;
    }
    m_Water.insert(iceberg);
    return true;
}
std::unordered_set<Iceberg*> Iceberg::Neighbours(EdgeState state) const {
    return state == Ice ? m_Ice : m_Water;
}
std::unordered_set<Iceberg*> Iceberg::WaterNeighbours() const {
    return m_Water;
}
std::unordered_set<Iceberg*> Iceberg::IceNeighbours() const {
    return m_Ice;
}


// Family: Constructors
Family::Family(EdgeState state)
: m_Edges(state) {
}

// Family: Methods
bool Family::Add(Iceberg* node) {
    if (m_Nodes.find(node) != m_Nodes.end()) {
        return false;
    }
    m_Nodes.insert(node);
    return true;
}


// Node: Constructors
Node::Node(Family* value)
: m_SubGraph(value) {
}

// Node: Methods
bool Node::AddNeighbour(Node* node) {
    if (m_Neighbours.find(node) != m_Neighbours.end()) {
        return false;
    }
    m_Neighbours.insert(node);
    return true;
}
std::unordered_set<Node*> Node::GetNeighbours() const {
    return m_Neighbours;
}