#include <bits/stdc++.h>
using namespace std;
const int N = 300005;
long long gcd(long long a, long long b) { return b == 0 ? a : gcd(b, a % b); }
long long lcm(long long a, long long b) { return a * (b / gcd(a, b)); }
long long fact(long long n) {
  long long ret = 1;
  for (int i = 1; i <= n; i++) ret *= i;
  return ret;
}
bool is_vowel(char c) {
  if (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u' || c == 'y')
    return 1;
  return 0;
}
long double getDistance(long double x1, long double y1, long double x2,
                        long double y2) {
  return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
}
int n, m, a, b, low[N], num[N], cnt = 1, par[N], rootChildren, val[N], root = a;
vector<pair<int, int> > adj[N];
pair<int, int> e[N];
bool bridge[N];
void tarjan(int node) {
  low[node] = num[node] = cnt++;
  for (int i = 0; i < adj[node].size(); i++) {
    int to = adj[node][i].first, id = adj[node][i].second;
    if (!num[to]) {
      par[to] = node;
      if (node == root) rootChildren++;
      tarjan(to);
      if (low[to] > num[node]) bridge[id] = 1;
      low[node] = min(low[node], low[to]);
    } else if (to != par[node])
      low[node] = min(low[node], num[to]);
  }
}
int nodeID[N], cur = 1;
bool gold[N], v[N];
void dfs(int node) {
  if (v[node]) return;
  v[node] = 1;
  nodeID[node] = cur;
  for (int i = 0; i < adj[node].size(); i++) {
    int to = adj[node][i].first;
    int id = adj[node][i].second;
    if (bridge[id]) continue;
    if (val[id]) gold[cur] = 1;
    dfs(to);
  }
}
int main() {
  scanf("%d%d", &n, &m);
  for (int i = 0; i < m; i++) {
    int a, b, c;
    scanf("%d%d%d", &a, &b, &c);
    e[i] = pair<int, int>(a, b);
    adj[a].push_back(pair<int, int>(b, i));
    adj[b].push_back(pair<int, int>(a, i));
    val[i] = c;
  }
  int a, b;
  scanf("%d%d", &a, &b);
  tarjan(a);
  for (int i = 1; i <= n; i++) {
    if (nodeID[i] == 0) {
      dfs(i);
      cur++;
    }
  }
  for (int i = 1; i <= n; i++) adj[i].clear();
  for (int i = 0; i < m; i++) {
    if (bridge[i]) {
      int a = nodeID[e[i].first];
      int b = nodeID[e[i].second];
      adj[a].push_back(pair<int, int>(b, val[i]));
      adj[b].push_back(pair<int, int>(a, val[i]));
    }
  }
  queue<pair<int, int> > q;
  memset(v, 0, sizeof(v));
  q.push(pair<int, int>(nodeID[a], gold[nodeID[a]]));
  v[nodeID[a]] = 1;
  while (q.size()) {
    pair<int, int> cur = q.front();
    q.pop();
    cur.second |= gold[cur.first];
    if (cur.first == nodeID[b]) {
      if (cur.second)
        printf("YES");
      else
        printf("NO");
      return 0;
    }
    int node = cur.first;
    for (int i = 0; i < adj[node].size(); i++) {
      int to = adj[node][i].first;
      if (v[to]) continue;
      q.push(pair<int, int>(to, cur.second | adj[node][i].second));
      v[to] = 1;
    }
  }
  return 0;
}
