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

//.define
// #define FILE_IN_OUT
#define RET(_x)                       return cout << (_x) << '\n', 0;
#define all(_obj)                     std::begin(_obj), std::end(_obj)
#define loop(_n)                      for (int i = 0; i < (_n); ++i)
#define ceilDiv(_dividend, _divider)  (((_dividend) - 1LL + (_divider)) / (_divider))
#define has(_obj, _val)               ((_obj).find(_val) != (_obj).end())
#define sz(_obj)                      static_cast<int>((_obj).size())
#ifdef SHJ_LOCAL
    #define debug(_x)                 std::cerr << (#_x) << " = " << (_x) << '\n' << std::flush;
#else
    #define debug(_x)                 ;
#endif
#define endl                          "\n"
template<typename Tp>
inline void outarr(Tp _begin, Tp _end, const char* _delim = " ") {
    for (Tp current = _begin; current != _end; ++current) {
        std::cout << *current << _delim;
    }
    std::cout << '\n';
}

//.constant
using ll  = int64_t;
using pii = std::pair<int, int>;
constexpr int INF = 0x3f3f3f3f;
constexpr int MOD = static_cast<const int>(1e9 + 7);

//.data
const int MAXV = 300000;

vector<pii> graph[MAXV];
vector<pii> gr[MAXV];
int vbt[MAXV];
int tIn[MAXV];
int fUp[MAXV];
bool used[MAXV];
bool bridge[MAXV];
bool art[MAXV];
int T = 0;
int VID = 0;

inline int NextID() {
    return ++VID;
}

void FindBridges(int from = 0, int p = -1) {
    used[from] = true;
    tIn[from] = fUp[from] = T++;
    for (auto&& [to, c] : graph[from]) {
        if (to == p) {
            continue;
        }
        if (!used[to]) {
            FindBridges(to, from);
            fUp[from] = min(fUp[from], fUp[to]);
            if (fUp[to] > tIn[from]) {
                bridge[to] = true;
            }
        } else {
            fUp[from] = min(fUp[from], tIn[to]);
        }
    }
}

void CreateGr(int from = 0, int vid = 0) {
    used[from] = true;
    vbt[from] = vid;
    for (auto&& [to, c] : graph[from]) {
        if (!used[to]) {
            if (bridge[to]) {
                CreateGr(to, NextID());
            } else {
                art[vbt[from]] |= c;
                CreateGr(to, vid);
            }
            if (bridge[to]) {
                gr[vbt[from]].emplace_back(vbt[to], c);
                gr[vbt[to]].emplace_back(vbt[from], c);
            }
        }
    }
}

void BuildBT() {
    FindBridges();
    memset(used, 0, sizeof(used));
    CreateGr();
}

void Dfs(int from, int p = -1, bool d = false) {
    art[from] |= d;
    for (auto&& [to, c] : gr[from]) {
        if (to != p) {
            Dfs(to, from, d | c);
        }
    }
}

//.code
int main() {
#ifdef FILE_IN_OUT
    std::ifstream cin ("input.txt",  std::ios::in);
    std::ofstream cout("output.txt", std::ios::out);
#else
    std::ios_base::sync_with_stdio(false);
    std::cin.tie(nullptr);
#endif

    int n, m;
    cin >> n >> m;
    loop(m) {
        int a, b, c;
        cin >> a >> b >> c;
        --a; --b;
        graph[a].emplace_back(b, c);
        graph[b].emplace_back(a, c);
    }
    int from, to;
    cin >> from >> to;
    --from; --to;
    BuildBT();
    Dfs(vbt[from]);
    if (art[vbt[to]]) {
        cout << "YES" endl;
    } else {
        cout << "NO" endl;
    }

#ifdef FILE_IN_OUT
    cin.close();
    cout.close();
#endif
    return 0;
}


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

//.define
// #define FILE_IN_OUT
#define RET(_x)                       return cout << (_x) << '\n', 0;
#define all(_obj)                     std::begin(_obj), std::end(_obj)
#define loop(_n)                      for (int i = 0; i < (_n); ++i)
#define ceilDiv(_dividend, _divider)  (((_dividend) - 1LL + (_divider)) / (_divider))
#define has(_obj, _val)               ((_obj).find(_val) != (_obj).end())
#define sz(_obj)                      static_cast<int>((_obj).size())
#ifdef SHJ_LOCAL
    #define debug(_x)                 std::cerr << (#_x) << " = " << (_x) << '\n' << std::flush;
#else
    #define debug(_x)                 ;
#endif
#define endl                          "\n"
template<typename Tp>
inline void outarr(Tp _begin, Tp _end, const char* _delim = " ") {
    for (Tp current = _begin; current != _end; ++current) {
        std::cout << *current << _delim;
    }
    std::cout << '\n';
}

//.constant
using ll  = int64_t;
using pii = std::pair<int, int>;
constexpr int INF = 0x3f3f3f3f;
constexpr int MOD = static_cast<const int>(1e9 + 7);

//.data
const int MAXV = 300000;

vector<pii> graph[MAXV];
vector<pii> gr[MAXV];
int vbt[MAXV];
int tIn[MAXV];
int fUp[MAXV];
bool used[MAXV];
bool bridge[MAXV];
bool art[MAXV];
int T = 0;
int VID = 0;

inline int NextID() {
    return ++VID;
}

void FindBridges(int from = 0, int p = -1) {
    used[from] = true;
    tIn[from] = fUp[from] = T++;
    for (auto&& [to, c] : graph[from]) {
        if (to == p) {
            continue;
        }
        if (!used[to]) {
            FindBridges(to, from);
            fUp[from] = min(fUp[from], fUp[to]);
            if (fUp[to] > tIn[from]) {
                bridge[to] = true;
            }
        } else {
            fUp[from] = min(fUp[from], tIn[to]);
        }
    }
}

void CreateGr(int from = 0, int p = -1, int vid = 0) {
    used[from] = true;
    vbt[from] = vid;
    for (auto&& [to, c] : graph[from]) {
        if (!used[to]) {
            if (bridge[to]) {
                CreateGr(to, from, NextID());
            } else {
                art[vbt[from]] |= c;
                CreateGr(to, from, vid);
            }
            if (bridge[to]) {
                gr[vbt[from]].emplace_back(vbt[to], c);
                gr[vbt[to]].emplace_back(vbt[from], c);
            }
        } else {
            if (to != p) {
                art[vbt[from]] |= c;
            }
        }
    }
}

void BuildBT() {
    FindBridges();
    memset(used, 0, sizeof(used));
    CreateGr();
}

void Dfs(int from, int p = -1, bool d = false) {
    art[from] |= d;
    for (auto&& [to, c] : gr[from]) {
        if (to != p) {
            Dfs(to, from, d | c);
        }
    }
}

//.code
int main() {
#ifdef FILE_IN_OUT
    std::ifstream cin ("input.txt",  std::ios::in);
    std::ofstream cout("output.txt", std::ios::out);
#else
    std::ios_base::sync_with_stdio(false);
    std::cin.tie(nullptr);
#endif

    int n, m;
    cin >> n >> m;
    loop(m) {
        int a, b, c;
        cin >> a >> b >> c;
        --a; --b;
        graph[a].emplace_back(b, c);
        graph[b].emplace_back(a, c);
    }
    int from, to;
    cin >> from >> to;
    --from; --to;
    BuildBT();
    Dfs(vbt[from]);
    if (art[vbt[to]]) {
        cout << "YES" endl;
    } else {
        cout << "NO" endl;
    }

#ifdef FILE_IN_OUT
    cin.close();
    cout.close();
#endif
    return 0;
}


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

//.define
// #define FILE_IN_OUT
#define RET(_x)                       return cout << (_x) << '\n', 0;
#define all(_obj)                     std::begin(_obj), std::end(_obj)
#define loop(_n)                      for (int i = 0; i < (_n); ++i)
#define ceilDiv(_dividend, _divider)  (((_dividend) - 1LL + (_divider)) / (_divider))
#define has(_obj, _val)               ((_obj).find(_val) != (_obj).end())
#define sz(_obj)                      static_cast<int>((_obj).size())
#ifdef SHJ_LOCAL
    #define debug(_x)                 std::cerr << (#_x) << " = " << (_x) << '\n' << std::flush;
#else
    #define debug(_x)                 ;
#endif
#define endl                          "\n"
template<typename Tp>
inline void outarr(Tp _begin, Tp _end, const char* _delim = " ") {
    for (Tp current = _begin; current != _end; ++current) {
        std::cout << *current << _delim;
    }
    std::cout << '\n';
}

//.constant
using ll  = int64_t;
using pii = std::pair<int, int>;
constexpr int INF = 0x3f3f3f3f;
constexpr int MOD = static_cast<const int>(1e9 + 7);

//.data
const int MAXV = 300000;

vector<pii> graph[MAXV];
vector<pii> gr[MAXV];
int vbt[MAXV];
int tIn[MAXV];
int fUp[MAXV];
bool used[MAXV];
bool bridge[MAXV];
bool art[MAXV];
int T = 0;
int VID = 0;

inline int NextID() {
    return ++VID;
}

void FindBridges(int from = 0, int p = -1) {
    used[from] = true;
    tIn[from] = fUp[from] = T++;
    for (auto&& [to, c] : graph[from]) {
        if (to == p) {
            continue;
        }
        if (!used[to]) {
            FindBridges(to, from);
            fUp[from] = min(fUp[from], fUp[to]);
            if (fUp[to] > tIn[from]) {
                bridge[to] = true;
            }
        } else {
            fUp[from] = min(fUp[from], tIn[to]);
        }
    }
}

void CreateGr(int from = 0, int p = -1, int vid = 0) {
    used[from] = true;
    vbt[from] = vid;
    for (auto&& [to, c] : graph[from]) {
        if (!used[to]) {
            if (bridge[to]) {
                CreateGr(to, from, NextID());
            } else {
                art[vbt[from]] |= c;
                CreateGr(to, from, vid);
            }
            if (bridge[to]) {
                gr[vbt[from]].emplace_back(vbt[to], c);
                gr[vbt[to]].emplace_back(vbt[from], c);
            }
        } else {
            if (to != p) {
                art[vbt[from]] |= c;
            }
        }
    }
}

void BuildBT() {
    FindBridges();
    memset(used, 0, sizeof(used));
    CreateGr();
}

void Dfs(int from, int p = -1, bool d = false) {
    art[from] |= d;
    for (auto&& [to, c] : gr[from]) {
        if (to != p) {
            Dfs(to, from, d | c | art[from]);
        }
    }
}

//.code
int main() {
#ifdef FILE_IN_OUT
    std::ifstream cin ("input.txt",  std::ios::in);
    std::ofstream cout("output.txt", std::ios::out);
#else
    std::ios_base::sync_with_stdio(false);
    std::cin.tie(nullptr);
#endif

    int n, m;
    cin >> n >> m;
    loop(m) {
        int a, b, c;
        cin >> a >> b >> c;
        --a; --b;
        graph[a].emplace_back(b, c);
        graph[b].emplace_back(a, c);
    }
    int from, to;
    cin >> from >> to;
    --from; --to;
    BuildBT();
    Dfs(vbt[from]);
    if (art[vbt[to]]) {
        cout << "YES" endl;
    } else {
        cout << "NO" endl;
    }

#ifdef FILE_IN_OUT
    cin.close();
    cout.close();
#endif
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

string to_string(string s) {
  return '"' + s + '"';
}

string to_string(const char* s) {
  return to_string((string) s);
}

template <typename A, typename B>
string to_string(pair<A, B> p) {
  return "(" + to_string(p.first) + ", " + to_string(p.second) + ")";
}

template <typename A>
string to_string(A v) {
  bool first = true;
  string res = "{";
  for (const auto &x : v) {
    if (!first) {
      res += ", ";
    }
    first = false;
    res += to_string(x);
  }
  res += "}";
  return res;
}

void debug_out() { cerr << endl; }

template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) {
  cerr << " " << to_string(H);
  debug_out(T...);
}

#ifdef LOCAL
#define debug(...) cerr << "[" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__)
#else
#define debug(...) 42
#endif

const int MAXN = 3e5+9;

class UnionFind{
  vector<int> p,rank,hasArtifact;
public:
  UnionFind(int N): p(N+1),rank(N+1),hasArtifact(N+1){
    for(int i = 1; i <= N; i++) p[i] = i;
  }

  int findSet(int i){
    if(p[i] == i) return i;
    else return p[i] = findSet(p[i]);
  }

  bool isSameSet(int i, int j){
    return findSet(i) == findSet(j);
  }

  void merge(int i, int j, int val = 0){
    int x = findSet(i), y = findSet(j);
    if(x == y) return;
    if(rank[x] > rank[y]){
      p[y] = x;
      hasArtifact[x] |= val | hasArtifact[y];
    }
    else{
      p[x] = y;
      hasArtifact[y] |= val | hasArtifact[x];
      if(rank[x] == rank[y]) ++rank[y];
    }
  }

  bool hasArt(int i){ return hasArtifact[i]; }
};

struct Edge{
  int u, v, hasArtifact;
  Edge(){}
  Edge(int u, int v, int hasArtifact): u(u), v(v), hasArtifact(hasArtifact){}
};

vector<Edge> E;
vector<vector<int> > adj(MAXN);
vector<vector<int> > tree(MAXN);
UnionFind uf(MAXN);
int tin[MAXN], low[MAXN], visited[MAXN], timer;

void dfs(int u, int edge){
  visited[u] = 1;
  tin[u] = low[u] = timer++;
  for(auto k: adj[u]){
    Edge e = E[k];
    int v = e.u ^ e.v ^ u;
    if(!visited[v]){
      dfs(v, k);
      low[u] = min(low[u], low[v]);
    }
    else if(k != edge){
      low[u] = min(low[u], tin[v]);
    }
  }
  if(low[u] < tin[u] && edge != -1) uf.merge(E[edge].u, E[edge].v, E[edge].hasArtifact);
}

void buildBridgeTree(){
  dfs(1,-1);
  for(auto e: E){
    int U = uf.findSet(e.u), V = uf.findSet(e.v);
    if(U != V){
      E.emplace_back(U,V,e.hasArtifact);
      tree[U].push_back(E.size()-1);
      tree[V].push_back(E.size()-1);
    }
  }
}

vector<int> parent(MAXN,-1);
void dfs1(int u, int t, int p){
  parent[u] = p;
  if(u == t) return;
  for(auto k: tree[u]){
    Edge e = E[k];
    int v = e.u ^ e.v ^ u;
    if(v == p) continue;
    dfs(v, u);
  }
}

int main(){
  ios::sync_with_stdio(false); cin.tie(NULL);
  int n, m; cin >> n >> m;
  for(int i = 0; i < m; i++){
    int u, v, hasArtifact; cin >> u >> v >> hasArtifact;
    E.emplace_back(u,v,hasArtifact);
    adj[u].push_back(E.size()-1);
    adj[v].push_back(E.size()-1);
  }
  int a, b; cin >> a >> b;
  buildBridgeTree();
  dfs1(uf.findSet(a), uf.findSet(b), -1);
  int cur = uf.findSet(b);
  bool isPossible = false;
  while(cur != -1){
    int u = parent[cur];
    isPossible = uf.hasArt(u);
    isPossible = uf.hasArt(cur);
    for(auto k: tree[u]){
      Edge e = E[k];
      int v = e.u ^ e.v ^ u;
      if(v == cur) isPossible = e.hasArtifact;
    }
    cur = parent[cur];
  }
  if(isPossible) cout << "YES" << endl;
  else cout << "NO" << endl;
  return 0;
}


#include <bits/stdc++.h>

using namespace std;

const int MAXN = 3e5+9;

class UnionFind{
  vector<int> p,rank,hasArtifact;
public:
  UnionFind(int N): p(N+1),rank(N+1),hasArtifact(N+1){
    for(int i = 1; i <= N; i++) p[i] = i;
  }

  int findSet(int i){
    if(p[i] == i) return i;
    else return p[i] = findSet(p[i]);
  }

  bool isSameSet(int i, int j){
    return findSet(i) == findSet(j);
  }

  void merge(int i, int j, int val = 0){
    int x = findSet(i), y = findSet(j);
    if(x == y) return;
    if(rank[x] > rank[y]){
      p[y] = x;
      hasArtifact[x] |= val | hasArtifact[y];
    }
    else{
      p[x] = y;
      hasArtifact[y] |= val | hasArtifact[x];
      if(rank[x] == rank[y]) ++rank[y];
    }
  }

