#include <bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
const long long int llINF = 0x3f3f3f3f3f3f3f;
const int MAXN = 500100;
const int MAXM = 1001000;
const long long int mod = 1e9 + 7;
const int LMAXN = 25;
vector<pair<int, int> > adj[MAXN];
int pre[MAXN], lo[MAXN], pa[MAXN], stk[MAXN];
int n, m;
int t, cnt, id;
int bcc[MAXN];
void dfsRebcc(int v) {
  pre[v] = cnt++;
  stk[t++] = v;
  lo[v] = pre[v];
  for (auto x : adj[v]) {
    int w = x.first;
    if (pre[w] == -1) {
      pa[w] = v;
      dfsRebcc(w);
      if (lo[w] < lo[v]) lo[v] = lo[w];
    } else {
      if (w != pa[v] && pre[w] < lo[v]) lo[v] = pre[w];
    }
  }
  if (lo[v] == pre[v]) {
    int u;
    do {
      u = stk[--t];
      bcc[u] = id;
    } while (u != v);
    id++;
  }
}
int ebcc() {
  for (int v = 0; v < MAXN; ++v) pre[v] = -1;
  t = cnt = id = 0;
  for (int v = 1; v < MAXN; ++v)
    if (pre[v] == -1) {
      pa[v] = v;
      dfsRebcc(v);
    }
  return id;
}
vector<pair<int, int> > adj2[MAXN];
vector<pair<int, int> > edges;
int tresure[MAXN];
int vis[MAXN];
void dfs(int v, bool ok) {
  ok |= tresure[v];
  vis[v] = ok;
  for (auto x : adj2[v]) {
    if (vis[x.first] != -1) continue;
    dfs(x.first, ok || x.second);
  }
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cin >> n >> m;
  int a, b, c;
  for (int i = 0; i < m; i++) {
    cin >> a >> b >> c;
    adj[a].push_back({b, c});
    adj[b].push_back({a, c});
    if (c) edges.push_back({a, b});
  }
  cin >> a >> b;
  int k = ebcc();
  for (int v = 1; v <= n; v++)
    for (auto x : adj[v]) {
      if (bcc[v] != bcc[x.first])
        adj2[bcc[v]].push_back({bcc[x.first], x.second});
      else if (x.second)
        tresure[bcc[v]] = 1;
    }
  if (bcc[a] == bcc[b]) {
    cout << (tresure[bcc[a]] ? "YES" : "NO") << endl;
    return 0;
  }
  memset(vis, -1, sizeof(vis));
  dfs(bcc[a], 0);
  cout << (vis[bcc[b]] ? "YES" : "NO") << endl;
}