  bool hasArt(int i){ return hasArtifact[i]; }
};

struct Edge{
  int u, v, hasArtifact;
  Edge(){}
  Edge(int u, int v, int hasArtifact): u(u), v(v), hasArtifact(hasArtifact){}
};

vector<Edge> E;
vector<vector<int> > adj(MAXN);
vector<vector<int> > tree(MAXN);
UnionFind uf(MAXN);
int tin[MAXN], low[MAXN], visited[MAXN], timer;

void dfs(int u, int edge){
  visited[u] = 1;
  tin[u] = low[u] = timer++;
  for(auto k: adj[u]){
    Edge e = E[k];
    int v = e.u ^ e.v ^ u;
    if(!visited[v]){
      dfs(v, k);
      low[u] = min(low[u], low[v]);
    }
    else if(k != edge){
      low[u] = min(low[u], tin[v]);
    }
  }
  if(low[u] < tin[u] && edge != -1) uf.merge(E[edge].u, E[edge].v, E[edge].hasArtifact);
}

void buildBridgeTree(){
  dfs(1,-1);
  int m = E.size();
  for(int i = 0; i < m; i++){
    Edge e = E[i];
    int U = uf.findSet(e.u), V = uf.findSet(e.v);
    if(U != V){
      E.emplace_back(U,V,e.hasArtifact);
      tree[U].push_back(E.size()-1);
      tree[V].push_back(E.size()-1);
    }
  }
}

vector<int> parent(MAXN,-1);
void dfs1(int u, int t, int p){
  parent[u] = p;
  if(u == t) return;
  for(auto k: tree[u]){
    Edge e = E[k];
    int v = e.u ^ e.v ^ u;
    if(v == p) continue;
    dfs1(v, t, u);
  }
}

int main(){
  ios::sync_with_stdio(false); cin.tie(NULL);
  int n, m; cin >> n >> m;
  for(int i = 0; i < m; i++){
    int u, v, hasArtifact; cin >> u >> v >> hasArtifact;
    E.emplace_back(u,v,hasArtifact);
    adj[u].push_back(E.size()-1);
    adj[v].push_back(E.size()-1);
  }
  int a, b; cin >> a >> b;
  buildBridgeTree();
  dfs1(uf.findSet(a), uf.findSet(b), -1);
  int cur = uf.findSet(b);
  bool isPossible = false;
  if(uf.findSet(a) == uf.findSet(b) && uf.hasArt(uf.findSet(a))) isPossible = true;
  else{
    while(cur != uf.findSet(a)){
      int u = parent[cur];
      isPossible |= uf.hasArt(u);
      isPossible |= uf.hasArt(cur);
      for(auto k: tree[u]){
	Edge e = E[k];
	int v = e.u ^ e.v ^ u;
	if(v == cur) isPossible |= e.hasArtifact;
      }
      cur = parent[cur];
    }
  }
  if(isPossible) cout << "YES" << endl;
  else cout << "NO" << endl;
  return 0;
}


#include <bits/stdc++.h>

using namespace std;

const int MAXN = 3e5+9;

class UnionFind{
  vector<int> p,rank,hasArtifact;
public:
  UnionFind(int N): p(N+1),rank(N+1){
    for(int i = 1; i <= N; i++) p[i] = i;
  }

  int findSet(int i){
    if(p[i] == i) return i;
    else return p[i] = findSet(p[i]);
  }

  bool isSameSet(int i, int j){
    return findSet(i) == findSet(j);
  }

  void merge(int i, int j){
    int x = findSet(i), y = findSet(j);
    if(x == y) return;
    if(rank[x] > rank[y]){
      p[y] = x;
    }
    else{
      p[x] = y;
      if(rank[x] == rank[y]) ++rank[y];
    }
  }
};

struct Edge{
  int u, v, hasArtifact;
  Edge(){}
  Edge(int u, int v, int hasArtifact): u(u), v(v), hasArtifact(hasArtifact){}
};

vector<Edge> E;
vector<vector<int> > adj(MAXN);
vector<vector<int> > tree(MAXN);
UnionFind uf(MAXN);
int tin[MAXN], low[MAXN], visited[MAXN], timer, hasArtifact[MAXN];

void dfs(int u, int edge){
  visited[u] = 1;
  tin[u] = low[u] = timer++;
  for(auto k: adj[u]){
    Edge e = E[k];
    int v = e.u ^ e.v ^ u;
    if(!visited[v]){
      dfs(v, k);
      low[u] = min(low[u], low[v]);
    }
    else if(k != edge){
      low[u] = min(low[u], tin[v]);
    }
  }
  if(low[u] < tin[u] && edge != -1) uf.merge(E[edge].u, E[edge].v);
}

void buildBridgeTree(){
  dfs(1,-1);
  int m = E.size();
  for(int i = 0; i < m; i++){
    Edge e = E[i];
    int U = uf.findSet(e.u), V = uf.findSet(e.v);
    if(U != V){
      E.emplace_back(U,V,e.hasArtifact);
      tree[U].push_back(E.size()-1);
      tree[V].push_back(E.size()-1);
    }
    else{
      hasArtifact[U] |= e.hasArtifact;
    }
  }
}

vector<int> parent(MAXN,-1);

void dfs1(int u, int t, int p){
  parent[u] = p;
  if(u == t) return;
  for(auto k: tree[u]){
    Edge e = E[k];
    int v = e.u ^ e.v ^ u;
    if(v == p) continue;
    dfs1(v, t, u);
  }
}

int main(){
  ios::sync_with_stdio(false); cin.tie(NULL);
  int n, m; cin >> n >> m;
  for(int i = 0; i < m; i++){
    int u, v, hasArtifact; cin >> u >> v >> hasArtifact;
    E.emplace_back(u,v,hasArtifact);
    adj[u].push_back(E.size()-1);
    adj[v].push_back(E.size()-1);
  }
  int a, b; cin >> a >> b;
  buildBridgeTree();
  dfs1(uf.findSet(a), uf.findSet(b), -1);
  int cur = uf.findSet(b);
  bool isPossible = false;
  if(uf.findSet(a) == uf.findSet(b) && hasArtifact[uf.findSet(a)]) isPossible = true;
  else{
    while(cur != uf.findSet(a)){
      int u = parent[cur];
      isPossible |= hasArtifact[u];
      isPossible |= hasArtifact[cur];
      for(auto k: tree[u]){
	Edge e = E[k];
	int v = e.u ^ e.v ^ u;
	if(v == cur) isPossible |= e.hasArtifact;
      }
      cur = parent[cur];
    }
  }
  if(isPossible) cout << "YES" << endl;
  else cout << "NO" << endl;
  return 0;
}


#include <bits/stdc++.h>

using namespace std;

const int MAXN = 3e5+9;

class UnionFind{
  vector<int> p,rank,hasArtifact;
public:
  UnionFind(int N): p(N+1),rank(N+1){
    for(int i = 1; i <= N; i++) p[i] = i;
  }

  int findSet(int i){
    if(p[i] == i) return i;
    else return p[i] = findSet(p[i]);
  }

  bool isSameSet(int i, int j){
    return findSet(i) == findSet(j);
  }

  void merge(int i, int j){
    int x = findSet(i), y = findSet(j);
    if(x == y) return;
    if(rank[x] > rank[y]){
      p[y] = x;
    }
    else{
      p[x] = y;
      if(rank[x] == rank[y]) ++rank[y];
    }
  }
};

struct Edge{
  int u, v, hasArtifact;
  Edge(){}
  Edge(int u, int v, int hasArtifact): u(u), v(v), hasArtifact(hasArtifact){}
};

vector<Edge> E;
vector<vector<int> > adj(MAXN);
vector<vector<int> > tree(MAXN);
UnionFind uf(MAXN);
int tin[MAXN], low[MAXN], visited[MAXN], timer, hasArtifact[MAXN];

void dfs(int u, int edge){
  visited[u] = 1;
  tin[u] = low[u] = timer++;
  for(auto k: adj[u]){
    Edge e = E[k];
    int v = e.u ^ e.v ^ u;
    if(!visited[v]){
      dfs(v, k);
      low[u] = min(low[u], low[v]);
    }
    else if(k != edge){
      low[u] = min(low[u], tin[v]);
    }
  }
  if(low[u] < tin[u] && edge != -1) uf.merge(E[edge].u, E[edge].v);
}

void buildBridgeTree(){
  dfs(1,-1);
  int m = E.size();
  for(int i = 0; i < m; i++){
    Edge e = E[i];
    int U = uf.findSet(e.u), V = uf.findSet(e.v);
    if(U != V){
      E.emplace_back(U,V,e.hasArtifact);
      tree[U].push_back(E.size()-1);
      tree[V].push_back(E.size()-1);
    }
    else{
      hasArtifact[U] |= e.hasArtifact;
    }
  }
}

vector<int> parent(MAXN,-1);

void dfs1(int u, int t, int p){
  parent[u] = p;
  if(u == t) return;
  for(auto k: tree[u]){
    Edge e = E[k];
    int v = e.u ^ e.v ^ u;
    if(v == p) continue;
    dfs1(v, t, u);
  }
}

int main(){
  ios::sync_with_stdio(false); cin.tie(NULL);
  int n, m; cin >> n >> m;
  for(int i = 0; i < m; i++){
    int u, v, hasArtifact; cin >> u >> v >> hasArtifact;
    E.emplace_back(u,v,hasArtifact);
    adj[u].push_back(E.size()-1);
    adj[v].push_back(E.size()-1);
  }
  int a, b; cin >> a >> b;
  buildBridgeTree();
  dfs1(uf.findSet(a), uf.findSet(b), -1);
  int cur = uf.findSet(b);
  bool isPossible = false;
  if(uf.findSet(a) == uf.findSet(b) && hasArtifact[uf.findSet(a)]) isPossible = true;
  else{
    while(cur != uf.findSet(a)){
      int u = parent[cur];
      isPossible |= hasArtifact[u];
      isPossible != hasArtifact[cur];
      for(auto k: tree[u]){
	Edge e = E[k];
	int v = e.u ^ e.v ^ u;
	if(v == cur) isPossible |= e.hasArtifact;
      }
      cur = parent[cur];
    }
  }
  if(isPossible) cout << "YES" << endl;
  else cout << "NO" << endl;
  return 0;
}


#include <bits/stdc++.h>

using namespace std;

const int MAXN = 3e5+9;

class UnionFind{
  vector<int> p,rank,hasArtifact;
public:
  UnionFind(int N): p(N+1),rank(N+1),hasArtifact(N+1){
    for(int i = 1; i <= N; i++) p[i] = i;
  }

  int findSet(int i){
    if(p[i] == i) return i;
    else return p[i] = findSet(p[i]);
  }

  bool isSameSet(int i, int j){
    return findSet(i) == findSet(j);
  }

  void merge(int i, int j, int val = 0){
    int x = findSet(i), y = findSet(j);
    if(x == y) return;
    if(rank[x] > rank[y]){
      p[y] = x;
      hasArtifact[x] |= val | hasArtifact[y];
    }
    else{
      p[x] = y;
      hasArtifact[y] |= val | hasArtifact[x];
      if(rank[x] == rank[y]) ++rank[y];
    }
  }

  bool hasArt(int i){ return hasArtifact[i]; }
};

struct Edge{
  int u, v, hasArtifact;
  Edge(){}
  Edge(int u, int v, int hasArtifact): u(u), v(v), hasArtifact(hasArtifact){}
};

vector<Edge> E;
vector<vector<int> > adj(MAXN);
vector<vector<int> > tree(MAXN);
UnionFind uf(MAXN);
int tin[MAXN], low[MAXN], visited[MAXN], timer;

void dfs(int u, int edge){
  visited[u] = 1;
  tin[u] = low[u] = timer++;
  for(auto k: adj[u]){
    Edge e = E[k];
    int v = e.u ^ e.v ^ u;
    if(!visited[v]){
      dfs(v, k);
      low[u] = min(low[u], low[v]);
    }
    else if(k != edge){
      low[u] = min(low[u], tin[v]);
    }
  }
  if(low[u] < tin[u] && edge != -1) uf.merge(E[edge].u, E[edge].v, E[edge].hasArtifact);
}

void buildBridgeTree(){
  dfs(1,-1);
  for(auto e: E){
    int U = uf.findSet(e.u), V = uf.findSet(e.v);
    if(U != V){
      E.emplace_back(U,V,e.hasArtifact);
      tree[U].push_back(E.size()-1);
      tree[V].push_back(E.size()-1);
    }
  }
}

vector<int> parent(MAXN,-1);
void dfs1(int u, int t, int p){
  parent[u] = p;
  if(u == t) return;
  for(auto k: tree[u]){
    Edge e = E[k];
    int v = e.u ^ e.v ^ u;
    if(v == p) continue;
    dfs1(v, t, u);
  }
}

int main(){
  ios::sync_with_stdio(false); cin.tie(NULL);
  int n, m; cin >> n >> m;
  for(int i = 0; i < m; i++){
    int u, v, hasArtifact; cin >> u >> v >> hasArtifact;
    E.emplace_back(u,v,hasArtifact);
    adj[u].push_back(E.size()-1);
    adj[v].push_back(E.size()-1);
  }
  int a, b; cin >> a >> b;
  buildBridgeTree();
  dfs1(uf.findSet(a), uf.findSet(b), -1);
  int cur = uf.findSet(b);
  bool isPossible = false;
  if(uf.findSet(a) == uf.findSet(b) && uf.hasArt(uf.findSet(a))) isPossible = true;
  else{
    while(cur != uf.findSet(a)){
      int u = parent[cur];
      isPossible = uf.hasArt(u);
      isPossible = uf.hasArt(cur);
      for(auto k: tree[u]){
	Edge e = E[k];
	int v = e.u ^ e.v ^ u;
	if(v == cur) isPossible = e.hasArtifact;
      }
      cur = parent[cur];
    }
  }
  if(isPossible) cout << "YES" << endl;
  else cout << "NO" << endl;
  return 0;
}


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

#define int long long
#define INF LLONG_MAX
#define _INF LLONG_MIN
#define endl '\n'

struct Grafo{
	vector<vector<int>> adj, adjDir, sccs, cost;
	vector<int> low, d, pai, sccCost;
	vector<bool> vis;
	map<pair<int, int>, bool> is_used;
	set<pair<pair<int, int>, int>> bridges;
	int tempo = 0;

	Grafo(int n){
		adj.resize(n);
		cost.resize(n);
		adjDir.resize(n);
		low.resize(n, INF);
		d.resize(n, INF);
		pai.resize(n, INF);
		vis.resize(n, false);
	}
};

void dfsBridges(int u, Grafo & grafo, vector<int> & ordem_vis){
	grafo.tempo++;
	grafo.d[u] = grafo.tempo;
	grafo.low[u] = grafo.tempo;
	grafo.vis[u] = true;
	for (int i = 0; i < grafo.adj[u].size(); i++){
		int v = grafo.adj[u][i];
		if (!grafo.is_used[make_pair(u, v)]){
			// monta grafo direcionado para calcular sccs
			grafo.adjDir[v].push_back(u);

			grafo.is_used[make_pair(u, v)] = true;
			grafo.is_used[make_pair(v, u)] = true;
		}
		if (!grafo.vis[v]){
			grafo.pai[v] = u;
			dfsBridges(v, grafo, ordem_vis);
			if(grafo.low[v] > grafo.d[u]){
				grafo.bridges.insert(make_pair(make_pair(u, v), grafo.cost[u][i]));
			}
			grafo.low[u] = min(grafo.low[u], grafo.low[v]);
		}
		else if (grafo.pai[u] != v){
			grafo.low[u] = min(grafo.low[u], grafo.d[v]);
		}
	}
	ordem_vis.push_back(u);
}

void dfsSCC(int u, Grafo & grafo){
	grafo.vis[u] = true;
	for(int i = 0; i < grafo.adjDir[u].size(); i++){
		int v = grafo.adjDir[u][i];
		if (!grafo.vis[v]){
			dfsSCC(v, grafo);
		}
	}
	grafo.sccs.back().push_back(u);
}

bool dfs(int a, int b, Grafo & grafo, bool f){
	grafo.vis[a] = true;
	if (grafo.sccCost[a]) f = true;
	if (a == b){
		// cout << "Chegou\n" << f << endl;
		return f;
	}
	// cout << "A = " << a << " " << grafo.adj[a].size() << endl;
	for (int i = 0; i < grafo.adj[a].size(); i++){
		int v = grafo.adj[a][i];
		// cout << v << endl;
		if (!grafo.vis[v]){
			if(dfs(v, b, grafo, f || grafo.cost[a][i])){
				return true;
			}
		}
	}
	return false;
}

signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
	int n, m, t = 1;
	cin >> n >> m;
	Grafo grafo = Grafo(n);
	for (int i = 0; i < m; i++){
		int x, y, w;
		cin >> x >> y >> w;
		x--; y--;

		grafo.adj[x].push_back(y);
		grafo.adj[y].push_back(x);

		grafo.cost[x].push_back(w);
		grafo.cost[y].push_back(w);
	}
	int a, b;
	cin >> a >> b;
	a--; b--;

	vector<int> ordem_vis;

	for (int i = 0; i < n; i++){
		if (!grafo.vis[i]){
			dfsBridges(i, grafo, ordem_vis);
		}
	}

	grafo.vis.assign(n, false);

	vector<int> new_id(n);

	for (int i = n - 1; i >= 0; i--){
		if (!grafo.vis[i]){
			grafo.sccs.push_back(vector<int> ());
			grafo.sccCost.push_back(0);
			dfsSCC(i, grafo);
			sort(grafo.sccs.back().begin(), grafo.sccs.back().end());
			for (int u : grafo.sccs.back()){
				new_id[u] = grafo.sccs.size() - 1;
				// cout << u << " " << new_id[u] << endl;
				for (int i = 0; i < grafo.adj[u].size(); i++){
					if (binary_search(grafo.sccs.back().begin(), grafo.sccs.back().end(), grafo.adj[u][i])){
						grafo.sccCost.back() += grafo.cost[u][i];
					}
				}
			}
			// cout << endl;
		}
	}

	for (int i = 0; i < n; i++){
		grafo.adj[i].clear();
		grafo.cost[i].clear();
	}
	grafo.adj.resize(grafo.sccs.size());
	grafo.cost.resize(grafo.sccs.size());
	grafo.vis.assign(grafo.sccs.size(), false);

	for (pair<pair<int, int>, int> p : grafo.bridges){
		int u, v;
		tie(u, v) = p.first;
		int cost_edge = p.second;
		// cout << "old: " << u << " " << v << " ";
		u = new_id[u]; v = new_id[v];
        // cout << "new: " << u << " " << v << endl;
		if (u != v){
			// cout << u << "-" << v << endl;
		    // cout << cost_edge << endl;
			grafo.adj[u].push_back(v);

			grafo.cost[u].push_back(cost_edge);

		}
	}

	a = new_id[a]; b = new_id[b];

	if (dfs(a, b, grafo, false)){
		cout << "YES\n";
		return 0;
	}
	grafo.vis.assign(grafo.sccs.size(), false);
	if (dfs(b, a, grafo, false)){
		cout << "YES\n";
		return 0;
	}
	else cout << "NO\n";

}


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

#define int long long
#define INF LLONG_MAX
#define _INF LLONG_MIN
#define endl '\n'

struct Grafo{
	vector<vector<int>> adj, adjDir, sccs, cost;
	vector<vector<bool>> is_used;
	vector<int> low, d, pai, sccCost;
	vector<bool> vis;
	set<pair<pair<int, int>, int>> bridges;
	int tempo = 0;

	Grafo(int n){
		is_used.resize(n);
		for (int i = 0; i < n; i++){
			is_used[i].assign(n, false);
		}
		adj.resize(n);
		cost.resize(n);
		adjDir.resize(n);
		low.resize(n, INF);
		d.resize(n, INF);
		pai.resize(n, INF);
		vis.resize(n, false);
	}
};

void dfsBridges(int u, Grafo & grafo, vector<int> & ordem_vis){
	grafo.tempo++;
	grafo.d[u] = grafo.tempo;
	grafo.low[u] = grafo.tempo;
	grafo.vis[u] = true;
	for (int i = 0; i < grafo.adj[u].size(); i++){
		int v = grafo.adj[u][i];
		if (!grafo.is_used[u][v]){
			// monta grafo direcionado para calcular sccs
			grafo.adjDir[u].push_back(v);

			grafo.is_used[u][v] = true;
			grafo.is_used[v][u] = true;
		}
		if (!grafo.vis[v]){
			grafo.pai[v] = u;
			dfsBridges(v, grafo, ordem_vis);
			if(grafo.low[v] > grafo.d[u]){
				grafo.bridges.insert(make_pair(make_pair(u, v), grafo.cost[u][i]));
			}
			grafo.low[u] = min(grafo.low[u], grafo.low[v]);
		}
		else if (grafo.pai[u] != v){
			grafo.low[u] = min(grafo.low[u], grafo.d[v]);
		}
	}
	ordem_vis.push_back(u);
}

void dfsSCC(int u, Grafo & grafo){
	grafo.vis[u] = true;
	for(int i = 0; i < grafo.adjDir[u].size(); i++){
		int v = grafo.adjDir[u][i];
		if (!grafo.vis[v]){
			dfsSCC(v, grafo);
		}
	}
	grafo.sccs.back().push_back(u);
}

bool dfs(int a, int b, Grafo & grafo, bool f){
	grafo.vis[a] = true;
	if (grafo.sccCost[a]) f = true;
	if (a == b){
		// cout << "Chegou\n" << f << endl;
		return f;
	}
	// cout << "A = " << a << " " << grafo.adj[a].size() << endl;
	for (int i = 0; i < grafo.adj[a].size(); i++){
		int v = grafo.adj[a][i];
		// cout << v << endl;
		if (!grafo.vis[v]){
			if(dfs(v, b, grafo, f || grafo.cost[a][i])){
				return true;
			}
		}
	}
	return false;
}

signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
	int n, m, t = 1;
	cin >> n >> m;
	Grafo grafo = Grafo(n);
	for (int i = 0; i < m; i++){
		int x, y, w;
		cin >> x >> y >> w;
		x--; y--;

		grafo.adj[x].push_back(y);
		grafo.adj[y].push_back(x);

		grafo.cost[x].push_back(w);
		grafo.cost[y].push_back(w);
	}
	int a, b;
	cin >> a >> b;
	a--; b--;

	vector<int> ordem_vis;

	for (int i = 0; i < n; i++){
		if (!grafo.vis[i]){
			dfsBridges(i, grafo, ordem_vis);
		}
	}

	grafo.vis.assign(n, false);

	vector<int> new_id(n);

	for (int i = n - 1; i >= 0; i--){
		if (!grafo.vis[i]){
			grafo.sccs.push_back(vector<int> ());
			grafo.sccCost.push_back(0);
			dfsSCC(i, grafo);
			sort(grafo.sccs.back().begin(), grafo.sccs.back().end());
			for (int u : grafo.sccs.back()){
				new_id[u] = grafo.sccs.size() - 1;
				// cout << u << " " << new_id[u] << endl;
				for (int i = 0; i < grafo.adj[u].size(); i++){
					if (binary_search(grafo.sccs.back().begin(), grafo.sccs.back().end(), grafo.adj[u][i])){
						grafo.sccCost.back() += grafo.cost[u][i];
					}
				}
			}
			// cout << endl;
		}
	}

	for (int i = 0; i < n; i++){
		grafo.adj[i].clear();
		grafo.cost[i].clear();
	}
	grafo.adj.resize(grafo.sccs.size());
	grafo.cost.resize(grafo.sccs.size());
	grafo.vis.assign(grafo.sccs.size(), false);

	for (pair<pair<int, int>, int> p : grafo.bridges){
		int u, v;
		tie(u, v) = p.first;
		int cost_edge = p.second;
		// cout << "old: " << u << " " << v << " ";
		u = new_id[u]; v = new_id[v];
        // cout << "new: " << u << " " << v << endl;
		if (u != v){
			// cout << u << "-" << v << endl;
		    // cout << cost_edge << endl;
			grafo.adj[u].push_back(v);

			grafo.cost[u].push_back(cost_edge);

		}
	}

	a = new_id[a]; b = new_id[b];

	if (dfs(a, b, grafo, false)){
		cout << "YES\n";
		return 0;
	}
	grafo.vis.assign(grafo.sccs.size(), false);
	if (dfs(b, a, grafo, false)){
		cout << "YES\n";
		return 0;
	}
	else cout << "NO\n";

}


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

#define int long long
#define INF LLONG_MAX
#define _INF LLONG_MIN
#define endl '\n'

struct Grafo{
	vector<vector<int>> adj, adjDir, sccs;
	vector<int> low, d, pai, sccCost;
	vector<bool> vis;
	map<pair<int, int>, bool> is_used;
	map<pair<int, int>, int> cost, costDir;
	set<pair<int, int>> bridges;
	int tempo = 0;

	Grafo(int n){
		adj.resize(n);
		adjDir.resize(n);
		low.resize(n, INF);
		d.resize(n, INF);
		pai.resize(n, INF);
		vis.resize(n, false);
	}
};

void dfsBridges(int u, Grafo & grafo, vector<int> & ordem_vis){
	grafo.tempo++;
	grafo.d[u] = grafo.tempo;
	grafo.low[u] = grafo.tempo;
	grafo.vis[u] = true;
	for (int v : grafo.adj[u]){
		if (!grafo.is_used[make_pair(u, v)]){
			// monta grafo direcionado para calcular sccs
			grafo.adjDir[u].push_back(v);
			grafo.costDir[make_pair(u, v)] = grafo.cost[make_pair(u, v)];

			grafo.is_used[make_pair(u, v)] = true;
			grafo.is_used[make_pair(v, u)] = true;
		}
		if (!grafo.vis[v]){
			grafo.pai[v] = u;

			dfsBridges(v, grafo, ordem_vis);
			if(grafo.low[v] > grafo.d[u]){
				grafo.bridges.emplace(u, v);
			}
			grafo.low[u] = min(grafo.low[u], grafo.low[v]);
		}
		else if (grafo.pai[u] != v){
			grafo.low[u] = min(grafo.low[u], grafo.d[v]);
		}
	}
	ordem_vis.push_back(u);
}

void dfsSCC(int u, Grafo & grafo){
	grafo.vis[u] = true;
	for(int v : grafo.adjDir[u]){
		if (!grafo.vis[v]){
			grafo.sccCost[grafo.sccCost.size() - 1] += grafo.costDir[make_pair(u, v)];
			dfsSCC(v, grafo);
		}
	}
	grafo.sccs[grafo.sccs.size() - 1].push_back(u);
}

bool dfs(int a, int b, vector<vector<int>> & adj, vector<vector<int>> & costE, vector<int> & costV, bool f){
	if (a == b){
		if (costV[a]) f = true;
		return f;
	}
	for (int i = 0; i < adj[a].size(); i++){
		int v = adj[a][i];
	    // cout << a << " " << v << " " << costE[a][i] << endl;
		f = costV[a] || costE[a][i];
		if(dfs(v, b, adj, costE, costV, f)){
			return true;
		}
	}
	return false;
}

signed main(){
	int n, m, t = 1;
	cin >> n >> m;
	Grafo grafo = Grafo(n);
	for (int i = 0; i < m; i++){
		int x, y, w;
		cin >> x >> y >> w;
		x--; y--;

		grafo.adj[x].push_back(y);
		grafo.adj[y].push_back(x);

		grafo.cost[make_pair(x, y)] = w;
		grafo.cost[make_pair(y, x)] = w;
	}

	int a, b;
	cin >> a >> b;
	a--; b--;

	vector<int> ordem_vis;

	for (int i = 0; i < n; i++){
		if (!grafo.vis[i]){
			dfsBridges(i, grafo, ordem_vis);
		}
	}

	grafo.vis.assign(n, false);

	map<int, int> new_id;

	for (int i = n - 1; i >= 0; i--){
		if (!grafo.vis[i]){
			grafo.sccs.push_back(vector<int> ());
			grafo.sccCost.push_back(0);
			dfsSCC(i, grafo);
			for (int v : grafo.sccs[grafo.sccs.size() - 1]){
				new_id[v] = grafo.sccs.size() - 1;
				// cout << v << " " << new_id[v] << " ";
			}
			// cout << endl;
		}
	}

	vector<vector<int>> adj_tree(n), cost_tree(n);

	// cout << endl;

	for (pair<int, int> p : grafo.bridges){
		int u, v;
		tie(u, v) = p;
		int cost_edge = grafo.costDir[make_pair(u, v)];
		//cout << "old: " << u << " " << v << " ";
		u = new_id[u]; v = new_id[v];
        //cout << "new: " << u << " " << v << endl;
		if (u != v){
		    // cout << cost_edge << endl;
			adj_tree[u].push_back(v);
			cost_tree[u].push_back(cost_edge);
		}
	}

	a = new_id[a]; b = new_id[b];

	if (dfs(a, b, adj_tree, cost_tree, grafo.sccCost, false)){
		cout << "YES\n";
	}
	else cout << "NO\n";

}


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

#define int long long
#define INF LLONG_MAX
#define _INF LLONG_MIN
#define endl '\n'

struct Grafo{
	vector<vector<int>> adj, cost, adjDir, costDir, sccs;
	vector<int> low, d, pai, sccCost;
	vector<bool> vis;
	map<pair<int, int>, bool> is_used;
	set<pair<int, int>> bridges;
	int tempo = 0;

	Grafo(int n){
		adj.resize(n);
		cost.resize(n);
		adjDir.resize(n);
		costDir.resize(n);
		low.resize(n, INF);
		d.resize(n, INF);
		pai.resize(n, INF);
		vis.resize(n, false);
	}
};

void dfsBridges(int u, Grafo & grafo, vector<int> & ordem_vis){
	grafo.tempo++;
	grafo.d[u] = grafo.tempo;
	grafo.low[u] = grafo.tempo;
	grafo.vis[u] = true;
	for (int v : grafo.adj[u]){
		if (!grafo.is_used[make_pair(u, v)]){
			// monta grafo direcionado para calcular sccs
			grafo.adjDir[u].push_back(v);
			grafo.costDir[u].push_back(grafo.cost[u][v]);

			grafo.is_used[make_pair(u, v)] = true;
			grafo.is_used[make_pair(v, u)] = true;
		}
		if (!grafo.vis[v]){
			grafo.pai[v] = u;

			dfsBridges(v, grafo, ordem_vis);
			if(grafo.low[v] > grafo.d[u]){
				grafo.bridges.emplace(u, v);
			}
			grafo.low[u] = min(grafo.low[u], grafo.low[v]);
		}
		else if (grafo.pai[u] != v){
			grafo.low[u] = min(grafo.low[u], grafo.d[v]);
		}
	}
	ordem_vis.push_back(u);
}

void dfsSCC(int u, Grafo & grafo){
	grafo.vis[u] = true;
	for(int v : grafo.adjDir[u]){
		if (!grafo.vis[v]){
			grafo.sccCost[grafo.sccCost.size() - 1] += grafo.costDir[u][v];
			dfsSCC(v, grafo);
		}
	}
	grafo.sccs[grafo.sccs.size() - 1].push_back(u);
}

bool dfs(int a, int b, vector<vector<int>> & adj, vector<vector<int>> & costE, vector<int> & costV, bool f){
	if (a == b){
		if (costV[a]) f = true;
		return f;
	}
	for (int v : adj[a]){
		f = costV[a] || costE[a][v];
		if(dfs(v, b, adj, costE, costV, f)){
			return true;
		}
	}
	return false;
}

signed main(){
	int n, m, t = 1;
	cin >> n >> m;
	Grafo grafo = Grafo(n);
	for (int i = 0; i < m; i++){
		int x, y, w;
		cin >> x >> y >> w;
		x--; y--;
		grafo.adj[x].push_back(y);
		grafo.adj[y].push_back(x);

		grafo.cost[x].push_back(w);
		grafo.cost[y].push_back(w);
	}

	int a, b;
	cin >> a >> b;
	a--; b--;

	vector<int> ordem_vis;

	for (int i = 0; i < n; i++){
		if (!grafo.vis[i]){
			dfsBridges(i, grafo, ordem_vis);
		}
	}

	grafo.vis.assign(n, false);

	map<int, int> new_id;

	for (int i = n - 1; i >= 0; i--){
		if (!grafo.vis[i]){
			grafo.sccs.push_back(vector<int> ());
			grafo.sccCost.push_back(0);
			dfsSCC(i, grafo);
			for (int v : grafo.sccs[grafo.sccs.size() - 1]){
				new_id[v] = grafo.sccs.size() - 1;
				// cout << v << " " << new_id[v] << " ";
			}
			// cout << endl;
		}
	}

	vector<vector<int>> adj_tree(n), cost_tree(n);

	// cout << endl;

	for (pair<int, int> p : grafo.bridges){
		int u, v;
		tie(u, v) = p;
		int cost_edge = grafo.costDir[u][v];
		// cout << "old: " << u << " " << v << " ";
		u = new_id[u]; v = new_id[v];
		// cout << "new: " << u << " " << v << endl;
		if (u != v){
			adj_tree[u].push_back(v);
			cost_tree[u].push_back(cost_edge);
		}
	}

	a = new_id[a]; b = new_id[b];

	if (dfs(a, b, adj_tree, cost_tree, grafo.sccCost, false)){
		cout << "YES\n";
	}
	else cout << "NO\n";

}


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

#define int long long
#define INF LLONG_MAX
#define _INF LLONG_MIN
#define endl '\n'

struct Grafo{
	vector<vector<int>> adj, adjDir, sccs, cost;
	vector<int> low, d, pai, sccCost;
	vector<bool> vis;
	map<pair<int, int>, bool> is_used;
	set<pair<pair<int, int>, int>> bridges;
	int tempo = 0;

	Grafo(int n){
		adj.resize(n);
		cost.resize(n);
		adjDir.resize(n);
		low.resize(n, INF);
		d.resize(n, INF);
		pai.resize(n, INF);
		vis.resize(n, false);
	}
};

void dfsBridges(int u, Grafo & grafo, vector<int> & ordem_vis){
	grafo.tempo++;
	grafo.d[u] = grafo.tempo;
	grafo.low[u] = grafo.tempo;
	grafo.vis[u] = true;
	for (int i = 0; i < grafo.adj[u].size(); i++){
		int v = grafo.adj[u][i];
		if (!grafo.is_used[make_pair(u, v)]){
			// monta grafo direcionado para calcular sccs
			grafo.adjDir[u].push_back(v);

			grafo.is_used[make_pair(u, v)] = true;
			grafo.is_used[make_pair(v, u)] = true;
		}
		if (!grafo.vis[v]){
			grafo.pai[v] = u;
			dfsBridges(v, grafo, ordem_vis);
			if(grafo.low[v] > grafo.d[u]){
				grafo.bridges.insert(make_pair(make_pair(u, v), grafo.cost[u][i]));
			}
			grafo.low[u] = min(grafo.low[u], grafo.low[v]);
		}
		else if (grafo.pai[u] != v){
			grafo.low[u] = min(grafo.low[u], grafo.d[v]);
		}
	}
	ordem_vis.push_back(u);
}

void dfsSCC(int u, Grafo & grafo){
	grafo.vis[u] = true;
	for(int i = 0; i < grafo.adjDir[u].size(); i++){
		int v = grafo.adjDir[u][i];
		if (!grafo.vis[v]){
			dfsSCC(v, grafo);
		}
	}
	grafo.sccs.back().push_back(u);
}

bool dfs(int a, int b, Grafo & grafo, bool f){
	grafo.vis[a] = true;
	if (grafo.sccCost[a]) f = true;
	if (a == b){
		// cout << "Chegou\n" << f << endl;
		return f;
	}
	// cout << "A = " << a << " " << grafo.adj[a].size() << endl;
	for (int i = 0; i < grafo.adj[a].size(); i++){
		int v = grafo.adj[a][i];
		// cout << v << endl;
		if (!grafo.vis[v]){
			if(dfs(v, b, grafo, f || grafo.cost[a][i])){
				return true;
			}
		}
	}
	return false;
}

signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
	int n, m, t = 1;
	cin >> n >> m;
	Grafo grafo = Grafo(n);
	for (int i = 0; i < m; i++){
		int x, y, w;
		cin >> x >> y >> w;
		x--; y--;

		grafo.adj[x].push_back(y);
		grafo.adj[y].push_back(x);

		grafo.cost[x].push_back(w);
		grafo.cost[y].push_back(w);
	}
	int a, b;
	cin >> a >> b;
	a--; b--;

	vector<int> ordem_vis;

	for (int i = 0; i < n; i++){
		if (!grafo.vis[i]){
			dfsBridges(i, grafo, ordem_vis);
		}
	}

	grafo.vis.assign(n, false);

	vector<int> new_id(n);

	for (int i = n - 1; i >= 0; i--){
		if (!grafo.vis[i]){
			grafo.sccs.push_back(vector<int> ());
			grafo.sccCost.push_back(0);
			dfsSCC(i, grafo);
			sort(grafo.sccs.back().begin(), grafo.sccs.back().end());
			for (int u : grafo.sccs.back()){
				new_id[u] = grafo.sccs.size() - 1;
				// cout << u << " " << new_id[u] << endl;
				for (int i = 0; i < grafo.adj[u].size(); i++){
					if (binary_search(grafo.sccs.back().begin(), grafo.sccs.back().end(), grafo.adj[u][i])){
						grafo.sccCost.back() += grafo.cost[u][i];
					}
				}
			}
			// cout << endl;
		}
	}

	Grafo grafo2 = Grafo(grafo.sccs.size());

	for (pair<pair<int, int>, int> p : grafo.bridges){
		int u, v;
		tie(u, v) = p.first;
		int cost_edge = p.second;
		// cout << "old: " << u << " " << v << " ";
		u = new_id[u]; v = new_id[v];
        // cout << "new: " << u << " " << v << endl;
		if (u != v){
			// cout << u << "-" << v << endl;
		    // cout << cost_edge << endl;
			grafo2.adj[u].push_back(v);
			grafo2.cost[u].push_back(cost_edge);

		}
	}

	if (dfs(a, b, grafo2, false)){
		cout << "YES\n";
		return 0;
	}
	grafo2.vis.assign(grafo.sccs.size(), false);
	if (dfs(b, a, grafo2, false)){
		cout << "YES\n";
		return 0;
	}
	else cout << "NO\n";

}


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

#define int long long
#define INF LLONG_MAX
#define _INF LLONG_MIN
#define endl '\n'

struct Grafo{
	vector<vector<int>> adj, cost, usable;
	vector<int> low, d, pai;
	vector<bool> vis, vtxValue;
	vector<pair<int, int>> bridges;
	vector<int> cost_bridge;
	int tempo = 0;

	Grafo(int n){
		adj.resize(n);
		usable = vector<vector<int>> (n, vector<int> (n, 0));
		cost.resize(n);
		low.resize(n, INF);
		d.resize(n, INF);
		pai.resize(n, INF);
		vis.resize(n, false);
		vtxValue.resize(n, false);
	}
};

int dfsBridges(int u, Grafo & g){
	g.tempo++;
	g.low[u] = g.tempo;
	g.d[u] = g.tempo;
	g.vis[u] = true;
	for (int i = 0; i < g.adj[u].size(); i++){
		int v = g.adj[u][i];
		if (!g.vis[v]){
			g.pai[v] = u;
			dfsBridges(v, g);
			if (g.low[v] > g.d[u]){
				g.usable[u][v] = 0;
				g.usable[v][u] = 0;
				g.bridges.emplace_back(u, v);
				g.bridges.emplace_back(v, u);
				g.cost_bridge.push_back(g.cost[u][i]);
				g.cost_bridge.push_back(g.cost[u][i]);
			}
			g.low[u] = min(g.low[u], g.low[v]);
		}
		else if (g.pai[u] != v){
			g.low[u] = min(g.low[u], g.d[v]);
		}
	}
}

void dfsCompConex(int u, Grafo & g, vector<int> & compConex){
	g.vis[u] = true;
	for (int v : g.adj[u]){
		if (!g.vis[v] && g.usable[u][v]){
			dfsCompConex(v, g, compConex);
		}
	}
	compConex.push_back(u);
}

bool dfs(int a, int b, Grafo & g, bool f){
	g.vis[a] = true;
	if (g.vtxValue[a]) f = true;
	if (a == b){
		// cout << "Chegou\n" << f << endl;
		return f;
	}
	for (int i = 0; i < g.adj[a].size(); i++){
		int v = g.adj[a][i];
		if (!g.vis[v]){
			// cout << a << " " << v << " " << g.cost[a][i] << endl;
			if(dfs(v, b, g, f || g.cost[a][i])){
				return true;
			}
		}
	}
	return false;
}

signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
	int n, m, t = 1;
	cin >> n >> m;
	Grafo g = Grafo(n);
	for (int i = 0; i < m; i++){
		int x, y, w;
		cin >> x >> y >> w;
		x--; y--;

		g.usable[x][y] = 1;
		g.usable[y][x] = 1;

		g.adj[x].push_back(y);
		g.adj[y].push_back(x);

		g.cost[x].push_back(w);
		g.cost[y].push_back(w);
	}
	int a, b;
	cin >> a >> b;
	a--; b--;

	for (int i = 0; i < n; i++){
		if (!g.vis[i]){
			dfsBridges(i, g);
		}
	}

	g.vis.assign(n, false);

	vector<int> new_id(n);

	int id = 0;

	for (int i = 0; i < n; i++){
		if (!g.vis[i]){
			vector<int> compConex;
			dfsCompConex(i, g, compConex);
			sort(compConex.begin(), compConex.end());
			for (int u : compConex){
				new_id[u] = id;
				// cout << u << " " << id << endl;
				for (int i = 0; i < g.adj[u].size(); i++){
					if (binary_search(compConex.begin(), compConex.end(), g.adj[u][i])){
						g.vtxValue[id] = g.vtxValue[id] || (g.cost[u][i] > 0);
					}
				}
			}
			id++;
		}
	}

	// cout << g.vtxValue[1] << endl;

	for (int i = 0; i < n; i++){
		g.adj[i].clear();
		g.cost[i].clear();
	}
	g.adj.resize(id);
	g.cost.resize(id);
	g.vis.assign(id, false);

	for (int i = 0; i < g.bridges.size(); i++){
		int u, v;
		tie(u, v) = g.bridges[i];
		// cout << u << "-" << v << "-" << g.cost_bridge[i] << endl;
		u = new_id[u]; v = new_id[v];
		if (u != v){
			g.adj[u].push_back(v);
			g.cost[u].push_back(g.cost_bridge[i]);
		}
	}

	a = new_id[a]; b = new_id[b];

	if (dfs(a, b, g, false)){
		cout << "YES\n";
		return 0;
	}
	// g.vis.assign(id, false);
	// if (dfs(b, a, g, false)){
	// 	cout << "YES\n";
	// 	return 0;
	// }
	else cout << "NO\n";

}


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

// #define int long long
#define INF INT_MAX
#define _INF INT_MIN
#define endl '\n'

struct Grafo{
	vector<vector<int>> adj, adjDir, sccs, cost, costDir;
	vector<int> low, d, pai, sccCost;
	vector<bool> vis;
	map<pair<int, int>, bool> is_used;
	set<pair<pair<int, int>, int>> bridges;
	int tempo = 0;

	Grafo(int n){
		adj.resize(n);
		cost.resize(n);
		adjDir.resize(n);
		costDir.resize(n);
		low.resize(n, INF);
		d.resize(n, INF);
		pai.resize(n, INF);
		vis.resize(n, false);
	}
};

void dfsBridges(int u, Grafo & grafo, vector<int> & ordem_vis){
	grafo.tempo++;
	grafo.d[u] = grafo.tempo;
	grafo.low[u] = grafo.tempo;
	grafo.vis[u] = true;
	for (int i = 0; i < grafo.adj[u].size(); i++){
		int v = grafo.adj[u][i];
		if (!grafo.is_used[make_pair(u, v)]){
			// monta grafo direcionado para calcular sccs
			grafo.adjDir[u].push_back(v);
			grafo.costDir[u].push_back(grafo.cost[u][i]);

			grafo.is_used[make_pair(u, v)] = true;
			grafo.is_used[make_pair(v, u)] = true;
		}
		if (!grafo.vis[v]){
			grafo.pai[v] = u;
			dfsBridges(v, grafo, ordem_vis);
			if(grafo.low[v] > grafo.d[u]){
				grafo.bridges.insert(make_pair(make_pair(u, v), grafo.cost[u][i]));
			}
			grafo.low[u] = min(grafo.low[u], grafo.low[v]);
		}
		else if (grafo.pai[u] != v){
			grafo.low[u] = min(grafo.low[u], grafo.d[v]);
		}
	}
	ordem_vis.push_back(u);
}

void dfsSCC(int u, Grafo & grafo){
	grafo.vis[u] = true;
	for(int i = 0; i < grafo.adjDir[u].size(); i++){
		int v = grafo.adjDir[u][i];
		if (!grafo.vis[v]){
			dfsSCC(v, grafo);
		}
	}
	grafo.sccs.back().push_back(u);
}

bool dfs(int a, int b, Grafo & grafo, bool f){
	grafo.vis[a] = true;
	if (grafo.sccCost[a]) f = true;
	if (a == b){
		// cout << "Chegou\n" << f << endl;
		return f;
	}
	// cout << "A = " << a << " " << grafo.adj[a].size() << endl;
	for (int i = 0; i < grafo.adj[a].size(); i++){
		int v = grafo.adj[a][i];
		// cout << v << endl;
		if (!grafo.vis[v]){
			if(dfs(v, b, grafo, f || grafo.cost[a][i])){
				return true;
			}
		}
	}
	return false;
}

signed main(){
    // ios::sync_with_stdio(false);
    // cin.tie(0);
    // cout.tie(0);
	int n, m, t = 1;
	cin >> n >> m;
	Grafo grafo = Grafo(n);
	for (int i = 0; i < m; i++){
		int x, y, w;
		cin >> x >> y >> w;
		x--; y--;

		grafo.adj[x].push_back(y);
		grafo.adj[y].push_back(x);

		grafo.cost[x].push_back(w);
		grafo.cost[y].push_back(w);
	}
	int a, b;
	cin >> a >> b;
	a--; b--;

	vector<int> ordem_vis;

	for (int i = 0; i < n; i++){
		if (!grafo.vis[i]){
			dfsBridges(i, grafo, ordem_vis);
		}
	}

	grafo.vis.assign(n, false);

	vector<int> new_id(n);

	for (int i = n - 1; i >= 0; i--){
		if (!grafo.vis[i]){
			grafo.sccs.push_back(vector<int> ());
			grafo.sccCost.push_back(0);
			dfsSCC(i, grafo);
			sort(grafo.sccs.back().begin(), grafo.sccs.back().end());
			for (int u : grafo.sccs.back()){
				new_id[u] = grafo.sccs.size() - 1;
				// cout << u << " " << new_id[u] << endl;
				for (int i = 0; i < grafo.adj[u].size(); i++){
					if (binary_search(grafo.sccs.back().begin(), grafo.sccs.back().end(), grafo.adj[u][i])){
						grafo.sccCost.back() += grafo.cost[u][i];
					}
				}
			}
			// cout << endl;
		}
	}

	for (int i = 0; i < n; i++){
		grafo.adj[i].clear();
		grafo.cost[i].clear();
	}
	grafo.adj.resize(grafo.sccs.size());
	grafo.cost.resize(grafo.sccs.size());
	grafo.vis.assign(grafo.sccs.size(), false);

	for (pair<pair<int, int>, int> p : grafo.bridges){
		int u, v;
		tie(u, v) = p.first;
		int cost_edge = p.second;
		// cout << "old: " << u << " " << v << " ";
		u = new_id[u]; v = new_id[v];
        // cout << "new: " << u << " " << v << endl;
		if (u != v){
			// cout << u << "-" << v << endl;
		    // cout << cost_edge << endl;
			grafo.adj[u].push_back(v);
			grafo.adj[v].push_back(u);
			grafo.cost[u].push_back(cost_edge);
			grafo.cost[v].push_back(cost_edge);
		}
	}

	a = new_id[a]; b = new_id[b];

	if (dfs(a, b, grafo, false)){
		cout << "YES\n";
	}
	else cout << "NO\n";

}


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

// #define int long long
#define INF LLONG_MAX
#define _INF LLONG_MIN
#define endl '\n'

struct Grafo{
	vector<vector<int>> adj, adjDir, sccs;
	vector<int> low, d, pai, sccCost;
	vector<bool> vis;
	map<pair<int, int>, bool> is_used;
	map<pair<int, int>, int> cost, costDir;
	set<pair<int, int>> bridges;
	int tempo = 0;

	Grafo(int n){
		adj.resize(n);
		adjDir.resize(n);
		low.resize(n, INF);
		d.resize(n, INF);
		pai.resize(n, INF);
		vis.resize(n, false);
	}
};

void dfsBridges(int u, Grafo & grafo, vector<int> & ordem_vis){
	grafo.tempo++;
	grafo.d[u] = grafo.tempo;
	grafo.low[u] = grafo.tempo;
	grafo.vis[u] = true;
	for (int v : grafo.adj[u]){
		if (!grafo.is_used[make_pair(u, v)]){
			// monta grafo direcionado para calcular sccs
			grafo.adjDir[u].push_back(v);
			grafo.costDir[make_pair(u, v)] = grafo.cost[make_pair(u, v)];

			grafo.is_used[make_pair(u, v)] = true;
			grafo.is_used[make_pair(v, u)] = true;
		}
		if (!grafo.vis[v]){
			grafo.pai[v] = u;
			dfsBridges(v, grafo, ordem_vis);
			if(grafo.low[v] > grafo.d[u]){
				grafo.bridges.emplace(u, v);
			}
			grafo.low[u] = min(grafo.low[u], grafo.low[v]);
		}
		else if (grafo.pai[u] != v){
			grafo.low[u] = min(grafo.low[u], grafo.d[v]);
		}
	}
	ordem_vis.push_back(u);
}

void dfsSCC(int u, Grafo & grafo){
	grafo.vis[u] = true;
	for(int v : grafo.adjDir[u]){
		if (!grafo.vis[v]){
			dfsSCC(v, grafo);
		}
	}
	grafo.sccs[grafo.sccs.size() - 1].push_back(u);
}

bool dfs(int a, int b, vector<vector<int>> & adj, map<pair<int,int>, int> & costE, vector<int> & costV, vector<bool> & vis, bool f){
	vis[a] = true;
	if (costV[a]) f = true;
	if (a == b){
		// cout << "Chegou\n" << f << endl;
		return f;
	}
	// cout << "A = " << a << " " << adj[a].size() << endl;
	for (int i = 0; i < adj[a].size(); i++){
		int v = adj[a][i];
		if (!vis[v]){
			if(dfs(v, b, adj, costE, costV, vis, f || costE[make_pair(a, v)])){
				return true;
			}
		}
	}
	return false;
}

signed main(){
	int n, m, t = 1;
	cin >> n >> m;
	Grafo grafo = Grafo(n);
	for (int i = 0; i < m; i++){
		int x, y, w;
		cin >> x >> y >> w;
		x--; y--;

		grafo.adj[x].push_back(y);
		grafo.adj[y].push_back(x);

		grafo.cost[make_pair(x, y)] = w;
		grafo.cost[make_pair(y, x)] = w;
	}

	int a, b;
	cin >> a >> b;
	a--; b--;

	vector<int> ordem_vis;

	for (int i = 0; i < n; i++){
		if (!grafo.vis[i]){
			dfsBridges(i, grafo, ordem_vis);
		}
	}

	grafo.vis.assign(n, false);

	map<int, int> new_id;

	for (int i = n - 1; i >= 0; i--){
		if (!grafo.vis[i]){
			grafo.sccs.push_back(vector<int> ());
			grafo.sccCost.push_back(0);
			dfsSCC(i, grafo);
			for (int v : grafo.sccs[grafo.sccs.size() - 1]){
				new_id[v] = grafo.sccs.size() - 1;
				// cout << v << " " << new_id[v] << endl;
			}
			for (int u : grafo.sccs[grafo.sccs.size() - 1]){
				for (int v : grafo.sccs[grafo.sccs.size() - 1]){
					// cout << u << " " << v << " " << grafo.cost[make_pair(u, v)] << endl;
					grafo.sccCost[grafo.sccCost.size() - 1] += grafo.cost[make_pair(u, v)];
					grafo.sccCost[grafo.sccCost.size() - 1] += grafo.cost[make_pair(v, u)];
				}
			}
			// cout << endl;
		}
	}

	vector<vector<int>> adj_tree(grafo.sccs.size()), adj_treeT(grafo.sccs.size());
	map<pair<int,int>, int> cost_tree, cost_treeT;
	vector<bool> vis(n, false);

	// cout << grafo.sccCost[1] << endl;

	for (pair<int, int> p : grafo.bridges){
		int u, v;
		tie(u, v) = p;
		int cost_edge = grafo.costDir[make_pair(u, v)];
		// cout << "old: " << u << " " << v << " ";
		u = new_id[u]; v = new_id[v];
        // cout << "new: " << u << " " << v << endl;
		if (u != v){
			// cout << u << "-" << v << endl;
		    // cout << cost_edge << endl;
			adj_tree[u].push_back(v);
			adj_tree[v].push_back(u);
			cost_tree[make_pair(u, v)] = cost_edge;
			cost_tree[make_pair(v, u)] = cost_edge;
		}
	}

	a = new_id[a]; b = new_id[b];

	if (dfs(a, b, adj_tree, cost_tree, grafo.sccCost, vis, false)){
		cout << "YES\n";
	}
	else cout << "NO\n";

}


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

#define int long long
#define INF LLONG_MAX
#define _INF LLONG_MIN
#define endl '\n'

struct Grafo{
	vector<vector<int>> adj, cost;
	vector<int> low, d, pai;
	vector<bool> vis, vtxValue;
	set<pair<pair<int, int>, int>> bridges;
	int tempo = 0;

	Grafo(int n){
		adj.resize(n);
		cost.resize(n);
		low.resize(n, INF);
		d.resize(n, INF);
		pai.resize(n, INF);
		vis.resize(n, false);
		vtxValue.resize(n, false);
	}
};

int dfsBridges(int u, Grafo & g){
	g.tempo++;
	g.low[u] = g.tempo;
	g.d[u] = g.tempo;
	g.vis[u] = true;
	for (int i = 0; i < g.adj[u].size(); i++){
		int v = g.adj[u][i];
		if (!g.vis[v]){
			g.pai[v] = u;
			dfsBridges(v, g);
			if (g.low[v] > g.d[u]){
				g.bridges.emplace(make_pair(min(u, v), max(u, v)), g.cost[u][i]);
			}
			g.low[u] = min(g.low[u], g.low[v]);
		}
		else if (g.pai[u] != v){
			g.low[u] = min(g.low[u], g.d[v]);
		}
	}
}

void dfsCompConex(int u, Grafo & g, vector<int> & compConex){
	g.vis[u] = true;
	for (int v : g.adj[u]){
		if (!g.vis[v]){
			dfsCompConex(v, g, compConex);
		}
	}
	compConex.push_back(u);
}

bool dfs(int a, int b, Grafo & g, bool f){
	g.vis[a] = true;
	if (g.vtxValue[a]) f = true;
	if (a == b){
		// cout << "Chegou\n" << f << endl;
		return f;
	}
	for (int i = 0; i < g.adj[a].size(); i++){
		int v = g.adj[a][i];
		if (!g.vis[v]){
			if(dfs(v, b, g, f || g.cost[a][i])){
				return true;
			}
		}
	}
	return false;
}

signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
	int n, m, t = 1;
	cin >> n >> m;
	Grafo g = Grafo(n);
	for (int i = 0; i < m; i++){
		int x, y, w;
		cin >> x >> y >> w;
		x--; y--;

		g.adj[x].push_back(y);
		g.adj[y].push_back(x);

		g.cost[x].push_back(w);
		g.cost[y].push_back(w);
	}
	int a, b;
	cin >> a >> b;
	a--; b--;

	for (int i = 0; i < n; i++){
		if (!g.vis[i]){
			dfsBridges(i, g);
		}
	}

	g.vis.assign(n, false);

	vector<int> new_id(n);

	int id = 0;

	for (int i = 0; i < n; i++){
		if (!g.vis[i]){
			vector<int> compConex;
			dfsCompConex(i, g, compConex);
			sort(compConex.begin(), compConex.end());
			for (int u : compConex){
				new_id[u] = id;
				for (int i = 0; i < g.adj[u].size(); i++){
					if (binary_search(compConex.begin(), compConex.end(), g.adj[u][i])){
						g.vtxValue[id] = true;
						break;
					}
				}
			}
			id++;
		}
	}

	for (int i = 0; i < n; i++){
		g.adj[i].clear();
		g.cost[i].clear();
	}
	g.adj.resize(id);
	g.cost.resize(id);
	g.vis.assign(id, false);

	for (pair<pair<int, int>, int> p : g.bridges){
		int u, v;
		tie(u, v) = p.first;
		int cost_edge = p.second;
		u = new_id[u]; v = new_id[v];
		if (u != v){
			g.adj[u].push_back(v);
			g.cost[u].push_back(cost_edge);
		}
	}

	a = new_id[a]; b = new_id[b];

	if (dfs(a, b, g, false)){
		cout << "YES\n";
		return 0;
	}
	g.vis.assign(id, false);
	if (dfs(b, a, g, false)){
		cout << "YES\n";
		return 0;
	}
	else cout << "NO\n";

}


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

#define int long long
#define INF LLONG_MAX
#define _INF LLONG_MIN
#define endl '\n'

struct Grafo{
	vector<vector<int>> adj, adjDir, sccs;
	vector<int> low, d, pai, sccCost;
	vector<bool> vis;
	map<pair<int, int>, bool> is_used;
	map<pair<int, int>, int> cost, costDir;
	set<pair<int, int>> bridges;
	int tempo = 0;

	Grafo(int n){
		adj.resize(n);
		adjDir.resize(n);
		low.resize(n, INF);
		d.resize(n, INF);
		pai.resize(n, INF);
		vis.resize(n, false);
	}
};

void dfsBridges(int u, Grafo & grafo, vector<int> & ordem_vis){
	grafo.tempo++;
	grafo.d[u] = grafo.tempo;
	grafo.low[u] = grafo.tempo;
	grafo.vis[u] = true;
	for (int v : grafo.adj[u]){
		if (!grafo.is_used[make_pair(u, v)]){
			// monta grafo direcionado para calcular sccs
			grafo.adjDir[u].push_back(v);
			grafo.costDir[make_pair(u, v)] = grafo.cost[make_pair(u, v)];

			grafo.is_used[make_pair(u, v)] = true;
			grafo.is_used[make_pair(v, u)] = true;
		}
		if (!grafo.vis[v]){
			grafo.pai[v] = u;
			dfsBridges(v, grafo, ordem_vis);
			if(grafo.low[v] > grafo.d[u]){
				grafo.bridges.emplace(u, v);
			}
			grafo.low[u] = min(grafo.low[u], grafo.low[v]);
		}
		else if (grafo.pai[u] != v){
			grafo.low[u] = min(grafo.low[u], grafo.d[v]);
		}
	}
	ordem_vis.push_back(u);
}

void dfsSCC(int u, Grafo & grafo){
	grafo.vis[u] = true;
	for(int v : grafo.adjDir[u]){
		if (!grafo.vis[v]){
			dfsSCC(v, grafo);
		}
	}
	grafo.sccs[grafo.sccs.size() - 1].push_back(u);
}

bool dfs(int a, int b, vector<vector<int>> & adj, vector<vector<int>> & costE, vector<int> & costV, bool f){
	if (a == b){
		if (costV[a]) f = true;
		return f;
	}
	for (int i = 0; i < adj[a].size(); i++){
		int v = adj[a][i];
	    // cout << a << " " << v << " " << costE[a][i] << endl;
		f = costV[a] || costE[a][i];
		if(dfs(v, b, adj, costE, costV, f)){
			return true;
		}
	}
	return false;
}

signed main(){
	int n, m, t = 1;
	cin >> n >> m;
	Grafo grafo = Grafo(n);
	for (int i = 0; i < m; i++){
		int x, y, w;
		cin >> x >> y >> w;
		x--; y--;

		grafo.adj[x].push_back(y);
		grafo.adj[y].push_back(x);

		grafo.cost[make_pair(x, y)] = w;
		grafo.cost[make_pair(y, x)] = w;
	}

	int a, b;
	cin >> a >> b;
	a--; b--;

	vector<int> ordem_vis;

	for (int i = 0; i < n; i++){
		if (!grafo.vis[i]){
			dfsBridges(i, grafo, ordem_vis);
		}
	}

	grafo.vis.assign(n, false);

	map<int, int> new_id;

	for (int i = n - 1; i >= 0; i--){
		if (!grafo.vis[i]){
			grafo.sccs.push_back(vector<int> ());
			grafo.sccCost.push_back(0);
			dfsSCC(i, grafo);
			for (int v : grafo.sccs[grafo.sccs.size() - 1]){
				new_id[v] = grafo.sccs.size() - 1;
			}
			for (int u : grafo.sccs[grafo.sccs.size() - 1]){
				for (int v : grafo.sccs[grafo.sccs.size() - 1]){
					grafo.sccCost[grafo.sccCost.size() - 1] += grafo.cost[make_pair(u, v)];
				}
			}
			// cout << endl;
		}
	}

	vector<vector<int>> adj_tree(n), cost_tree(n);

	// cout << grafo.sccCost[0] << endl;

	for (pair<int, int> p : grafo.bridges){
		int u, v;
		tie(u, v) = p;
		int cost_edge = grafo.costDir[make_pair(u, v)];
		//cout << "old: " << u << " " << v << " ";
		u = new_id[u]; v = new_id[v];
        //cout << "new: " << u << " " << v << endl;
		if (u != v){
		    // cout << cost_edge << endl;
			adj_tree[u].push_back(v);
			cost_tree[u].push_back(cost_edge);
		}
	}

	a = new_id[a]; b = new_id[b];

	if (dfs(a, b, adj_tree, cost_tree, grafo.sccCost, false)){
		cout << "YES\n";
	}
	else cout << "NO\n";

}


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

#define int long long
#define INF LLONG_MAX
#define _INF LLONG_MIN
#define endl '\n'

struct Grafo{
	vector<vector<int>> adj, adjDir, sccs, cost, costDir;
	vector<int> low, d, pai, sccCost;
	vector<bool> vis;
	map<pair<int, int>, bool> is_used;
	set<pair<pair<int, int>, int>> bridges;
	int tempo = 0;

	Grafo(int n){
		adj.resize(n);
		cost.resize(n);
		adjDir.resize(n);
		costDir.resize(n);
		low.resize(n, INF);
		d.resize(n, INF);
		pai.resize(n, INF);
		vis.resize(n, false);
	}
};

void dfsBridges(int u, Grafo & grafo, vector<int> & ordem_vis){
	grafo.tempo++;
	grafo.d[u] = grafo.tempo;
	grafo.low[u] = grafo.tempo;
	grafo.vis[u] = true;
	for (int i = 0; i < grafo.adj[u].size(); i++){
		int v = grafo.adj[u][i];
		if (!grafo.is_used[make_pair(u, v)]){
			// monta grafo direcionado para calcular sccs
			grafo.adjDir[u].push_back(v);
			grafo.costDir[u].push_back(grafo.cost[u][i]);

			grafo.is_used[make_pair(u, v)] = true;
			grafo.is_used[make_pair(v, u)] = true;
		}
		if (!grafo.vis[v]){
			grafo.pai[v] = u;
			dfsBridges(v, grafo, ordem_vis);
			if(grafo.low[v] > grafo.d[u]){
				grafo.bridges.insert(make_pair(make_pair(u, v), grafo.cost[u][i]));
			}
			grafo.low[u] = min(grafo.low[u], grafo.low[v]);
		}
		else if (grafo.pai[u] != v){
			grafo.low[u] = min(grafo.low[u], grafo.d[v]);
		}
	}
	ordem_vis.push_back(u);
}

void dfsSCC(int u, Grafo & grafo){
	grafo.vis[u] = true;
	for(int i = 0; i < grafo.adjDir[u].size(); i++){
		int v = grafo.adjDir[u][i];
		if (!grafo.vis[v]){
			dfsSCC(v, grafo);
		}
	}
	grafo.sccs.back().push_back(u);
}

bool dfs(int a, int b, Grafo & grafo, bool f){
	grafo.vis[a] = true;
	if (grafo.sccCost[a]) f = true;
	if (a == b){
		// cout << "Chegou\n" << f << endl;
		return f;
	}
	// cout << "A = " << a << " " << grafo.adj[a].size() << endl;
	for (int i = 0; i < grafo.adj[a].size(); i++){
		int v = grafo.adj[a][i];
		// cout << v << endl;
		if (!grafo.vis[v]){
			if(dfs(v, b, grafo, f || grafo.cost[a][i])){
				return true;
			}
		}
	}
	return false;
}

signed main(){
    // ios::sync_with_stdio(false);
    // cin.tie(0);
    // cout.tie(0);
	int n, m, t = 1;
	cin >> n >> m;
	Grafo grafo = Grafo(n);
	for (int i = 0; i < m; i++){
		int x, y, w;
		cin >> x >> y >> w;
		x--; y--;

		grafo.adj[x].push_back(y);
		grafo.adj[y].push_back(x);

		grafo.cost[x].push_back(w);
		grafo.cost[y].push_back(w);
	}
	int a, b;
	cin >> a >> b;
	a--; b--;

	vector<int> ordem_vis;

	for (int i = 0; i < n; i++){
		if (!grafo.vis[i]){
			dfsBridges(i, grafo, ordem_vis);
		}
	}

	grafo.vis.assign(n, false);

	vector<int> new_id(n);

	for (int i = n - 1; i >= 0; i--){
		if (!grafo.vis[i]){
			grafo.sccs.push_back(vector<int> ());
			grafo.sccCost.push_back(0);
			dfsSCC(i, grafo);
			sort(grafo.sccs.back().begin(), grafo.sccs.back().end());
			for (int u : grafo.sccs.back()){
				new_id[u] = grafo.sccs.size() - 1;
				// cout << u << " " << new_id[u] << endl;
				for (int i = 0; i < grafo.adj[u].size(); i++){
					if (binary_search(grafo.sccs.back().begin(), grafo.sccs.back().end(), grafo.adj[u][i])){
						grafo.sccCost.back() += grafo.cost[u][i];
					}
				}
			}
			// cout << endl;
		}
	}

	for (int i = 0; i < n; i++){
		grafo.adj[i].clear();
		grafo.cost[i].clear();
	}
	grafo.adj.resize(grafo.sccs.size());
	grafo.cost.resize(grafo.sccs.size());
	grafo.vis.assign(grafo.sccs.size(), false);

	for (pair<pair<int, int>, int> p : grafo.bridges){
		int u, v;
		tie(u, v) = p.first;
		int cost_edge = p.second;
		// cout << "old: " << u << " " << v << " ";
		u = new_id[u]; v = new_id[v];
        // cout << "new: " << u << " " << v << endl;
		if (u != v){
			// cout << u << "-" << v << endl;
		    // cout << cost_edge << endl;
			grafo.adj[u].push_back(v);
			grafo.adj[v].push_back(u);
			grafo.cost[u].push_back(cost_edge);
			grafo.cost[v].push_back(cost_edge);
		}
	}

	a = new_id[a]; b = new_id[b];

	if (dfs(a, b, grafo, false)){
		cout << "YES\n";
	}
	else cout << "NO\n";

}


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

#define int long long
#define INF LLONG_MAX
#define _INF LLONG_MIN
#define endl '\n'

struct Grafo{
	vector<vector<int>> adj, adjDir, sccs, cost;
	vector<int> low, d, pai, sccCost;
	vector<bool> vis;
	map<pair<int, int>, bool> is_used;
	set<pair<pair<int, int>, int>> bridges;
	int tempo = 0;

	Grafo(int n){
		adj.resize(n);
		cost.resize(n);
		adjDir.resize(n);
		low.resize(n, INF);
		d.resize(n, INF);
		pai.resize(n, INF);
		vis.resize(n, false);
	}
};

void dfsBridges(int u, Grafo & grafo, vector<int> & ordem_vis){
	grafo.tempo++;
	grafo.d[u] = grafo.tempo;
	grafo.low[u] = grafo.tempo;
	grafo.vis[u] = true;
	for (int i = 0; i < grafo.adj[u].size(); i++){
		int v = grafo.adj[u][i];
		if (!grafo.is_used[make_pair(u, v)]){
			// monta grafo direcionado para calcular sccs
			grafo.adjDir[u].push_back(v);

			grafo.is_used[make_pair(u, v)] = true;
			grafo.is_used[make_pair(v, u)] = true;
		}
		if (!grafo.vis[v]){
			grafo.pai[v] = u;
			dfsBridges(v, grafo, ordem_vis);
			if(grafo.low[v] > grafo.d[u]){
				grafo.bridges.insert(make_pair(make_pair(u, v), grafo.cost[u][i]));
			}
			grafo.low[u] = min(grafo.low[u], grafo.low[v]);
		}
		else if (grafo.pai[u] != v){
			grafo.low[u] = min(grafo.low[u], grafo.d[v]);
		}
	}
	ordem_vis.push_back(u);
}

void dfsSCC(int u, Grafo & grafo){
	grafo.vis[u] = true;
	for(int i = 0; i < grafo.adjDir[u].size(); i++){
		int v = grafo.adjDir[u][i];
		if (!grafo.vis[v]){
			dfsSCC(v, grafo);
		}
	}
	grafo.sccs.back().push_back(u);
}

bool dfs(int a, int b, Grafo & grafo, bool f){
	grafo.vis[a] = true;
	if (grafo.sccCost[a]) f = true;
	if (a == b){
		// cout << "Chegou\n" << f << endl;
		return f;
	}
	// cout << "A = " << a << " " << grafo.adj[a].size() << endl;
	for (int i = 0; i < grafo.adj[a].size(); i++){
		int v = grafo.adj[a][i];
		// cout << v << endl;
		if (!grafo.vis[v]){
			if(dfs(v, b, grafo, f || grafo.cost[a][i])){
				return true;
			}
		}
	}
	return false;
}

signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
	int n, m, t = 1;
	cin >> n >> m;
	Grafo grafo = Grafo(n);
	for (int i = 0; i < m; i++){
		int x, y, w;
		cin >> x >> y >> w;
		x--; y--;

		grafo.adj[x].push_back(y);
		grafo.adj[y].push_back(x);

		grafo.cost[x].push_back(w);
		grafo.cost[y].push_back(w);
	}
	int a, b;
	cin >> a >> b;
	a--; b--;

	vector<int> ordem_vis;

	for (int i = 0; i < n; i++){
		if (!grafo.vis[i]){
			dfsBridges(i, grafo, ordem_vis);
		}
	}

	grafo.vis.assign(n, false);

	vector<int> new_id(n);

	for (int i = n - 1; i >= 0; i--){
		if (!grafo.vis[i]){
			grafo.sccs.push_back(vector<int> ());
			grafo.sccCost.push_back(0);
			dfsSCC(i, grafo);
			sort(grafo.sccs.back().begin(), grafo.sccs.back().end());
			for (int u : grafo.sccs.back()){
				new_id[u] = grafo.sccs.size() - 1;
				// cout << u << " " << new_id[u] << endl;
				for (int i = 0; i < grafo.adj[u].size(); i++){
					if (binary_search(grafo.sccs.back().begin(), grafo.sccs.back().end(), grafo.adj[u][i])){
						grafo.sccCost.back() += grafo.cost[u][i];
					}
				}
			}
			// cout << endl;
		}
	}

	for (int i = 0; i < n; i++){
		grafo.adj[i].clear();
		grafo.cost[i].clear();
	}
	grafo.adj.resize(grafo.sccs.size());
	grafo.cost.resize(grafo.sccs.size());
	grafo.vis.assign(grafo.sccs.size(), false);

	for (pair<pair<int, int>, int> p : grafo.bridges){
		int u, v;
		tie(u, v) = p.first;
		int cost_edge = p.second;
		// cout << "old: " << u << " " << v << " ";
		u = new_id[u]; v = new_id[v];
        // cout << "new: " << u << " " << v << endl;
		if (u != v){
			// cout << u << "-" << v << endl;
		    // cout << cost_edge << endl;
			grafo.adj[u].push_back(v);

			grafo.cost[u].push_back(cost_edge);

		}
	}

	a = new_id[a]; b = new_id[b];

	if (dfs(a, b, grafo, false)){
		cout << "YES\n";
		return 0;
	}
	grafo.vis.assign(grafo.sccs.size(), false);
	if (dfs(b, a, grafo, false)){
		cout << "YES\n";
		return 0;
	}
	else cout << "NO\n";

}


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

#define int long long
#define INF LLONG_MAX
#define _INF LLONG_MIN
#define endl '\n'

struct Grafo{
	vector<vector<int>> adj, cost;
	vector<int> low, d, pai;
	vector<bool> vis, vtxValue;
	vector<pair<int, int>> bridges;
	vector<int> cost_bridge;
	int tempo = 0;

	map<pair<int, int>, bool> usable;

	Grafo(int n){
		adj.resize(n);
		cost.resize(n);
		low.resize(n, INF);
		d.resize(n, INF);
		pai.resize(n, INF);
		vis.resize(n, false);
		vtxValue.resize(n, false);
	}
};

int dfsBridges(int u, Grafo & g){
	g.tempo++;
	g.low[u] = g.tempo;
	g.d[u] = g.tempo;
	g.vis[u] = true;
	for (int i = 0; i < g.adj[u].size(); i++){
		int v = g.adj[u][i];
		if (!g.vis[v]){
			g.pai[v] = u;
			dfsBridges(v, g);
			if (g.low[v] > g.d[u]){
				g.usable[make_pair(u, v)] = false;
				g.usable[make_pair(v, u)] = false;
				g.bridges.emplace_back(u, v);
				g.bridges.emplace_back(v, u);
				g.cost_bridge.push_back(g.cost[u][i]);
				g.cost_bridge.push_back(g.cost[u][i]);
			}
			g.low[u] = min(g.low[u], g.low[v]);
		}
		else if (g.pai[u] != v){
			g.low[u] = min(g.low[u], g.d[v]);
		}
	}
}

void dfsCompConex(int u, Grafo & g, vector<int> & compConex){
	g.vis[u] = true;
	for (int v : g.adj[u]){
		if (!g.vis[v] && g.usable[make_pair(u,v)]){
			dfsCompConex(v, g, compConex);
		}
	}
	compConex.push_back(u);
}

bool dfs(int a, int b, Grafo & g, bool f){
	g.vis[a] = true;
	if (g.vtxValue[a]) f = true;
	if (a == b){
		// cout << "Chegou\n" << f << endl;
		return f;
	}
	for (int i = 0; i < g.adj[a].size(); i++){
		int v = g.adj[a][i];
		if (!g.vis[v]){
			// cout << a << " " << v << " " << g.cost[a][i] << endl;
			if(dfs(v, b, g, f || g.cost[a][i])){
				return true;
			}
		}
	}
	return false;
}

signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
	int n, m, t = 1;
	cin >> n >> m;
	Grafo g = Grafo(n);
	for (int i = 0; i < m; i++){
		int x, y, w;
		cin >> x >> y >> w;
		x--; y--;

		g.adj[x].push_back(y);
		g.adj[y].push_back(x);

		g.cost[x].push_back(w);
		g.cost[y].push_back(w);
	}
	int a, b;
	cin >> a >> b;
	a--; b--;

	for (int i = 0; i < n; i++){
		if (!g.vis[i]){
			dfsBridges(i, g);
		}
	}

	g.vis.assign(n, false);

	vector<int> new_id(n);

	int id = 0;

	for (int i = 0; i < n; i++){
		if (!g.vis[i]){
			vector<int> compConex;
			dfsCompConex(i, g, compConex);
			sort(compConex.begin(), compConex.end());
			for (int u : compConex){
				new_id[u] = id;
				// cout << u << " " << id << endl;
				for (int i = 0; i < g.adj[u].size(); i++){
					if (binary_search(compConex.begin(), compConex.end(), g.adj[u][i])){
						g.vtxValue[id] = g.vtxValue[id] || (g.cost[u][i] > 0);
					}
				}
			}
			id++;
		}
	}

	// cout << g.vtxValue[1] << endl;

	for (int i = 0; i < n; i++){
		g.adj[i].clear();
		g.cost[i].clear();
	}
	g.adj.resize(id);
	g.cost.resize(id);
	g.vis.assign(id, false);

	for (int i = 0; i < g.bridges.size(); i++){
		int u, v;
		tie(u, v) = g.bridges[i];
		// cout << u << "-" << v << "-" << g.cost_bridge[i] << endl;
		u = new_id[u]; v = new_id[v];
		if (u != v){
			g.adj[u].push_back(v);
			g.cost[u].push_back(g.cost_bridge[i]);
		}
	}

	a = new_id[a]; b = new_id[b];

	if (dfs(a, b, g, false)){
		cout << "YES\n";
		return 0;
	}
	// g.vis.assign(id, false);
	// if (dfs(b, a, g, false)){
	// 	cout << "YES\n";
	// 	return 0;
	// }
	else cout << "NO\n";

}


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

// #define int long long
#define INF INT_MAX
#define _INF INT_MIN
#define endl '\n'

struct Grafo{
	vector<vector<int>> adj, adjDir, sccs;
	vector<int> low, d, pai, sccCost;
	vector<bool> vis;
	map<pair<int, int>, bool> is_used;
	map<pair<int, int>, int> cost, costDir;
	set<pair<int, int>> bridges;
	int tempo = 0;

	Grafo(int n){
		adj.resize(n);
		adjDir.resize(n);
		low.resize(n, INF);
		d.resize(n, INF);
		pai.resize(n, INF);
		vis.resize(n, false);
	}
};

void dfsBridges(int u, Grafo & grafo, vector<int> & ordem_vis){
	grafo.tempo++;
	grafo.d[u] = grafo.tempo;
	grafo.low[u] = grafo.tempo;
	grafo.vis[u] = true;
	for (int v : grafo.adj[u]){
		if (!grafo.is_used[make_pair(u, v)]){
			// monta grafo direcionado para calcular sccs
			grafo.adjDir[u].push_back(v);
			grafo.costDir[make_pair(u, v)] = grafo.cost[make_pair(u, v)];

			grafo.is_used[make_pair(u, v)] = true;
			grafo.is_used[make_pair(v, u)] = true;
		}
		if (!grafo.vis[v]){
			grafo.pai[v] = u;
			dfsBridges(v, grafo, ordem_vis);
			if(grafo.low[v] > grafo.d[u]){
				grafo.bridges.emplace(u, v);
			}
			grafo.low[u] = min(grafo.low[u], grafo.low[v]);
		}
		else if (grafo.pai[u] != v){
			grafo.low[u] = min(grafo.low[u], grafo.d[v]);
		}
	}
	ordem_vis.push_back(u);
}

void dfsSCC(int u, Grafo & grafo){
	grafo.vis[u] = true;
	for(int v : grafo.adjDir[u]){
		if (!grafo.vis[v]){
			dfsSCC(v, grafo);
		}
	}
	grafo.sccs[grafo.sccs.size() - 1].push_back(u);
}

bool dfs(int a, int b, Grafo & grafo, bool f){
	grafo.vis[a] = true;
	if (grafo.sccCost[a]) f = true;
	if (a == b){
		// cout << "Chegou\n" << f << endl;
		return f;
	}
	// cout << "A = " << a << " " << adj[a].size() << endl;
	for (int i = 0; i < grafo.adj[a].size(); i++){
		int v = grafo.adj[a][i];
		if (!grafo.vis[v]){
			if(dfs(v, b, grafo, f || grafo.cost[make_pair(a, v)])){
				return true;
			}
		}
	}
	return false;
}

signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
	int n, m, t = 1;
	cin >> n >> m;
	Grafo grafo = Grafo(n);
	for (int i = 0; i < m; i++){
		int x, y, w;
		cin >> x >> y >> w;
		x--; y--;

		grafo.adj[x].push_back(y);
		grafo.adj[y].push_back(x);

		grafo.cost[make_pair(x, y)] = w;
		grafo.cost[make_pair(y, x)] = w;
	}

	int a, b;
	cin >> a >> b;
	a--; b--;

	vector<int> ordem_vis;

	for (int i = 0; i < n; i++){
		if (!grafo.vis[i]){
			dfsBridges(i, grafo, ordem_vis);
		}
	}

	grafo.vis.assign(n, false);

	map<int, int> new_id;

	for (int i = n - 1; i >= 0; i--){
		if (!grafo.vis[i]){
			grafo.sccs.push_back(vector<int> ());
			grafo.sccCost.push_back(0);
			dfsSCC(i, grafo);
			for (int v : grafo.sccs[grafo.sccs.size() - 1]){
				new_id[v] = grafo.sccs.size() - 1;
				// cout << v << " " << new_id[v] << endl;
			}
			for (int u : grafo.sccs[grafo.sccs.size() - 1]){
				for (int v : grafo.sccs[grafo.sccs.size() - 1]){
					// cout << u << " " << v << " " << grafo.cost[make_pair(u, v)] << endl;
					grafo.sccCost[grafo.sccCost.size() - 1] += grafo.cost[make_pair(u, v)];
					grafo.sccCost[grafo.sccCost.size() - 1] += grafo.cost[make_pair(v, u)];
				}
			}
			// cout << endl;
		}
	}

	grafo.adj.clear();
	grafo.adj.resize(grafo.sccs.size());
	grafo.cost.clear();
	grafo.vis.assign(grafo.sccs.size(), false);

	for (pair<int, int> p : grafo.bridges){
		int u, v;
		tie(u, v) = p;
		int cost_edge = grafo.costDir[make_pair(u, v)];
		// cout << "old: " << u << " " << v << " ";
		u = new_id[u]; v = new_id[v];
        // cout << "new: " << u << " " << v << endl;
		if (u != v){
			// cout << u << "-" << v << endl;
		    // cout << cost_edge << endl;
			grafo.adj[u].push_back(v);
			grafo.adj[v].push_back(u);
			grafo.cost[make_pair(u, v)] = cost_edge;
			grafo.cost[make_pair(v, u)] = cost_edge;
		}
	}

	a = new_id[a]; b = new_id[b];

	if (dfs(a, b, grafo, false)){
		cout << "YES\n";
	}
	else cout << "NO\n";

}


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

#define int long long
#define INF LLONG_MAX
#define _INF LLONG_MIN
#define endl '\n'

struct Grafo{
	vector<vector<int>> adj, adjDir, sccs;
	vector<int> low, d, pai, sccCost;
	vector<bool> vis;
	map<pair<int, int>, bool> is_used;
	map<pair<int, int>, int> cost, costDir;
	set<pair<int, int>> bridges;
	int tempo = 0;

	Grafo(int n){
		adj.resize(n);
		adjDir.resize(n);
		low.resize(n, INF);
		d.resize(n, INF);
		pai.resize(n, INF);
		vis.resize(n, false);
	}
};

void dfsBridges(int u, Grafo & grafo, vector<int> & ordem_vis){
	grafo.tempo++;
	grafo.d[u] = grafo.tempo;
	grafo.low[u] = grafo.tempo;
	grafo.vis[u] = true;
	for (int v : grafo.adj[u]){
		if (!grafo.is_used[make_pair(u, v)]){
			// monta grafo direcionado para calcular sccs
			grafo.adjDir[u].push_back(v);
			grafo.costDir[make_pair(u, v)] = grafo.cost[make_pair(u, v)];

			grafo.is_used[make_pair(u, v)] = true;
			grafo.is_used[make_pair(v, u)] = true;
		}
		if (!grafo.vis[v]){
			grafo.pai[v] = u;
			dfsBridges(v, grafo, ordem_vis);
			if(grafo.low[v] > grafo.d[u]){
				grafo.bridges.emplace(u, v);
			}
			grafo.low[u] = min(grafo.low[u], grafo.low[v]);
		}
		else if (grafo.pai[u] != v){
			grafo.low[u] = min(grafo.low[u], grafo.d[v]);
		}
	}
	ordem_vis.push_back(u);
}

void dfsSCC(int u, Grafo & grafo){
	grafo.vis[u] = true;
	for(int v : grafo.adjDir[u]){
		if (!grafo.vis[v]){
			dfsSCC(v, grafo);
		}
	}
	grafo.sccs[grafo.sccs.size() - 1].push_back(u);
}

bool dfs(int a, int b, vector<vector<int>> & adj, map<pair<int,int>, int> & costE, vector<int> & costV, vector<bool> & vis, bool f){
	vis[a] = true;
	if (costV[a]) f = true;
	if (a == b){
		// cout << "Chegou\n" << f << endl;
		return f;
	}
	// cout << "A = " << a << " " << adj[a].size() << endl;
	for (int i = 0; i < adj[a].size(); i++){
		int v = adj[a][i];
		if (!vis[v]){
			if(dfs(v, b, adj, costE, costV, vis, f || costE[make_pair(a, v)])){
				return true;
			}
		}
	}
	return false;
}

signed main(){
	int n, m, t = 1;
	cin >> n >> m;
	Grafo grafo = Grafo(n);
	for (int i = 0; i < m; i++){
		int x, y, w;
		cin >> x >> y >> w;
		x--; y--;

		grafo.adj[x].push_back(y);
		grafo.adj[y].push_back(x);

		grafo.cost[make_pair(x, y)] = w;
		grafo.cost[make_pair(y, x)] = w;
	}

	int a, b;
	cin >> a >> b;
	a--; b--;

	vector<int> ordem_vis;

	for (int i = 0; i < n; i++){
		if (!grafo.vis[i]){
			dfsBridges(i, grafo, ordem_vis);
		}
	}

	grafo.vis.assign(n, false);

	map<int, int> new_id;

	for (int i = n - 1; i >= 0; i--){
		if (!grafo.vis[i]){
			grafo.sccs.push_back(vector<int> ());
			grafo.sccCost.push_back(0);
			dfsSCC(i, grafo);
			for (int v : grafo.sccs[grafo.sccs.size() - 1]){
				new_id[v] = grafo.sccs.size() - 1;
				// cout << v << " " << new_id[v] << endl;
			}
			for (int u : grafo.sccs[grafo.sccs.size() - 1]){
				for (int v : grafo.sccs[grafo.sccs.size() - 1]){
					// cout << u << " " << v << " " << grafo.cost[make_pair(u, v)] << endl;
					grafo.sccCost[grafo.sccCost.size() - 1] += grafo.cost[make_pair(u, v)];
					grafo.sccCost[grafo.sccCost.size() - 1] += grafo.cost[make_pair(v, u)];
				}
			}
			// cout << endl;
		}
	}

	vector<vector<int>> adj_tree(n), adj_treeT(n);
	map<pair<int,int>, int> cost_tree, cost_treeT;
	vector<bool> vis(n, false);

	// cout << grafo.sccCost[1] << endl;

	for (pair<int, int> p : grafo.bridges){
		int u, v;
		tie(u, v) = p;
		int cost_edge = grafo.costDir[make_pair(u, v)];
		// cout << "old: " << u << " " << v << " ";
		u = new_id[u]; v = new_id[v];
        // cout << "new: " << u << " " << v << endl;
		if (u != v){
			// cout << u << "-" << v << endl;
		    // cout << cost_edge << endl;
			adj_tree[u].push_back(v);
			adj_tree[v].push_back(u);
			cost_tree[make_pair(u, v)] = cost_edge;
			cost_tree[make_pair(v, u)] = cost_edge;
		}
	}

	a = new_id[a]; b = new_id[b];

	if (dfs(a, b, adj_tree, cost_tree, grafo.sccCost, vis, false)){
		cout << "YES\n";
	}
	else cout << "NO\n";

}


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

// #define int long long
#define INF INT_MAX
#define _INF INT_MIN
#define endl '\n'

struct Grafo{
	vector<vector<int>> adj, adjDir, sccs, cost, costDir;
	vector<int> low, d, pai, sccCost;
	vector<bool> vis;
	map<pair<int, int>, bool> is_used;
	set<pair<pair<int, int>, int>> bridges;
	int tempo = 0;

	Grafo(int n){
		adj.resize(n);
		cost.resize(n);
		adjDir.resize(n);
		costDir.resize(n);
		low.resize(n, INF);
		d.resize(n, INF);
		pai.resize(n, INF);
		vis.resize(n, false);
	}
};

void dfsBridges(int u, Grafo & grafo, vector<int> & ordem_vis){
	grafo.tempo++;
	grafo.d[u] = grafo.tempo;
	grafo.low[u] = grafo.tempo;
	grafo.vis[u] = true;
	for (int i = 0; i < grafo.adj[u].size(); i++){
		int v = grafo.adj[u][i];
		if (!grafo.is_used[make_pair(u, v)]){
			// monta grafo direcionado para calcular sccs
			grafo.adjDir[u].push_back(v);
			grafo.costDir[u].push_back(grafo.cost[u][i]);

			grafo.is_used[make_pair(u, v)] = true;
			grafo.is_used[make_pair(v, u)] = true;
		}
		if (!grafo.vis[v]){
			grafo.pai[v] = u;
			dfsBridges(v, grafo, ordem_vis);
			if(grafo.low[v] > grafo.d[u]){
				grafo.bridges.insert(make_pair(make_pair(u, v), grafo.cost[u][i]));
			}
			grafo.low[u] = min(grafo.low[u], grafo.low[v]);
		}
		else if (grafo.pai[u] != v){
			grafo.low[u] = min(grafo.low[u], grafo.d[v]);
		}
	}
	ordem_vis.push_back(u);
}

void dfsSCC(int u, Grafo & grafo){
	grafo.vis[u] = true;
	for(int i = 0; i < grafo.adjDir[u].size(); i++){
		int v = grafo.adjDir[u][i];
		if (!grafo.vis[v]){
			dfsSCC(v, grafo);
		}
	}
	grafo.sccs[grafo.sccs.size() - 1].push_back(u);
}

bool dfs(int a, int b, Grafo & grafo, bool f){
	grafo.vis[a] = true;
	if (grafo.sccCost[a]) f = true;
	if (a == b){
		// cout << "Chegou\n" << f << endl;
		return f;
	}
	// cout << "A = " << a << " " << grafo.adj[a].size() << endl;
	for (int i = 0; i < grafo.adj[a].size(); i++){
		int v = grafo.adj[a][i];
		// cout << v << endl;
		if (!grafo.vis[v]){
			if(dfs(v, b, grafo, f || grafo.cost[a][i])){
				return true;
			}
		}
	}
	return false;
}

signed main(){
    // ios::sync_with_stdio(false);
    // cin.tie(0);
    // cout.tie(0);
	int n, m, t = 1;
	cin >> n >> m;
	Grafo grafo = Grafo(n);
	for (int i = 0; i < m; i++){
		int x, y, w;
		cin >> x >> y >> w;
		x--; y--;

		grafo.adj[x].push_back(y);
		grafo.adj[y].push_back(x);

		grafo.cost[x].push_back(w);
		grafo.cost[y].push_back(w);
	}
	int a, b;
	cin >> a >> b;
	a--; b--;

	vector<int> ordem_vis;

	for (int i = 0; i < n; i++){
		if (!grafo.vis[i]){
			dfsBridges(i, grafo, ordem_vis);
		}
	}

	grafo.vis.assign(n, false);

	vector<int> new_id(n);

	for (int i = n - 1; i >= 0; i--){
		if (!grafo.vis[i]){
			grafo.sccs.push_back(vector<int> ());
			grafo.sccCost.push_back(0);
			dfsSCC(i, grafo);
			sort(grafo.sccs[grafo.sccs.size() - 1].begin(), grafo.sccs[grafo.sccs.size() - 1].end());
			for (int u : grafo.sccs[grafo.sccs.size() - 1]){
				new_id[u] = grafo.sccs.size() - 1;
				// cout << u << " " << new_id[u] << endl;
				for (int i = 0; i < grafo.adj[u].size(); i++){
					if (binary_search(grafo.sccs[grafo.sccs.size() - 1].begin(), grafo.sccs[grafo.sccs.size() - 1].end(), grafo.adj[u][i])){
						grafo.sccCost[grafo.sccCost.size() - 1] += grafo.cost[u][i];
					}
				}
			}
			// cout << endl;
		}
	}

	for (int i = 0; i < n; i++){
		grafo.adj[i].clear();
		grafo.cost[i].clear();
	}
	grafo.adj.resize(grafo.sccs.size());
	grafo.cost.resize(grafo.sccs.size());
	grafo.vis.assign(grafo.sccs.size(), false);

	for (pair<pair<int, int>, int> p : grafo.bridges){
		int u, v;
		tie(u, v) = p.first;
		int cost_edge = p.second;
		// cout << "old: " << u << " " << v << " ";
		u = new_id[u]; v = new_id[v];
        // cout << "new: " << u << " " << v << endl;
		if (u != v){
			// cout << u << "-" << v << endl;
		    // cout << cost_edge << endl;
			grafo.adj[u].push_back(v);
			grafo.adj[v].push_back(u);
			grafo.cost[u].push_back(cost_edge);
			grafo.cost[v].push_back(cost_edge);
		}
	}

	a = new_id[a]; b = new_id[b];

	if (dfs(a, b, grafo, false)){
		cout << "YES\n";
	}
	else cout << "NO\n";

}


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

#define int long long
#define INF LLONG_MAX
#define _INF LLONG_MIN
#define endl '\n'

struct Grafo{
	vector<vector<int>> adj, cost, usable;
	vector<int> low, d, pai;
	vector<bool> vis, vtxValue;
	vector<pair<int, int>> bridges;
	vector<int> cost_bridge;
	int tempo = 0;

	Grafo(int n){
		adj.resize(n);
		usable = vector<vector<int>> (n, vector<int> (n, 0));
		cost.resize(n);
		low.resize(n, INF);
		d.resize(n, INF);
		pai.resize(n, INF);
		vis.resize(n, false);
		vtxValue.resize(n, false);
	}
};

int dfsBridges(int u, Grafo & g){
	g.tempo++;
	g.low[u] = g.tempo;
	g.d[u] = g.tempo;
	g.vis[u] = true;
	for (int i = 0; i < g.adj[u].size(); i++){
		int v = g.adj[u][i];
		if (!g.vis[v]){
			g.pai[v] = u;
			dfsBridges(v, g);
			if (g.low[v] > g.d[u]){
				g.usable[u][v] = 0;
				g.usable[v][u] = 0;
				g.bridges.emplace_back(u, v);
				g.bridges.emplace_back(v, u);
				g.cost_bridge.push_back(g.cost[u][i]);
				g.cost_bridge.push_back(g.cost[u][i]);
			}
			g.low[u] = min(g.low[u], g.low[v]);
		}
		else if (g.pai[u] != v){
			g.low[u] = min(g.low[u], g.d[v]);
		}
	}
}

void dfsCompConex(int u, Grafo & g, vector<int> & compConex){
	g.vis[u] = true;
	for (int v : g.adj[u]){
		if (!g.vis[v] && g.usable[u][v]){
			dfsCompConex(v, g, compConex);
		}
	}
	compConex.push_back(u);
}

bool dfs(int a, int b, Grafo & g, bool f){
	g.vis[a] = true;
	if (g.vtxValue[a]) f = true;
	if (a == b){
		// cout << "Chegou\n" << f << endl;
		return f;
	}
	for (int i = 0; i < g.adj[a].size(); i++){
		int v = g.adj[a][i];
		if (!g.vis[v]){
			// cout << a << " " << v << " " << g.cost[a][i] << endl;
			if(dfs(v, b, g, f || g.cost[a][i])){
				return true;
			}
		}
	}
	return false;
}

signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
	int n, m, t = 1;
	cin >> n >> m;
	Grafo g = Grafo(n);
	for (int i = 0; i < m; i++){
		int x, y, w;
		cin >> x >> y >> w;
		x--; y--;

		g.usable[x][y] = 1;

		g.adj[x].push_back(y);
		g.adj[y].push_back(x);

		g.cost[x].push_back(w);
		g.cost[y].push_back(w);
	}
	int a, b;
	cin >> a >> b;
	a--; b--;

	for (int i = 0; i < n; i++){
		if (!g.vis[i]){
			dfsBridges(i, g);
		}
	}

	g.vis.assign(n, false);

	vector<int> new_id(n);

	int id = 0;

	for (int i = 0; i < n; i++){
		if (!g.vis[i]){
			vector<int> compConex;
			dfsCompConex(i, g, compConex);
			sort(compConex.begin(), compConex.end());
			for (int u : compConex){
				new_id[u] = id;
				// cout << u << " " << id << endl;
				for (int i = 0; i < g.adj[u].size(); i++){
					if (binary_search(compConex.begin(), compConex.end(), g.adj[u][i])){
						g.vtxValue[id] = g.vtxValue[id] || (g.cost[u][i] > 0);
					}
				}
			}
			id++;
		}
	}

	// cout << g.vtxValue[1] << endl;

	for (int i = 0; i < n; i++){
		g.adj[i].clear();
		g.cost[i].clear();
	}
	g.adj.resize(id);
	g.cost.resize(id);
	g.vis.assign(id, false);

	for (int i = 0; i < g.bridges.size(); i++){
		int u, v;
		tie(u, v) = g.bridges[i];
		// cout << u << "-" << v << "-" << g.cost_bridge[i] << endl;
		u = new_id[u]; v = new_id[v];
		if (u != v){
			g.adj[u].push_back(v);
			g.cost[u].push_back(g.cost_bridge[i]);
		}
	}

	a = new_id[a]; b = new_id[b];

	if (dfs(a, b, g, false)){
		cout << "YES\n";
		return 0;
	}
	// g.vis.assign(id, false);
	// if (dfs(b, a, g, false)){
	// 	cout << "YES\n";
	// 	return 0;
	// }
	else cout << "NO\n";

}


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

// #define int long long
#define INF INT_MAX
#define _INF INT_MIN
#define endl '\n'

struct Grafo{
	vector<vector<int>> adj, adjDir, sccs, cost, costDir;
	vector<int> low, d, pai, sccCost;
	vector<bool> vis;
	map<pair<int, int>, bool> is_used;
	set<pair<pair<int, int>, int>> bridges;
	int tempo = 0;

	Grafo(int n){
		adj.resize(n);
		cost.resize(n);
		adjDir.resize(n);
		costDir.resize(n);
		low.resize(n, INF);
		d.resize(n, INF);
		pai.resize(n, INF);
		vis.resize(n, false);
	}
};

void dfsBridges(int u, Grafo & grafo, vector<int> & ordem_vis){
	grafo.tempo++;
	grafo.d[u] = grafo.tempo;
	grafo.low[u] = grafo.tempo;
	grafo.vis[u] = true;
	for (int i = 0; i < grafo.adj[u].size(); i++){
		int v = grafo.adj[u][i];
		if (!grafo.is_used[make_pair(u, v)]){
			// monta grafo direcionado para calcular sccs
			grafo.adjDir[u].push_back(v);
			grafo.costDir[u].push_back(grafo.cost[u][i]);

			grafo.is_used[make_pair(u, v)] = true;
			grafo.is_used[make_pair(v, u)] = true;
		}
		if (!grafo.vis[v]){
			grafo.pai[v] = u;
			dfsBridges(v, grafo, ordem_vis);
			if(grafo.low[v] > grafo.d[u]){
				grafo.bridges.insert(make_pair(make_pair(u, v), grafo.cost[u][i]));
			}
			grafo.low[u] = min(grafo.low[u], grafo.low[v]);
		}
		else if (grafo.pai[u] != v){
			grafo.low[u] = min(grafo.low[u], grafo.d[v]);
		}
	}
	ordem_vis.push_back(u);
}

void dfsSCC(int u, Grafo & grafo, int & cont){
	grafo.vis[u] = true;
	for(int i = 0; i < grafo.adjDir[u].size(); i++){
		int v = grafo.adjDir[u][i];
		cont += grafo.costDir[u][i];
		if (!grafo.vis[v]){
			dfsSCC(v, grafo, cont);
		}
	}
	grafo.sccs[grafo.sccs.size() - 1].push_back(u);
}

bool dfs(int a, int b, vector<vector<int>> & adj, map<pair<int,int>, int> & costE, vector<int> & costV, vector<bool> & vis, bool f){
	vis[a] = true;
	if (costV[a]) f = true;
	if (a == b){
		// cout << "Chegou\n" << f << endl;
		return f;
	}
	// cout << "A = " << a << " " << adj[a].size() << endl;
	for (int i = 0; i < adj[a].size(); i++){
		int v = adj[a][i];
		if (!vis[v]){
			if(dfs(v, b, adj, costE, costV, vis, f || costE[make_pair(a, v)])){
				return true;
			}
		}
	}
	return false;
}

signed main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int n, m, t = 1;
	cin >> n >> m;
	Grafo grafo = Grafo(n);
	for (int i = 0; i < m; i++){
		int x, y, w;
		cin >> x >> y >> w;
		x--; y--;

		grafo.adj[x].push_back(y);
		grafo.adj[y].push_back(x);

		grafo.cost[x].push_back(w);
		grafo.cost[y].push_back(w);
	}

	int a, b;
	cin >> a >> b;
	a--; b--;

	vector<int> ordem_vis;

	for (int i = 0; i < n; i++){
		if (!grafo.vis[i]){
			dfsBridges(i, grafo, ordem_vis);
		}
	}

	grafo.vis.assign(n, false);

	map<int, int> new_id;

	for (int i = n - 1; i >= 0; i--){
		if (!grafo.vis[i]){
			grafo.sccs.push_back(vector<int> ());
			grafo.sccCost.push_back(0);
			int cont = 0;
			dfsSCC(i, grafo, cont);
			for (int v : grafo.sccs[grafo.sccs.size() - 1]){
				new_id[v] = grafo.sccs.size() - 1;
				// cout << v << " " << new_id[v] << endl;
			}
			grafo.sccCost[grafo.sccCost.size() - 1] = cont;
			// cout << endl;
		}
	}

	vector<vector<int>> adj_tree(grafo.sccs.size()), adj_treeT(grafo.sccs.size());
	map<pair<int,int>, int> cost_tree, cost_treeT;
	vector<bool> vis(n, false);

	// cout << grafo.sccCost[1] << endl;

	for (pair<pair<int, int>, int> p : grafo.bridges){
		int u, v;
		tie(u, v) = p.first;
		int cost_edge = p.second;
		// cout << "old: " << u << " " << v << " ";
		u = new_id[u]; v = new_id[v];
        // cout << "new: " << u << " " << v << endl;
		if (u != v){
			// cout << u << "-" << v << endl;
		    // cout << cost_edge << endl;
			adj_tree[u].push_back(v);
			adj_tree[v].push_back(u);
			cost_tree[make_pair(u, v)] = cost_edge;
			cost_tree[make_pair(v, u)] = cost_edge;
		}
	}

	a = new_id[a]; b = new_id[b];

	if (dfs(a, b, adj_tree, cost_tree, grafo.sccCost, vis, false)){
		cout << "YES\n";
	}
	else cout << "NO\n";

}


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

// #define int long long
#define INF INT_MAX
#define _INF INT_MIN
#define endl '\n'

struct Grafo{
	vector<vector<int>> adj, adjDir, sccs, cost, costDir;
	vector<int> low, d, pai, sccCost;
	vector<bool> vis;
	map<pair<int, int>, bool> is_used;
	set<pair<pair<int, int>, int>> bridges;
	int tempo = 0;

	Grafo(int n){
		adj.resize(n);
		adjDir.resize(n);
		low.resize(n, INF);
		d.resize(n, INF);
		pai.resize(n, INF);
		vis.resize(n, false);
	}
};

void dfsBridges(int u, Grafo & grafo, vector<int> & ordem_vis){
	grafo.tempo++;
	grafo.d[u] = grafo.tempo;
	grafo.low[u] = grafo.tempo;
	grafo.vis[u] = true;
	for (int i = 0; i < grafo.adj[u].size(); i++){
		int v = grafo.adj[u][i];
		if (!grafo.is_used[make_pair(u, v)]){
			// monta grafo direcionado para calcular sccs
			grafo.adjDir[u].push_back(v);
			grafo.costDir[u].push_back(grafo.cost[u][i]);

			grafo.is_used[make_pair(u, v)] = true;
			grafo.is_used[make_pair(v, u)] = true;
		}
		if (!grafo.vis[v]){
			grafo.pai[v] = u;
			dfsBridges(v, grafo, ordem_vis);
			if(grafo.low[v] > grafo.d[u]){
				grafo.bridges.insert(make_pair(make_pair(u, v), grafo.cost[u][i]));
			}
			grafo.low[u] = min(grafo.low[u], grafo.low[v]);
		}
		else if (grafo.pai[u] != v){
			grafo.low[u] = min(grafo.low[u], grafo.d[v]);
		}
	}
	ordem_vis.push_back(u);
}

void dfsSCC(int u, Grafo & grafo, int & cont){
	grafo.vis[u] = true;
	for(int i = 0; i < grafo.adjDir[u].size(); i++){
		int v = grafo.adjDir[u][i];
		cont += grafo.costDir[u][i];
		if (!grafo.vis[v]){
			dfsSCC(v, grafo, cont);
		}
	}
	grafo.sccs[grafo.sccs.size() - 1].push_back(u);
}

bool dfs(int a, int b, vector<vector<int>> & adj, map<pair<int,int>, int> & costE, vector<int> & costV, vector<bool> & vis, bool f){
	vis[a] = true;
	if (costV[a]) f = true;
	if (a == b){
		// cout << "Chegou\n" << f << endl;
		return f;
	}
	// cout << "A = " << a << " " << adj[a].size() << endl;
	for (int i = 0; i < adj[a].size(); i++){
		int v = adj[a][i];
		if (!vis[v]){
			if(dfs(v, b, adj, costE, costV, vis, f || costE[make_pair(a, v)])){
				return true;
			}
		}
	}
	return false;
}

signed main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int n, m, t = 1;
	cin >> n >> m;
	Grafo grafo = Grafo(n);
	for (int i = 0; i < m; i++){
		int x, y, w;
		cin >> x >> y >> w;
		x--; y--;

		grafo.adj[x].push_back(y);
		grafo.adj[y].push_back(x);

		grafo.cost[x].push_back(w);
		grafo.cost[y].push_back(w);
	}

	int a, b;
	cin >> a >> b;
	a--; b--;

	vector<int> ordem_vis;

	for (int i = 0; i < n; i++){
		if (!grafo.vis[i]){
			dfsBridges(i, grafo, ordem_vis);
		}
	}

	grafo.vis.assign(n, false);

	map<int, int> new_id;

	for (int i = n - 1; i >= 0; i--){
		if (!grafo.vis[i]){
			grafo.sccs.push_back(vector<int> ());
			grafo.sccCost.push_back(0);
			int cont = 0;
			dfsSCC(i, grafo, cont);
			for (int v : grafo.sccs[grafo.sccs.size() - 1]){
				new_id[v] = grafo.sccs.size() - 1;
				// cout << v << " " << new_id[v] << endl;
			}
			grafo.sccCost[grafo.sccCost.size() - 1] = cont;
			// cout << endl;
		}
	}

	vector<vector<int>> adj_tree(grafo.sccs.size()), adj_treeT(grafo.sccs.size());
	map<pair<int,int>, int> cost_tree, cost_treeT;
	vector<bool> vis(n, false);

	// cout << grafo.sccCost[1] << endl;

	for (pair<pair<int, int>, int> p : grafo.bridges){
		int u, v;
		tie(u, v) = p.first;
		int cost_edge = p.second;
		// cout << "old: " << u << " " << v << " ";
		u = new_id[u]; v = new_id[v];
        // cout << "new: " << u << " " << v << endl;
		if (u != v){
			// cout << u << "-" << v << endl;
		    // cout << cost_edge << endl;
			adj_tree[u].push_back(v);
			adj_tree[v].push_back(u);
			cost_tree[make_pair(u, v)] = cost_edge;
			cost_tree[make_pair(v, u)] = cost_edge;
		}
	}

	a = new_id[a]; b = new_id[b];

	if (dfs(a, b, adj_tree, cost_tree, grafo.sccCost, vis, false)){
		cout << "YES\n";
	}
	else cout << "NO\n";

}


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

#define int long long
#define INF LLONG_MAX
#define _INF LLONG_MIN
#define endl '\n'

struct Grafo{
	vector<vector<int>> adj, cost, usable;
	vector<int> low, d, pai;
	vector<bool> vis, vtxValue;
	vector<pair<int, int>> bridges;
	vector<int> cost_bridge;
	int tempo = 0;

	Grafo(int n){
		adj.resize(n);
		usable = vector<vector<int>> (n, vector<int> (n, 0));
		cost.resize(n);
		low.resize(n, INF);
		d.resize(n, INF);
		pai.resize(n, INF);
		vis.resize(n, false);
		vtxValue.resize(n, false);
	}
};

int dfsBridges(int u, Grafo & g){
	g.tempo++;
	g.low[u] = g.tempo;
	g.d[u] = g.tempo;
	g.vis[u] = true;
	for (int i = 0; i < g.adj[u].size(); i++){
		int v = g.adj[u][i];
		if (!g.vis[v]){
			g.pai[v] = u;
			dfsBridges(v, g);
			if (g.low[v] > g.d[u]){
				g.usable[u][v] = 0;
				g.usable[v][u] = 0;
				g.bridges.emplace_back(min(u, v), max(u, v));
				g.cost_bridge.push_back(g.cost[u][i]);
			}
			g.low[u] = min(g.low[u], g.low[v]);
		}
		else if (g.pai[u] != v){
			g.low[u] = min(g.low[u], g.d[v]);
		}
	}
}

void dfsCompConex(int u, Grafo & g, vector<int> & compConex){
	g.vis[u] = true;
	for (int v : g.adj[u]){
		if (!g.vis[v] && g.usable[u][v]){
			dfsCompConex(v, g, compConex);
		}
	}
	compConex.push_back(u);
}

bool dfs(int a, int b, Grafo & g, bool f){
	g.vis[a] = true;
	if (g.vtxValue[a]) f = true;
	if (a == b){
		// cout << "Chegou\n" << f << endl;
		return f;
	}
	for (int i = 0; i < g.adj[a].size(); i++){
		int v = g.adj[a][i];
		if (!g.vis[v]){
			if(dfs(v, b, g, f || g.cost[a][i])){
				return true;
			}
		}
	}
	return false;
}

signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
	int n, m, t = 1;
	cin >> n >> m;
	Grafo g = Grafo(n);
	for (int i = 0; i < m; i++){
		int x, y, w;
		cin >> x >> y >> w;
		x--; y--;

		g.usable[x][y] = 1;

		g.adj[x].push_back(y);
		g.adj[y].push_back(x);

		g.cost[x].push_back(w);
		g.cost[y].push_back(w);
	}
	int a, b;
	cin >> a >> b;
	a--; b--;

	for (int i = 0; i < n; i++){
		if (!g.vis[i]){
			dfsBridges(i, g);
		}
	}

	g.vis.assign(n, false);

	vector<int> new_id(n);

	int id = 0;

	for (int i = 0; i < n; i++){
		if (!g.vis[i]){
			vector<int> compConex;
			dfsCompConex(i, g, compConex);
			sort(compConex.begin(), compConex.end());
			for (int u : compConex){
				new_id[u] = id;
				// cout << u << " " << id << endl;
				for (int i = 0; i < g.adj[u].size(); i++){
					if (binary_search(compConex.begin(), compConex.end(), g.adj[u][i])){
						g.vtxValue[id] = true;
						break;
					}
				}
			}
			id++;
		}
	}

	for (int i = 0; i < n; i++){
		g.adj[i].clear();
		g.cost[i].clear();
	}
	g.adj.resize(id);
	g.cost.resize(id);
	g.vis.assign(id, false);

	for (int i = 0; i < g.bridges.size(); i++){
		int u, v;
		tie(u, v) = g.bridges[i];
		u = new_id[u]; v = new_id[v];
		if (u != v){
			g.adj[u].push_back(v);
			g.cost[u].push_back(g.cost_bridge[i]);
		}
	}

	a = new_id[a]; b = new_id[b];

	if (dfs(a, b, g, false)){
		cout << "YES\n";
		return 0;
	}
	g.vis.assign(id, false);
	if (dfs(b, a, g, false)){
		cout << "YES\n";
		return 0;
	}
	else cout << "NO\n";

}