#include <bits/stdc++.h>
#define pb push_back
#define sc second
#define fr first
#define mk make_pair
#define ll long long
#define ii pair<int,int>
#define mp make_pair
using namespace std;
int n,m;
vector < ii > adj[1000006];
bool artPoint[1000006];
int par[1000006], num[1000006], low[1000006];
int cnt;
vector<int> G[1000006]; //Graph
vector<pair<int, int> > bridges;
int N = 6;
void dfsArticulationPointsAndBridges(int u) {
	num[u] = low[u] = cnt++;
	for (int i=0; i<(int)G[u].size(); i++) {
		int v = G[u][i];
		if (num[v] == -1) {
			par[v] = u;
			dfsArticulationPointsAndBridges(v);

			if (num[u] <= low[v]) artPoint[u] = 1;
			if (num[u] < low[v]) bridges.push_back(make_pair(u, v));
			low[u] = min(low[u], low[v]);
		} else if(par[u] != v) low[u] = min(low[u], num[v]);
	}
}

set < ii > is_bridges;
int p[1000005];
int R[1000005];
int ok[1000005];
int root(int x)
{
    while(p[x] != x)
    {
        p[x] = p[p[x]];
        x = p[x];
    }
    return x;
}
void M(int i,int j)
{
    int x = root(i),y = root(j);
    if(x != y)
    {
        int tt = max(ok[x] , ok[y]);
        ok[x] = tt;
        ok[y] = tt;
        if(R[x] > R[y])
            {
                p[y] = x;
            }
        else
            p[x] = y,R[y] += (R[x] == R[y]);
    }
}

int st,En;
int yes = 0;
int vis[1000005];
int dfs(int node,int take)
{
  vis[node] = 1;
  if(node == En)
  {
      yes = take;
  }
  for(auto x : adj[node])
  {
      int y = x.fr;
      y = root(y);
      int u = x.sc;
      int take2 = take;
      if(ok[y])
        take2 = 1;
      if(u)
        take2 = 1;
      if(!vis[y])
      {
          dfs(y,take2);
      }
  }
}
map < ii , int > F;
int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        p[i] = i;
        R[i] = 0;
    }
    vector < pair < ii , int > > all_edge;
    for(int i=0;i<m;i++)
    {
        int x,y,z;
        scanf("%d%d%d",&x,&y,&z);
        adj[x].push_back(mp(y,z));
        adj[y].push_back(mp(x,z));
        all_edge.push_back(mp(mp(x,y),z));
        G[x].push_back(y);
        G[y].push_back(x);

    }

    cin>>st>>En;
    cnt = 0;
	memset(num, -1, sizeof(num));
	memset(par, -1, sizeof(par));
	dfsArticulationPointsAndBridges(1);
	for(auto x : bridges)
    {
        is_bridges.insert(x);
        is_bridges.insert(mp(x.sc,x.fr));
    }
    for(auto x : all_edge)
    {
        if(is_bridges.find(x.fr) == is_bridges.end())
        {
            x.fr.fr = root(x.fr.fr);
            x.fr.sc = root(x.fr.sc);
            if(x.sc == 1)
            {
                ok[x.fr.fr] = 1;
                ok[x.fr.sc] = 1;
            }
            M(x.fr.fr,x.fr.sc);
        }
    }
    for(auto x : all_edge)
    {
        int c = x.fr.fr;
        int c2 = x.fr.sc;
        int val = x.sc;
        c = root(c);
        c2 = root(c2);
        adj[c].push_back(mp(c2,val));
        adj[c2].push_back(mp(c,val));
    }

    st = root(st);
    En = root(En);

    if(st == En)
    {
        int u = st;
        if(ok[u])
            cout<<"YES\n";
        else
            cout<<"NO\n";
        return 0;
    }
    dfs(st,0);
    if(yes)
        cout<<"YES\n";
    else
        cout<<"NO\n";
}


#include <bits/stdc++.h>
#define pb push_back
#define sc second
#define fr first
#define mk make_pair
#define ll long long
#define ii pair<int,int>
#define mp make_pair
using namespace std;
int n,m;
vector < ii > adj[1000006];
bool artPoint[1000006];
int par[1000006], num[1000006], low[1000006];
int cnt;
vector<int> G[1000006]; //Graph
vector<pair<int, int> > bridges;
int N = 6;
void dfsArticulationPointsAndBridges(int u) {
	num[u] = low[u] = cnt++;
	for (int i=0; i<(int)G[u].size(); i++) {
		int v = G[u][i];
		if (num[v] == -1) {
			par[v] = u;
			dfsArticulationPointsAndBridges(v);

			if (num[u] <= low[v]) artPoint[u] = 1;
			if (num[u] < low[v]) bridges.push_back(make_pair(u, v));
			low[u] = min(low[u], low[v]);
		} else if(par[u] != v) low[u] = min(low[u], num[v]);
	}
}

set < ii > is_bridges;
int p[1000005];
int R[1000005];
int ok[1000005];
int root(int x)
{
    while(p[x] != x)
    {
        p[x] = p[p[x]];
        x = p[x];
    }
    return x;
}
void M(int i,int j)
{
    int x = root(i),y = root(j);
    if(x != y)
    {
        int tt = max(ok[x] , ok[y]);
        ok[x] = tt;
        ok[y] = tt;
        if(R[x] > R[y])
            {
                p[y] = x;
            }
        else
            p[x] = y,R[y] += (R[x] == R[y]);
    }
}

int st,En;
int yes = 0;
int vis[1000005];
int dfs(int node,int take)
{
  vis[node] = 1;
  if(node == En)
  {
      yes = take;
  }
  for(auto x : adj[node])
  {
      int y = x.fr;
      y = root(y);
      int u = x.sc;
      int take2 = take;
      if(ok[y])
        take2 = 1;
      if(u)
        take2 = 1;
      if(!vis[y])
      {
          dfs(y,take2);
      }
  }
}
map < ii , int > F;
int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        p[i] = i;
        R[i] = 0;
    }
    vector < pair < ii , int > > all_edge;
    for(int i=0;i<m;i++)
    {
        int x,y,z;
        scanf("%d%d%d",&x,&y,&z);
        adj[x].push_back(mp(y,z));
        adj[y].push_back(mp(x,z));
        all_edge.push_back(mp(mp(x,y),z));
        G[x].push_back(y);
        G[y].push_back(x);

    }

    cin>>st>>En;
    cnt = 0;
	memset(num, -1, sizeof(num));
	memset(par, -1, sizeof(par));
	dfsArticulationPointsAndBridges(1);
	for(auto x : bridges)
    {
        is_bridges.insert(x);
        is_bridges.insert(mp(x.sc,x.fr));
    }
    for(auto x : all_edge)
    {
        if(is_bridges.find(x.fr) == is_bridges.end())
        {
            if(x.sc == 1)
            {
                ok[x.fr.fr] = 1;
                ok[x.fr.sc] = 1;
            }
            M(x.fr.fr,x.fr.sc);
        }
    }
    for(auto x : all_edge)
    {
        int c = x.fr.fr;
        int c2 = x.fr.sc;
        int val = x.sc;
        c = root(c);
        c2 = root(c2);
        adj[c].push_back(mp(c2,val));
        adj[c2].push_back(mp(c,val));
    }
    st = root(st);
    En = root(En);

    if(st == En)
    {
        int u = st;
        if(ok[u])
            cout<<"YES\n";
        else
            cout<<"NO\n";
        return 0;
    }
    dfs(st,0);
    if(yes)
        cout<<"YES\n";
    else
        cout<<"NO\n";
}


#include <bits/stdc++.h>
#define pb push_back
#define sc second
#define fr first
#define mk make_pair
#define ll long long
#define ii pair<int,int>
#define mp make_pair
using namespace std;
int n,m;
vector < ii > adj[1000006];
bool artPoint[1000006];
int par[1000006], num[1000006], low[1000006];
int cnt;
vector<int> G[1000006]; //Graph
vector<pair<int, int> > bridges;
int N = 6;
void dfsArticulationPointsAndBridges(int u) {
	num[u] = low[u] = cnt++;
	for (int i=0; i<(int)G[u].size(); i++) {
		int v = G[u][i];
		if (num[v] == -1) {
			par[v] = u;
			dfsArticulationPointsAndBridges(v);

			if (num[u] <= low[v]) artPoint[u] = 1;
			if (num[u] < low[v]) bridges.push_back(make_pair(u, v));
			low[u] = min(low[u], low[v]);
		} else if(par[u] != v) low[u] = min(low[u], num[v]);
	}
}

set < ii > is_bridges;
int p[1000005];
int R[1000005];
int ok[1000005];
int root(int x)
{
    while(p[x] != x)
    {
        p[x] = p[p[x]];
        x = p[x];
    }
    return x;
}
void M(int i,int j)
{
    int x = root(i),y = root(j);
    if(x != y)
    {
        int tt = max(ok[x] , ok[y]);
        ok[x] = tt;
        ok[y] = tt;
        if(R[x] > R[y])
            {
                p[y] = x;
            }
        else
            p[x] = y,R[y] += (R[x] == R[y]);
    }
}

int st,En;
int yes = 0;
int vis[1000005];
int dfs(int node,int take)
{
  vis[node] = 1;
  if(node == En)
  {
      yes = take;
  }
  for(auto x : adj[node])
  {
      int y = x.fr;
      y = root(y);
      int u = x.sc;
      int take2 = take;
      if(ok[y])
        take2 = 1;
      if(u)
        take2 = 1;
      if(!vis[y])
      {
          dfs(y,take2);
      }
  }
}
map < ii , int > F;
int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        p[i] = i;
        R[i] = 0;
    }
    vector < pair < ii , int > > all_edge;
    for(int i=0;i<m;i++)
    {
        int x,y,z;
        scanf("%d%d%d",&x,&y,&z);
        adj[x].push_back(mp(y,z));
        adj[y].push_back(mp(x,z));
        all_edge.push_back(mp(mp(x,y),z));
        G[x].push_back(y);
        G[y].push_back(x);

    }

    cin>>st>>En;
    cnt = 0;
	memset(num, -1, sizeof(num));
	memset(par, -1, sizeof(par));
	dfsArticulationPointsAndBridges(1);
	for(auto x : bridges)
    {
        is_bridges.insert(x);
        is_bridges.insert(mp(x.sc,x.fr));
    }
    for(auto x : all_edge)
    {
        if(is_bridges.find(x.fr) == is_bridges.end())
        {
            x.fr.fr = root(x.fr.fr);
            x.fr.sc = root(x.fr.sc);
            if(x.sc == 1)
            {
                ok[x.fr.fr] = 1;
                ok[x.fr.sc] = 1;
            }
            M(x.fr.fr,x.fr.sc);
        }
    }
    for(auto x : all_edge)
    {
        int c = x.fr.fr;
        int c2 = x.fr.sc;
        int val = x.sc;
        c = root(c);
        c2 = root(c2);
        adj[c].push_back(mp(c2,val));
        adj[c2].push_back(mp(c,val));
    }

    st = root(st);
    En = root(En);

    if(st == En)
    {
        int u = st;
        if(ok[u])
            cout<<"YES\n";
        else
            cout<<"NO\n";
        return 0;
    }
    dfs(st,ok[st]);
    if(yes)
        cout<<"YES\n";
    else
        cout<<"NO\n";
}


#include <bits/stdc++.h>
#define F(i,n) for (int i=1; i<=(int)n; i++)
#define FF(i,n) for (int i=0; i<(int)n; i++)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define all(x) x.begin(),x.end()
#define pi pair < int , int >
#define re(x) (int)x.size()
#define y1 u228
using namespace std;
typedef long long ll;
const int N = 3e5+228;
const int big = 2e9;
const ll md = 1e9 + 7;
int n,m,a,b,c,fup[N],tin[N],k,sv[N],timer,st,fn;
bool used[N],mrk[N],most[N],est[N];
vector < int > g[N],g1[N],g2[N];
bool ans;
void IS_BRIDGE(int x){most[x]=1;}
void dfs (int v, int p = -1) {
	used[v] = true;
	tin[v] = fup[v] = timer++;
	for (size_t i=0; i<g[v].size(); ++i) {
		int to = g[v][i];
		if (to == p)  continue;
		if (used[to])
			fup[v] = min (fup[v], tin[to]);
		else {
			dfs (to, v);
			fup[v] = min (fup[v], fup[to]);
			if (fup[to] > tin[v])
				IS_BRIDGE(g2[v][i]);
		}
	}
}
void go(int v){
    mrk[v]=1; sv[v]=k;
    FF(j,re(g[v])){
        int u=g[v][j];
        if (mrk[u] || most[g2[v][j]]) continue;
        if (g1[v][j]) est[k]=1;
        go(u);
    }
}
void go1(int v,bool ok){
    ok|=est[sv[v]];
    if (sv[v]==sv[fn]) {ans|=ok;return;}
    mrk[v]=1;
    FF(j,re(g[v])){
        int u=g[v][j];
        if (mrk[u]) continue;
        if (most[g2[v][j]])go1(u,ok|g1[v][j]); else
        go1(u,ok);
    }
}

int main()
{
    ios_base::sync_with_stdio(false);cin.tie(0);
    //freopen("input.txt","r",stdin);
//    freopen("output.txt","w",stdout);
    cin>>n>>m;
    F(i,m){
        cin>>a>>b>>c;
        g[a].pb(b);
        g[b].pb(a);
        g1[a].pb(c);
        g1[b].pb(c);
        g2[a].pb(i);
        g2[b].pb(i);
    }
    F(i,n) if (!used[i]) dfs(i);
    F(i,n) mrk[i]=0;
    F(i,n) {
        if (mrk[i]) continue;
        k++;
        go(i);
    }
    F(i,n) mrk[i]=0;
    cin>>st>>fn;
    go1(st,0);
    if (ans) cout<<"YES"; else cout<<"NO";
    return 0;
}


#include <bits/stdc++.h>
#define F(i,n) for (int i=1; i<=(int)n; i++)
#define FF(i,n) for (int i=0; i<(int)n; i++)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define all(x) x.begin(),x.end()
#define pi pair < int , int >
#define re(x) (int)x.size()
#define y1 u228
using namespace std;
typedef long long ll;
const int N = 3e5+228;
const int big = 2e9;
const ll md = 1e9 + 7;
int n,m,a,b,c,fup[N],tin[N],k,sv[N],timer,st,fn;
bool used[N],mrk[N],most[N],est[N];
vector < int > g[N],g1[N],g2[N];
bool ans;
void IS_BRIDGE(int x){most[x]=1;}
void dfs (int v, int p = -1) {
	used[v] = true;
	tin[v] = fup[v] = timer++;
	for (size_t i=0; i<g[v].size(); ++i) {
		int to = g[v][i];
		if (to == p)  continue;
		if (used[to])
			fup[v] = min (fup[v], tin[to]);
		else {
			dfs (to, v);
			fup[v] = min (fup[v], fup[to]);
			if (fup[to] > tin[v])
				IS_BRIDGE(g2[v][i]);
		}
	}
}
void go(int v){
    mrk[v]=1; sv[v]=k;
    FF(j,re(g[v])){
        int u=g[v][j];
        if (mrk[u] || most[g2[v][j]]) continue;
        if (g1[v][j]) est[k]=1;
        go(u);
    }
}
void go1(int v,bool ok){
    ok|=est[sv[v]];
    if (sv[v]==sv[fn]) {ans=ok;return;}
    mrk[v]=1;
    FF(j,re(g[v])){
        int u=g[v][j];
        if (mrk[u]) continue;
        if (most[g2[v][j]])go1(u,ok|g1[v][j]); else
        go1(u,ok);
    }
}

int main()
{
    ios_base::sync_with_stdio(false);cin.tie(0);
    //freopen("input.txt","r",stdin);
//    freopen("output.txt","w",stdout);
    cin>>n>>m;
    F(i,m){
        cin>>a>>b>>c;
        g[a].pb(b);
        g[b].pb(a);
        g1[a].pb(c);
        g1[b].pb(c);
        g2[a].pb(i);
        g2[b].pb(i);
    }
    F(i,n) if (!used[i]) dfs(i);
    F(i,n) mrk[i]=0;
    F(i,n) {
        if (mrk[i]) continue;
        k++;
        go(i);
    }
    F(i,n) mrk[i]=0;
    cin>>st>>fn;
    go1(st,0);
    if (ans) cout<<"YES"; else cout<<"NO";
    return 0;
}


#include <bits/stdc++.h>
#define F(i,n) for (int i=1; i<=(int)n; i++)
#define FF(i,n) for (int i=0; i<(int)n; i++)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define all(x) x.begin(),x.end()
#define pi pair < int , int >
#define re(x) (int)x.size()
#define y1 u228
using namespace std;
typedef long long ll;
const int N = 6e5+228;
const int big = 2e9;
const int md = 1e9 + 7;
int n,m,a,b,c,fup[N],tin[N],k,sv[N],timer,st,fn;
bool used[N],mrk[N],most[N],est[N];
vector < int > g[N],g1[N],g2[N];
bool ans;
void IS_BRIDGE(int x){most[x]=1;}
void dfs (int v, int p = -1) {
	used[v] = true;
	tin[v] = fup[v] = timer++;
	for (size_t i=0; i<g[v].size(); ++i) {
		int to = g[v][i];
		if (to == p)  continue;
		if (used[to])
			fup[v] = min (fup[v], tin[to]);
		else {
			dfs (to, v);
			fup[v] = min (fup[v], fup[to]);
			if (fup[to] > tin[v])
				IS_BRIDGE(g2[v][i]);
		}
	}
}
void go(int v){
    mrk[v]=1; sv[v]=k;
    FF(j,re(g[v])){
        int u=g[v][j];
        if (mrk[u] || most[g2[v][j]]) continue;
        if (g1[v][j]) est[k]=1;
        go(u);
    }
}
void go1(int v,bool ok){
    ok|=est[sv[v]];
    if (sv[v]==sv[fn]) {ans|=ok;return;}
    mrk[v]=1;
    FF(j,re(g[v])){
        int u=g[v][j];
        if (mrk[u]) continue;
        if (most[g2[v][j]])go1(u,ok|g1[v][j]); else
        go1(u,ok);
    }
}

int main()
{
    ios_base::sync_with_stdio(false);cin.tie(0);
    //freopen("input.txt","r",stdin);
//    freopen("output.txt","w",stdout);
    cin>>n>>m;
    F(i,m){
        cin>>a>>b>>c;
        g[a].pb(b);
        g[b].pb(a);
        g1[a].pb(c);
        g1[b].pb(c);
        g2[a].pb(i);
        g2[b].pb(i);
    }
    F(i,n) if (!used[i]) dfs(i);
    F(i,n) mrk[i]=0;
    F(i,n) {
        if (mrk[i]) continue;
        k++;
        go(i);
    }
    F(i,n) mrk[i]=0;
    cin>>st>>fn;
    go1(st,0);
    if (ans) cout<<"YES"; else cout<<"NO";
    return 0;
}


#include <bits/stdc++.h>
#define F(i,n) for (int i=1; i<=(int)n; i++)
#define FF(i,n) for (int i=0; i<(int)n; i++)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define all(x) x.begin(),x.end()
#define pi pair < int , int >
#define re(x) (int)x.size()
#define y1 u228
using namespace std;
typedef long long ll;
const int N = 6e5+228;
const int big = 2e9;
const int md = 1e9 + 7;
int n,m,a,b,c,fup[N],tin[N],k,sv[N],timer,st,fn;
bool used[N],mrk[N],most[N],est[N];
vector < int > g[N],g1[N],g2[N];
bool ans;
void IS_BRIDGE(int x){most[x]=1;}
void dfs (int v, int p = -1) {
	used[v] = true;
	tin[v] = fup[v] = timer++;
	for (size_t i=0; i<g[v].size(); ++i) {
		int to = g[v][i];
		if (to == p)  continue;
		if (used[to])
			fup[v] = min (fup[v], tin[to]);
		else {
			dfs (to, v);
			fup[v] = min (fup[v], fup[to]);
			if (fup[to] > tin[v])
				IS_BRIDGE(g2[v][i]);
		}
	}
}
void go(int v){
    mrk[v]=1; sv[v]=k;
    FF(j,re(g[v])){
        int u=g[v][j];
        if (!most[g2[v][j]]) est[k]=1;
        if (mrk[u] || most[g2[v][j]]) continue;
        go(u);
    }
}
void go1(int v,bool ok){
    ok|=est[sv[v]];
    if (sv[v]==sv[fn]) {ans|=ok;return;}
    mrk[v]=1;
    FF(j,re(g[v])){
        int u=g[v][j];
        if (mrk[u]) continue;
        if (most[g2[v][j]])go1(u,ok|g1[v][j]); else
        go1(u,ok);
    }
}

int main()
{
    ios_base::sync_with_stdio(false);cin.tie(0);
    //freopen("input.txt","r",stdin);
//    freopen("output.txt","w",stdout);
    cin>>n>>m;
    F(i,m){
        cin>>a>>b>>c;
        g[a].pb(b);
        g[b].pb(a);
        g1[a].pb(c);
        g1[b].pb(c);
        g2[a].pb(i);
        g2[b].pb(i);
    }
    F(i,n) if (!used[i]) dfs(i);
    F(i,n) mrk[i]=0;
    F(i,n) {
        if (mrk[i]) continue;
        k++;
        go(i);
    }
    F(i,n) mrk[i]=0;
    cin>>st>>fn;
    go1(st,0);
    if (ans) cout<<"YES"; else cout<<"NO";
    return 0;
}


#include <bits/stdc++.h>
#define F(i,n) for (int i=1; i<=(int)n; i++)
#define FF(i,n) for (int i=0; i<(int)n; i++)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define all(x) x.begin(),x.end()
#define pi pair < int , int >
#define re(x) (int)x.size()
#define y1 u228
using namespace std;
typedef long long ll;
const int N = 6e5+228;
const int big = 2e9;
const int md = 1e9 + 7;
int n,m,a,b,c,fup[N],tin[N],k,sv[N],timer,st,fn;
bool used[N],mrk[N],most[N],est[N];
vector < int > g[N],g1[N],g2[N];
bool ans;
void IS_BRIDGE(int x){most[x]=1;}
void dfs (int v, int p = -1) {
	used[v] = true;
	tin[v] = fup[v] = timer++;
	for (size_t i=0; i<g[v].size(); ++i) {
		int to = g[v][i];
		if (to == p)  continue;
		if (used[to])
			fup[v] = min (fup[v], tin[to]);
		else {
			dfs (to, v);
			fup[v] = min (fup[v], fup[to]);
			if (fup[to] > tin[v])
				IS_BRIDGE(g2[v][i]);
		}
	}
}
void go(int v){
    mrk[v]=1; sv[v]=k;
    FF(j,re(g[v])){
        int u=g[v][j];
        if (!most[g2[v][j]]) est[k]|=g1[v][j];
        if (mrk[u] || most[g2[v][j]]) continue;
        go(u);
    }
}
void go1(int v,bool ok){
    ok|=est[sv[v]];
    if (sv[v]==sv[fn]) {ans|=ok;return;}
    mrk[v]=1;
    FF(j,re(g[v])){
        int u=g[v][j];
        if (mrk[u]) continue;
        if (most[g2[v][j]])go1(u,ok|g1[v][j]); else
        go1(u,ok);
    }
}

int main()
{
    ios_base::sync_with_stdio(false);cin.tie(0);
    //freopen("input.txt","r",stdin);
//    freopen("output.txt","w",stdout);
    cin>>n>>m;
    F(i,m){
        cin>>a>>b>>c;
        g[a].pb(b);
        g[b].pb(a);
        g1[a].pb(c);
        g1[b].pb(c);
        g2[a].pb(i);
        g2[b].pb(i);
    }
    F(i,n) if (!used[i]) dfs(i);
    F(i,n) mrk[i]=0;
    F(i,n) {
        if (mrk[i]) continue;
        k++;
        go(i);
    }
    F(i,n) mrk[i]=0;
    cin>>st>>fn;
    go1(st,0);
    if (ans) cout<<"YES"; else cout<<"NO";
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
long long const N = 300001;
int num[N] , low[N ] ;
int dx[N];
int cha[N];
int cnt = 0;
int n,m,u,v,w  , x , y;
vector < pair < int, int >  > a[N],b[N];
struct data
{
    int u,v,w;
};
data make_data(int u,int v ,int w)
{
    data a;
    a.u= u;
    a.v= v;
    a.w= w;
    return a;
}
vector < data > c;
void dfs( int u , int uu,int dxx)
{
    int v,w;
    num[u]=low[u]=++cnt;
    for (int i=0;i<a[u].size();i++)
    {
        v= a[u][i].first;
        w= a[u][i].second;
        if (v == uu) continue ;
        if (num[v]==0)
        {
            dfs( v, u , w);
            low[u] = min( low[u] , low[v]);
            if ( low[v] >= num[v] )
            {
         //       cout<<" convert "<<u<<" -- "<<v<<endl;
                c.push_back( make_data(u,v,w) );
            }
            else
            {
                cha[u] = cha[uu];
            }
        } else low[u] = min( low[u] , num[v] );
    }
    if (low[u]==num[u]) cha[u]=u;
    else
        {
            cha[u]=uu;
            dx[u] = dxx;
        }
}

int find_cha(int x)
{
    if ( low[x] == num[x] ) return x;
    return find_cha( cha[x] );
}

int timkiem(int u ,int uu, int kt)
{
    if ( (u == y ) && (kt == 1) )
    {
        cout<<"YES";
        exit(0);
    }
    for (int i=0;i< b[u].size();i++)
    {
        v = b[u][i].first;
        w = b[u][i].second;
        if (v==uu) continue ;
        if (dx[v]==1 || w==1)
        {timkiem( v , u , 1 );continue;};
        timkiem( v , u ,  kt ) ;
    }
}
int main()
{
   // freopen("652E.inp","r",stdin);
    //freopen("652E.out","w",stdout);
    ios_base::sync_with_stdio();
    cin.tie(0);cout.tie(0);
    cin>>n>>m;
    cha[1] =1 ;
    for (int i=1;i<=m;i++)
    {
        cin>>u>>v>>w;
        a[u].push_back( make_pair (v,w) );
        a[v].push_back( make_pair (u,w) );

     //   cout<<u<<" - "<<v<<endl;
    }
    dfs( 1, 1, 0);
    cin>>x>>y;

    for (int i=1;i<=n;i++)
    {
        int xx = find_cha(i);
        cha[i] = xx;
        if (dx[i]==1) dx[xx] = 1;
    }
   // for (int i=1;i<=n;i++) cout<<i<<" "<<cha[i]<<" "<<dx[i]<<endl;
    for (int i=0;i< c.size();i++)
    {
        u = cha[ c[i].u ];
        v = cha[ c[i].v ];
        w = cha[ c[i].w ];
        b[u].push_back( make_pair(v,w) );
        b[v].push_back( make_pair(u,w) );
    }
    y=cha[y];
    if (dx[cha[x]] == 0 ) timkiem( cha[x] , -1 , 0 );else timkiem( cha[x] , -1 , 1);
    cout<<"NO";
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
long long const N = 300001;
int num[N] , low[N ] ;
int dx[N];
int cha[N];
int cnt = 0;
int n,m,u,v,w  , x , y;
vector < pair < int, int >  > a[N],b[N];
struct data
{
    int u,v,w;
};
data make_data(int u,int v ,int w)
{
    data a;
    a.u= u;
    a.v= v;
    a.w= w;
    return a;
}
vector < data > c;
void dfs( int u , int uu,int dxx)
{
    int v,w;
    num[u]=low[u]=++cnt;
    for (int i=0;i<a[u].size();i++)
    {
        v= a[u][i].first;
        w= a[u][i].second;
        if (v == uu) continue ;
        if (num[v]==0)
        {
            dfs( v, u , w);
            low[u] = min( low[u] , low[v]);
            if ( low[v] >= num[v] )
            {
          //     cout<<" convert "<<u<<" -- "<<v<<endl;
                c.push_back( make_data(u,v,w) );
            }
            else
            {
          //      cout<<" Sum "<<u<<" "<<v<<" "<<w<<endl;
                cha[v] = u;
                if (w==1)
                {
                    dx[u]=dx[v]=1;
                }
            }
        } else
        {
            low[u] = min( low[u] , num[v] );
          //   cout<<" Sum "<<u<<" "<<v<<" "<<w<<endl;
                cha[v] = u;
                if (w==1)
                {
                    dx[u]=dx[v]=1;
                }
        }
    }
    if (low[u]==num[u]) cha[u]=u;
    else
        {
            cha[u]=uu;
            dx[u]=dxx;
        }
}

int find_cha(int x)
{
    if ( low[x] == num[x] ) return x;
    return cha[x]= find_cha( cha[x] );
}

int timkiem(int u ,int uu, int kt)
{
    if ( (u == y ) && (kt == 1) )
    {
        cout<<"YES";
        exit(0);
    }
    for (int i=0;i< b[u].size();i++)
    {
        v = b[u][i].first;
        w = b[u][i].second;
        if (v==uu) continue ;
        if (dx[v]==1 || w==1)
        {timkiem( v , u , 1 );continue;};
        timkiem( v , u ,  kt ) ;
    }
}
int main()
{
 //   freopen("652E.inp","r",stdin);
  //  freopen("652E.out","w",stdout);
    ios_base::sync_with_stdio();
    cin.tie(0);cout.tie(0);
    cin>>n>>m;
    cha[1] =1 ;
    for (int i=1;i<=m;i++)
    {
        cin>>u>>v>>w;
        a[u].push_back( make_pair (v,w) );
        a[v].push_back( make_pair (u,w) );

    }
    dfs( 1, 1, 0);
    cin>>x>>y;

   // for (int i=1;i<=n;i++) cout<<i<<" "<<cha[i]<<" "<<dx[i]<<endl;

    for (int i=1;i<=n;i++)
    {
        int xx = find_cha(i);
    }

    for (int i=1;i<=n;i++) if (dx[i]==1) dx[cha[i]]= 1;

 //   for (int i=1;i<=n;i++) cout<<i<<" "<<cha[i]<<" "<<dx[i]<<endl;

    for (int i=0;i< c.size();i++)
    {
        u = cha[ c[i].u ];
        v = cha[ c[i].v ];
        w = cha[ c[i].w ];
        b[u].push_back( make_pair(v,w) );
        b[v].push_back( make_pair(u,w) );
    }
    y=cha[y];
    if (dx[cha[x]] == 0 ) timkiem( cha[x] , -1 , 0 );else timkiem( cha[x] , -1 , 1);
    cout<<"NO";

    return 0;
}


#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<math.h>
#include<bits/stdc++.h>
#include<stack>
#include<queue>
#include<list>
#include<vector>
#include<bitset>
#include<unordered_map>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
// #include "boost/algorithm/string.hpp"
#define fio ios_base::sync_with_stdio(false)
#define mod 998244353
#define mod1 mod
#define mod2 100000009
#define li long long int
#define ll li
#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#define readi(x) scanf("%d",&x)
#define  reads(x)  scanf("%s", x)
#define readl(x) scanf("%I64d",&x)
#define rep(i,n) for(i=0;i<n;i++)
#define revp(i,n) for(i=(n-1);i>=0;i--)
#define myrep1(i,a,b) for(i=a;i<=b;i++)
#define myrep2(i,a,b) for(i=b;i>=a;i--)
#define pb push_back
#define mp make_pair
#define fi first
#define sec second
#define MAXN 1000000000000000005
#define MINN -10000000000000000
#define INTMAX 1000001000
#define pii pair<ll,ll>
#define pdd pair<double,double>
#define pic pair<int,char>
#define N 200010
#define lgn 20
#define ddouble long double
#define minus minu
#define PI 3.1415926535
#define lgn 20

// #define INTMAX 200000000

// using namespace boost;
// #define si short int

using namespace std;
using namespace __gnu_pbds;
typedef priority_queue<ll, vector<ll > > max_pq;
typedef priority_queue<pii, vector<pii> , greater<pii>  > min_pq;
ll toint(const string &s) {stringstream ss; ss << s; ll x; ss >> x; return x;}
string tostring ( ll number ){stringstream ss; ss<< number; return ss.str();}

// using namespace __gnu_pbds;
// typedef priority_queue<pair<ll,char> , vector<pair<ll , char> > > max_pq;
// typedef priority_queue<pii , vector<pii > ,greater<pii > > min_pq;
typedef tree<ll , null_type, less<ll>, rb_tree_tag, tree_order_statistics_node_update> OST;
// typedef priority_queue<pair < ll , pair < pii , ll > >  , vector<pair < ll , pair < pii , ll > >  > ,greater<pair < ll , pair < pii , ll > >  > > min_pq;
#define TRACE
#ifdef TRACE
#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
    template <typename Arg1>
    void __f(const char* name, Arg1&& arg1){
        cout << name << " : " << arg1 << std::endl;
        //use cerr if u want to display at the bottom
    }
    template <typename Arg1, typename... Args>
    void __f(const char* names, Arg1&& arg1, Args&&... args){
        const char* comma = strchr(names + 1, ','); cout.write(names, comma - names) << " : " << arg1<<" | ";__f(comma+1, args...);
    }
#else
#define trace(...)
#endif
bool visited[ N ];
ll n,m;
ll disc[ N ], low[ N ];
bool ap[ N ];
set < pii > bridges;
vector < vector < ll > > adjlist ( N );
vector < vector < ll > > scclist ( N );
vector < vector < pii > > treelist ( N );
map < pii, ll > cost;
vector < pair < ll, pii>  > edges;
ll col[ N ];
char c[ N ];
ll which = 0;
ll dist[ N ];
ll maxcost[ N ];
void dfs ( ll i, ll par , ll ti )
{
    visited[i] = 1;
    disc[i] = low[i] = ti;
    ll ch = 0;
    for ( auto it : adjlist[i] )
    {
        if ( !visited[it] )
        {
            dfs(it,i,ti+1);
            ch ++;
            low[i] = min(low[i],low[it]);
            if ( par == -1 and ch > 1 )
                ap[i]=1;
            if ( par != -1 and low[it] >= disc[i] )
                ap[i]=1;
            if ( low[it] > disc[i] )
                bridges.insert({min(i,it),max(it,i)});
        }
        else if ( it != par )
        {
            low[i] = min(low[i],disc[it]);
        }
    }
}
void dfs2 ( ll i ){
    visited[i] = 1;
    col[i] = (which);
    for ( auto it : scclist[i] ){
        if ( !visited[it] ){
            dfs2(it);
            maxcost[which] = max(maxcost[which],cost[{min(i,it),max(i,it)}]);
        }
    }
}
ll fans = 0;
void init ( ){
    memset(ap,0,sizeof ap);
    memset(visited,0,sizeof visited);
    which = 0;
    fans =0;
}
void dijkstra( )
{
    for ( ll i = 0; i <= n; i ++)
        dist[i] = INT_MAX,visited[i]=0;// check max
    set < pii > pq;
    // pq.insert({0,s});
    for ( ll i = 1; i <= n; i ++){
        if ( c[i] == 'A' ){
            pq.insert({0,col[i]});
            dist[col[i]] = 0;
        }
    }

    ll ansmax = INT_MIN, cnt = 0;
    while ( !pq.empty() )
    {
        ll node = (*pq.begin()).sec;
        ll d = (*pq.begin()).fi;
        visited[node] = 1;
        if ( d > ansmax )
            ansmax = d, cnt = 1;
        else if ( d == ansmax )
            cnt++;
        pq.erase(pq.begin());
        for ( auto it : treelist[node] )
        {
            if ( !visited[it.fi] and ((d+it.sec)<dist[it.fi]) )
            {
                if ( dist[it.fi] != INT_MAX )
                    pq.erase({dist[it.fi],it.fi});
                dist[it.fi] = d + it.sec;
                pq.insert({d+it.sec,it.fi});
            }
        }
    }
    ll fans = 0;
    for ( ll i = 1; i <= n; i ++)
        if ( c[i] == 'H' )
            fans += dist[col[i]];
    cout << fans <<"\n";
    // cout << ansmax <<" " << cnt <<"\n";
}
ll acnt[ N ], hcnt[ N ];
ll T[ N ], L[ N ];
map < pii, ll > treecost;
void dp ( ll i, ll par ){
    visited[i] =1;
    T[i] = par;
    L[i] = L[par] + 1;
    for ( auto it : treelist[i] ){
        if ( it.fi != par ){
            treecost[{min(i,it.fi),max(i,it.fi)}] = it.sec;
            dp(it.fi,i);
        }
    }
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    #ifndef ONLINE_JUDGE
    freopen("input.txt","r",stdin);
    freopen("output.txt","w",stdout);
    #endif
    ll t;
    // cin >> t;
    t = 1;
    while ( t-- ){
        init();
        cin >> n >> m;
        while ( m -- ){
            ll x,y,c;
            cin >> x >> y >> c;
            adjlist[x].pb(y);
            adjlist[y].pb(x);
            cost[{min(x,y),max(x,y)}]=c;
            edges.pb({c,{min(x,y),max(x,y)}});
        }
        for ( ll i = 1; i <= n; i ++)
            if (!visited[i] )
                dfs(i,-1,1);
        for ( auto it : edges)
        {
            if ( bridges.find(it.sec) == bridges.end() ){
                scclist[it.sec.fi].pb(it.sec.sec);
                scclist[it.sec.sec].pb(it.sec.fi);
            }
        }
        memset(visited,0,sizeof visited);
        for ( ll i = 1; i <= n; i ++){
            if ( !visited[i] ){
                which++;
                dfs2(i);
            }
        }
        // for ( ll i = 1; i <= n; i ++)
        //     trace(i,col[i]);
        // treesize = which
        ll u,v;
        for ( auto it : bridges ){
            u = min(it.fi,it.sec);
            v = max(it.fi,it.sec);
            // trace(u,v);
            treelist[col[u]].pb({col[v],cost[{u,v}]});
            treelist[col[v]].pb({col[u],cost[{u,v}]});
        }
        ll a,b;
        cin >> a >> b;
        a = col[a], b=col[b];
        dp(1,0);
        if ( L[a] > L[b] )
            swap(a,b);
        bool flg = 0;
        flg |= maxcost[a];
        flg |= maxcost[b];
        while ( L[b] > L[a] ){
            flg |= treecost[{min(T[b],b),max(T[b],b)}];
            b = T[b];
        }
        while ( a != b ){
            flg |= treecost[{min(T[b],b),max(T[b],b)}];
            flg |= treecost[{min(T[a],a),max(T[a],a)}];
            a = T[a];
            b = T[b];
        }
        if ( flg )
            cout <<"YES";
        else
            cout <<"NO";

        // for ( ll i = 1; i <= n; i ++){
        //     if ( c[i] == 'H' )
        //         hcnt[col[i]]++;
        //     else if ( c[i] == 'A' )
        //         acnt[col[i]]++;
        // }
        // memset(visited,0,sizeof visited);
        // // trace(which);
        // for ( ll i = 1; i <= which; i ++){
        //     if ( !visited[i] ){
        //         // trace(i);
        //         dp(i,0);
        //     }
        // }
        // cout << fans <<"\n";
        // // dijkstra();
        // bridges.clear();
        // edges.clear();
        // for ( ll i = 1; i <= n; i ++){
        //     adjlist[i].clear();
        //     scclist[i].clear();
        //     treelist[i].clear();
        //     acnt[i] = 0, hcnt[i] = 0;
        // }
    }

}


#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<math.h>
#include<bits/stdc++.h>
#include<stack>
#include<queue>
#include<list>
#include<vector>
#include<bitset>
#include<unordered_map>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
// #include "boost/algorithm/string.hpp"
#define fio ios_base::sync_with_stdio(false)
#define mod 998244353
#define mod1 mod
#define mod2 100000009
#define li long long int
#define ll li
#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#define readi(x) scanf("%d",&x)
#define  reads(x)  scanf("%s", x)
#define readl(x) scanf("%I64d",&x)
#define rep(i,n) for(i=0;i<n;i++)
#define revp(i,n) for(i=(n-1);i>=0;i--)
#define myrep1(i,a,b) for(i=a;i<=b;i++)
#define myrep2(i,a,b) for(i=b;i>=a;i--)
#define pb push_back
#define mp make_pair
#define fi first
#define sec second
#define MAXN 1000000000000000005
#define MINN -10000000000000000
#define INTMAX 1000001000
#define pii pair<ll,ll>
#define pdd pair<double,double>
#define pic pair<int,char>
#define N 400010
#define lgn 20
#define ddouble long double
#define minus minu
#define PI 3.1415926535
#define lgn 20

// #define INTMAX 200000000

// using namespace boost;
// #define si short int

using namespace std;
using namespace __gnu_pbds;
typedef priority_queue<ll, vector<ll > > max_pq;
typedef priority_queue<pii, vector<pii> , greater<pii>  > min_pq;
ll toint(const string &s) {stringstream ss; ss << s; ll x; ss >> x; return x;}
string tostring ( ll number ){stringstream ss; ss<< number; return ss.str();}

// using namespace __gnu_pbds;
// typedef priority_queue<pair<ll,char> , vector<pair<ll , char> > > max_pq;
// typedef priority_queue<pii , vector<pii > ,greater<pii > > min_pq;
typedef tree<ll , null_type, less<ll>, rb_tree_tag, tree_order_statistics_node_update> OST;
// typedef priority_queue<pair < ll , pair < pii , ll > >  , vector<pair < ll , pair < pii , ll > >  > ,greater<pair < ll , pair < pii , ll > >  > > min_pq;
#define TRACE
#ifdef TRACE
#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
    template <typename Arg1>
    void __f(const char* name, Arg1&& arg1){
        cout << name << " : " << arg1 << std::endl;
        //use cerr if u want to display at the bottom
    }
    template <typename Arg1, typename... Args>
    void __f(const char* names, Arg1&& arg1, Args&&... args){
        const char* comma = strchr(names + 1, ','); cout.write(names, comma - names) << " : " << arg1<<" | ";__f(comma+1, args...);
    }
#else
#define trace(...)
#endif
bool visited[ N ];
ll n,m;
ll disc[ N ], low[ N ];
bool ap[ N ];
set < pii > bridges;
vector < vector < ll > > adjlist ( N );
vector < vector < ll > > scclist ( N );
vector < vector < pii > > treelist ( N );
map < pii, ll > cost;
vector < pair < ll, pii>  > edges;
ll col[ N ];
char c[ N ];
ll which = 0;
ll dist[ N ];
ll maxcost[ N ];
void dfs ( ll i, ll par , ll ti )
{
    visited[i] = 1;
    disc[i] = low[i] = ti;
    ll ch = 0;
    for ( auto it : adjlist[i] )
    {
        if ( !visited[it] )
        {
            dfs(it,i,ti+1);
            ch ++;
            low[i] = min(low[i],low[it]);
            if ( par == -1 and ch > 1 )
                ap[i]=1;
            if ( par != -1 and low[it] >= disc[i] )
                ap[i]=1;
            if ( low[it] > disc[i] )
                bridges.insert({min(i,it),max(it,i)});
        }
        else if ( it != par )
        {
            low[i] = min(low[i],disc[it]);
        }
    }
}
void dfs2 ( ll i ){
    visited[i] = 1;
    col[i] = (which);
    for ( auto it : scclist[i] ){
        if ( !visited[it] ){
            dfs2(it);
            maxcost[which] = max(maxcost[which],cost[{min(i,it),max(i,it)}]);
        }
    }
}
ll fans = 0;
void init ( ){
    memset(ap,0,sizeof ap);
    memset(visited,0,sizeof visited);
    which = 0;
    fans =0;
}
ll acnt[ N ], hcnt[ N ];
ll T[ N ], L[ N ];
map < pii, ll > treecost;
void dp ( ll i, ll par ){
    visited[i] =1;
    T[i] = par;
    L[i] = L[par] + 1;
    for ( auto it : treelist[i] ){
        if ( it.fi != par ){
            treecost[{min(i,it.fi),max(i,it.fi)}] = it.sec;
            dp(it.fi,i);
        }
    }
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    #ifndef ONLINE_JUDGE
    freopen("input.txt","r",stdin);
    freopen("output.txt","w",stdout);
    #endif
    ll t;
    // cin >> t;
    t = 1;
    while ( t-- ){
        init();
        cin >> n >> m;
        while ( m -- ){
            ll x,y,c;
            cin >> x >> y >> c;
            adjlist[x].pb(y);
            adjlist[y].pb(x);
            cost[{min(x,y),max(x,y)}]=c;
            edges.pb({c,{min(x,y),max(x,y)}});
        }
        for ( ll i = 1; i <= n; i ++)
            if (!visited[i] )
                dfs(i,-1,1);
        for ( auto it : edges)
        {
            if ( bridges.find(it.sec) == bridges.end() ){
                scclist[it.sec.fi].pb(it.sec.sec);
                scclist[it.sec.sec].pb(it.sec.fi);
            }
        }
        memset(visited,0,sizeof visited);
        for ( ll i = 1; i <= n; i ++){
            if ( !visited[i] ){
                which++;
                dfs2(i);
            }
        }
        // treesize = which
        ll u,v;
        for ( auto it : bridges ){
            u = min(it.fi,it.sec);
            v = max(it.fi,it.sec);
            // trace(u,v);
            treelist[col[u]].pb({col[v],cost[{u,v}]});
            treelist[col[v]].pb({col[u],cost[{u,v}]});
        }
        ll a,b;
        cin >> a >> b;
        a = col[a], b=col[b];
        dp(1,0);
        if ( L[a] > L[b] )
            swap(a,b);
        bool flg = 0;
        flg |= maxcost[a];
        flg |= maxcost[b];
        while ( L[b] > L[a] ){
            flg |= treecost[{min(T[b],b),max(T[b],b)}];
            b = T[b];
            flg |= maxcost[b];
        }
        while ( a != b ){
            flg |= treecost[{min(T[b],b),max(T[b],b)}];
            flg |= treecost[{min(T[a],a),max(T[a],a)}];
            a = T[a];
            b = T[b];
            flg |= maxcost[b];
            flg |= maxcost[a];
        }
        assert(a != 0 );
        if ( flg )
            cout <<"YES";
        else
            cout <<"NO";

        // for ( ll i = 1; i <= n; i ++){
        //     if ( c[i] == 'H' )
        //         hcnt[col[i]]++;
        //     else if ( c[i] == 'A' )
        //         acnt[col[i]]++;
        // }
        // memset(visited,0,sizeof visited);
        // // trace(which);
        // for ( ll i = 1; i <= which; i ++){
        //     if ( !visited[i] ){
        //         // trace(i);
        //         dp(i,0);
        //     }
        // }
        // cout << fans <<"\n";
        // // dijkstra();
        // bridges.clear();
        // edges.clear();
        // for ( ll i = 1; i <= n; i ++){
        //     adjlist[i].clear();
        //     scclist[i].clear();
        //     treelist[i].clear();
        //     acnt[i] = 0, hcnt[i] = 0;
        // }
    }

}


#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<math.h>
#include<bits/stdc++.h>
#include<stack>
#include<queue>
#include<list>
#include<vector>
#include<bitset>
#include<unordered_map>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
// #include "boost/algorithm/string.hpp"
#define fio ios_base::sync_with_stdio(false)
#define mod 998244353
#define mod1 mod
#define mod2 100000009
#define li long long int
#define ll li
#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#define readi(x) scanf("%d",&x)
#define  reads(x)  scanf("%s", x)
#define readl(x) scanf("%I64d",&x)
#define rep(i,n) for(i=0;i<n;i++)
#define revp(i,n) for(i=(n-1);i>=0;i--)
#define myrep1(i,a,b) for(i=a;i<=b;i++)
#define myrep2(i,a,b) for(i=b;i>=a;i--)
#define pb push_back
#define mp make_pair
#define fi first
#define sec second
#define MAXN 1000000000000000005
#define MINN -10000000000000000
#define INTMAX 1000001000
#define pii pair<ll,ll>
#define pdd pair<double,double>
#define pic pair<int,char>
#define N 400010
#define lgn 20
#define ddouble long double
#define minus minu
#define PI 3.1415926535
#define lgn 20

// #define INTMAX 200000000

// using namespace boost;
// #define si short int

using namespace std;
using namespace __gnu_pbds;
typedef priority_queue<ll, vector<ll > > max_pq;
typedef priority_queue<pii, vector<pii> , greater<pii>  > min_pq;
ll toint(const string &s) {stringstream ss; ss << s; ll x; ss >> x; return x;}
string tostring ( ll number ){stringstream ss; ss<< number; return ss.str();}

// using namespace __gnu_pbds;
// typedef priority_queue<pair<ll,char> , vector<pair<ll , char> > > max_pq;
// typedef priority_queue<pii , vector<pii > ,greater<pii > > min_pq;
typedef tree<ll , null_type, less<ll>, rb_tree_tag, tree_order_statistics_node_update> OST;
// typedef priority_queue<pair < ll , pair < pii , ll > >  , vector<pair < ll , pair < pii , ll > >  > ,greater<pair < ll , pair < pii , ll > >  > > min_pq;
#define TRACE
#ifdef TRACE
#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
    template <typename Arg1>
    void __f(const char* name, Arg1&& arg1){
        cout << name << " : " << arg1 << std::endl;
        //use cerr if u want to display at the bottom
    }
    template <typename Arg1, typename... Args>
    void __f(const char* names, Arg1&& arg1, Args&&... args){
        const char* comma = strchr(names + 1, ','); cout.write(names, comma - names) << " : " << arg1<<" | ";__f(comma+1, args...);
    }
#else
#define trace(...)
#endif
bool visited[ N ];
ll n,m;
ll disc[ N ], low[ N ];
bool ap[ N ];
set < pii > bridges;
vector < vector < ll > > adjlist ( N );
vector < vector < ll > > scclist ( N );
vector < vector < pii > > treelist ( N );
map < pii, ll > cost;
vector < pair < ll, pii>  > edges;
ll col[ N ];
char c[ N ];
ll which = 0;
ll dist[ N ];
ll maxcost[ N ];
void dfs ( ll i, ll par , ll ti )
{
    visited[i] = 1;
    disc[i] = low[i] = ti;
    ll ch = 0;
    for ( auto it : adjlist[i] )
    {
        if ( !visited[it] )
        {
            dfs(it,i,ti+1);
            ch ++;
            low[i] = min(low[i],low[it]);
            if ( par == -1 and ch > 1 )
                ap[i]=1;
            if ( par != -1 and low[it] >= disc[i] )
                ap[i]=1;
            if ( low[it] > disc[i] )
                bridges.insert({min(i,it),max(it,i)});
        }
        else if ( it != par )
        {
            low[i] = min(low[i],disc[it]);
        }
    }
}
void dfs2 ( ll i ){
    visited[i] = 1;
    col[i] = (which);
    for ( auto it : scclist[i] ){
        if ( !visited[it] ){
            dfs2(it);
            // trace(i,it);
            maxcost[which] = max(maxcost[which],cost[{min(i,it),max(i,it)}]);
        }
        else{
            maxcost[which] = max(maxcost[which],cost[{min(i,it),max(i,it)}]);
        }
    }
}
ll fans = 0;
void init ( ){
    memset(ap,0,sizeof ap);
    memset(visited,0,sizeof visited);
    which = 0;
    fans =0;
}
ll acnt[ N ], hcnt[ N ];
ll T[ N ], L[ N ];
map < pii, ll > treecost;
void dp ( ll i, ll par ){
    visited[i] =1;
    T[i] = par;
    L[i] = L[par] + 1;
    for ( auto it : treelist[i] ){
        if ( it.fi != par ){
            treecost[{min(i,it.fi),max(i,it.fi)}] = it.sec;
            dp(it.fi,i);
        }
    }
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    #ifndef ONLINE_JUDGE
    freopen("input.txt","r",stdin);
    freopen("output.txt","w",stdout);
    #endif
    ll t;
    // cin >> t;
    t = 1;
    while ( t-- ){
        init();
        cin >> n >> m;
        while ( m -- ){
            ll x,y,c;
            cin >> x >> y >> c;
            adjlist[x].pb(y);
            adjlist[y].pb(x);
            cost[{min(x,y),max(x,y)}]=c;
            edges.pb({c,{min(x,y),max(x,y)}});
        }
        for ( ll i = 1; i <= n; i ++)
            if (!visited[i] )
                dfs(i,-1,1);
        for ( auto it : edges)
        {
            if ( bridges.find(it.sec) == bridges.end() ){
                // trace(it.sec.fi,it.sec.sec);
                scclist[it.sec.fi].pb(it.sec.sec);
                scclist[it.sec.sec].pb(it.sec.fi);
            }
        }
        memset(visited,0,sizeof visited);
        for ( ll i = 1; i <= n; i ++){
            if ( !visited[i] ){
                which++;
                dfs2(i);
            }
        }
        // treesize = which
        // trace(which);
        // for ( ll i = 1; i <= 3; i ++)
        //     trace(maxcost[i]);
        ll u,v;
        for ( auto it : bridges ){
            u = min(it.fi,it.sec);
            v = max(it.fi,it.sec);
            // trace(u,v);
            treelist[col[u]].pb({col[v],cost[{u,v}]});
            treelist[col[v]].pb({col[u],cost[{u,v}]});
        }
        ll a,b;
        cin >> a >> b;
        a = col[a], b=col[b];
        dp(1,0);
        if ( L[a] > L[b] )
            swap(a,b);
        bool flg = 0;
        flg |= maxcost[a];
        flg |= maxcost[b];
        while ( L[b] > L[a] ){
            flg |= treecost[{min(T[b],b),max(T[b],b)}];
            b = T[b];
            flg |= maxcost[b];
        }
        while ( a != b ){
            flg |= treecost[{min(T[b],b),max(T[b],b)}];
            flg |= treecost[{min(T[a],a),max(T[a],a)}];
            a = T[a];
            b = T[b];
            flg |= maxcost[b];
            flg |= maxcost[a];
        }
        assert(a != 0 );
        if ( flg )
            cout <<"YES";
        else
            cout <<"NO";

        // for ( ll i = 1; i <= n; i ++){
        //     if ( c[i] == 'H' )
        //         hcnt[col[i]]++;
        //     else if ( c[i] == 'A' )
        //         acnt[col[i]]++;
        // }
        // memset(visited,0,sizeof visited);
        // // trace(which);
        // for ( ll i = 1; i <= which; i ++){
        //     if ( !visited[i] ){
        //         // trace(i);
        //         dp(i,0);
        //     }
        // }
        // cout << fans <<"\n";
        // // dijkstra();
        // bridges.clear();
        // edges.clear();
        // for ( ll i = 1; i <= n; i ++){
        //     adjlist[i].clear();
        //     scclist[i].clear();
        //     treelist[i].clear();
        //     acnt[i] = 0, hcnt[i] = 0;
        // }
    }

}


#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<math.h>
#include<bits/stdc++.h>
#include<stack>
#include<queue>
#include<list>
#include<vector>
#include<bitset>
#include<unordered_map>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
// #include "boost/algorithm/string.hpp"
#define fio ios_base::sync_with_stdio(false)
#define mod 998244353
#define mod1 mod
#define mod2 100000009
#define li long long int
#define ll li
#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#define readi(x) scanf("%d",&x)
#define  reads(x)  scanf("%s", x)
#define readl(x) scanf("%I64d",&x)
#define rep(i,n) for(i=0;i<n;i++)
#define revp(i,n) for(i=(n-1);i>=0;i--)
#define myrep1(i,a,b) for(i=a;i<=b;i++)
#define myrep2(i,a,b) for(i=b;i>=a;i--)
#define pb push_back
#define mp make_pair
#define fi first
#define sec second
#define MAXN 1000000000000000005
#define MINN -10000000000000000
#define INTMAX 1000001000
#define pii pair<ll,ll>
#define pdd pair<double,double>
#define pic pair<int,char>
#define N 400010
#define lgn 20
#define ddouble long double
#define minus minu
#define PI 3.1415926535
#define lgn 20

// #define INTMAX 200000000

// using namespace boost;
// #define si short int

using namespace std;
using namespace __gnu_pbds;
typedef priority_queue<ll, vector<ll > > max_pq;
typedef priority_queue<pii, vector<pii> , greater<pii>  > min_pq;
ll toint(const string &s) {stringstream ss; ss << s; ll x; ss >> x; return x;}
string tostring ( ll number ){stringstream ss; ss<< number; return ss.str();}

// using namespace __gnu_pbds;
// typedef priority_queue<pair<ll,char> , vector<pair<ll , char> > > max_pq;
// typedef priority_queue<pii , vector<pii > ,greater<pii > > min_pq;
typedef tree<ll , null_type, less<ll>, rb_tree_tag, tree_order_statistics_node_update> OST;
// typedef priority_queue<pair < ll , pair < pii , ll > >  , vector<pair < ll , pair < pii , ll > >  > ,greater<pair < ll , pair < pii , ll > >  > > min_pq;
#define TRACE
#ifdef TRACE
#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
    template <typename Arg1>
    void __f(const char* name, Arg1&& arg1){
        cout << name << " : " << arg1 << std::endl;
        //use cerr if u want to display at the bottom
    }
    template <typename Arg1, typename... Args>
    void __f(const char* names, Arg1&& arg1, Args&&... args){
        const char* comma = strchr(names + 1, ','); cout.write(names, comma - names) << " : " << arg1<<" | ";__f(comma+1, args...);
    }
#else
#define trace(...)
#endif
bool visited[ N ];
ll n,m;
ll disc[ N ], low[ N ];
bool ap[ N ];
set < pii > bridges;
vector < vector < ll > > adjlist ( N );
vector < vector < ll > > scclist ( N );
vector < vector < pii > > treelist ( N );
map < pii, ll > cost;
vector < pair < ll, pii>  > edges;
ll col[ N ];
char c[ N ];
ll which = 0;
ll dist[ N ];
ll maxcost[ N ];
void dfs ( ll i, ll par , ll ti )
{
    visited[i] = 1;
    disc[i] = low[i] = ti;
    ll ch = 0;
    for ( auto it : adjlist[i] )
    {
        if ( !visited[it] )
        {
            dfs(it,i,ti+1);
            ch ++;
            low[i] = min(low[i],low[it]);
            if ( par == -1 and ch > 1 )
                ap[i]=1;
            if ( par != -1 and low[it] >= disc[i] )
                ap[i]=1;
            if ( low[it] > disc[i] )
                bridges.insert({min(i,it),max(it,i)});
        }
        else if ( it != par )
        {
            low[i] = min(low[i],disc[it]);
        }
    }
}
void dfs2 ( ll i ){
    visited[i] = 1;
    col[i] = (which);
    for ( auto it : scclist[i] ){
        if ( !visited[it] ){
            dfs2(it);
            maxcost[which] = max(maxcost[which],cost[{min(i,it),max(i,it)}]);
        }
    }
}
ll fans = 0;
void init ( ){
    memset(ap,0,sizeof ap);
    memset(visited,0,sizeof visited);
    which = 0;
    fans =0;
}
void dijkstra( )
{
    for ( ll i = 0; i <= n; i ++)
        dist[i] = INT_MAX,visited[i]=0;// check max
    set < pii > pq;
    // pq.insert({0,s});
    for ( ll i = 1; i <= n; i ++){
        if ( c[i] == 'A' ){
            pq.insert({0,col[i]});
            dist[col[i]] = 0;
        }
    }

    ll ansmax = INT_MIN, cnt = 0;
    while ( !pq.empty() )
    {
        ll node = (*pq.begin()).sec;
        ll d = (*pq.begin()).fi;
        visited[node] = 1;
        if ( d > ansmax )
            ansmax = d, cnt = 1;
        else if ( d == ansmax )
            cnt++;
        pq.erase(pq.begin());
        for ( auto it : treelist[node] )
        {
            if ( !visited[it.fi] and ((d+it.sec)<dist[it.fi]) )
            {
                if ( dist[it.fi] != INT_MAX )
                    pq.erase({dist[it.fi],it.fi});
                dist[it.fi] = d + it.sec;
                pq.insert({d+it.sec,it.fi});
            }
        }
    }
    ll fans = 0;
    for ( ll i = 1; i <= n; i ++)
        if ( c[i] == 'H' )
            fans += dist[col[i]];
    cout << fans <<"\n";
    // cout << ansmax <<" " << cnt <<"\n";
}
ll acnt[ N ], hcnt[ N ];
ll T[ N ], L[ N ];
map < pii, ll > treecost;
void dp ( ll i, ll par ){
    visited[i] =1;
    T[i] = par;
    L[i] = L[par] + 1;
    for ( auto it : treelist[i] ){
        if ( it.fi != par ){
            treecost[{min(i,it.fi),max(i,it.fi)}] = it.sec;
            dp(it.fi,i);
        }
    }
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    #ifndef ONLINE_JUDGE
    freopen("input.txt","r",stdin);
    freopen("output.txt","w",stdout);
    #endif
    ll t;
    // cin >> t;
    t = 1;
    while ( t-- ){
        init();
        cin >> n >> m;
        while ( m -- ){
            ll x,y,c;
            cin >> x >> y >> c;
            adjlist[x].pb(y);
            adjlist[y].pb(x);
            cost[{min(x,y),max(x,y)}]=c;
            edges.pb({c,{min(x,y),max(x,y)}});
        }
        for ( ll i = 1; i <= n; i ++)
            if (!visited[i] )
                dfs(i,-1,1);
        for ( auto it : edges)
        {
            if ( bridges.find(it.sec) == bridges.end() ){
                scclist[it.sec.fi].pb(it.sec.sec);
                scclist[it.sec.sec].pb(it.sec.fi);
            }
        }
        memset(visited,0,sizeof visited);
        for ( ll i = 1; i <= n; i ++){
            if ( !visited[i] ){
                which++;
                dfs2(i);
            }
        }
        // for ( ll i = 1; i <= n; i ++)
        //     trace(i,col[i]);
        // treesize = which
        ll u,v;
        for ( auto it : bridges ){
            u = min(it.fi,it.sec);
            v = max(it.fi,it.sec);
            // trace(u,v);
            treelist[col[u]].pb({col[v],cost[{u,v}]});
            treelist[col[v]].pb({col[u],cost[{u,v}]});
        }
        ll a,b;
        cin >> a >> b;
        a = col[a], b=col[b];
        dp(1,0);
        if ( L[a] > L[b] )
            swap(a,b);
        bool flg = 0;
        flg |= maxcost[a];
        flg |= maxcost[b];
        while ( L[b] > L[a] ){
            flg |= treecost[{min(T[b],b),max(T[b],b)}];
            b = T[b];
        }
        while ( a != b ){
            flg |= treecost[{min(T[b],b),max(T[b],b)}];
            flg |= treecost[{min(T[a],a),max(T[a],a)}];
            a = T[a];
            b = T[b];
        }
        if ( flg )
            cout <<"YES";
        else
            cout <<"NO";

        // for ( ll i = 1; i <= n; i ++){
        //     if ( c[i] == 'H' )
        //         hcnt[col[i]]++;
        //     else if ( c[i] == 'A' )
        //         acnt[col[i]]++;
        // }
        // memset(visited,0,sizeof visited);
        // // trace(which);
        // for ( ll i = 1; i <= which; i ++){
        //     if ( !visited[i] ){
        //         // trace(i);
        //         dp(i,0);
        //     }
        // }
        // cout << fans <<"\n";
        // // dijkstra();
        // bridges.clear();
        // edges.clear();
        // for ( ll i = 1; i <= n; i ++){
        //     adjlist[i].clear();
        //     scclist[i].clear();
        //     treelist[i].clear();
        //     acnt[i] = 0, hcnt[i] = 0;
        // }
    }

}


#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<math.h>
#include<bits/stdc++.h>
#include<stack>
#include<queue>
#include<list>
#include<vector>
#include<bitset>
#include<unordered_map>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
// #include "boost/algorithm/string.hpp"
#define fio ios_base::sync_with_stdio(false)
#define mod 998244353
#define mod1 mod
#define mod2 100000009
#define li long long int
#define ll li
#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#define readi(x) scanf("%d",&x)
#define  reads(x)  scanf("%s", x)
#define readl(x) scanf("%I64d",&x)
#define rep(i,n) for(i=0;i<n;i++)
#define revp(i,n) for(i=(n-1);i>=0;i--)
#define myrep1(i,a,b) for(i=a;i<=b;i++)
#define myrep2(i,a,b) for(i=b;i>=a;i--)
#define pb push_back
#define mp make_pair
#define fi first
#define sec second
#define MAXN 1000000000000000005
#define MINN -10000000000000000
#define INTMAX 1000001000
#define pii pair<ll,ll>
#define pdd pair<double,double>
#define pic pair<int,char>
#define N 400010
#define lgn 20
#define ddouble long double
#define minus minu
#define PI 3.1415926535
#define lgn 20

// #define INTMAX 200000000

// using namespace boost;
// #define si short int

using namespace std;
using namespace __gnu_pbds;
typedef priority_queue<ll, vector<ll > > max_pq;
typedef priority_queue<pii, vector<pii> , greater<pii>  > min_pq;
ll toint(const string &s) {stringstream ss; ss << s; ll x; ss >> x; return x;}
string tostring ( ll number ){stringstream ss; ss<< number; return ss.str();}

// using namespace __gnu_pbds;
// typedef priority_queue<pair<ll,char> , vector<pair<ll , char> > > max_pq;
// typedef priority_queue<pii , vector<pii > ,greater<pii > > min_pq;
typedef tree<ll , null_type, less<ll>, rb_tree_tag, tree_order_statistics_node_update> OST;
// typedef priority_queue<pair < ll , pair < pii , ll > >  , vector<pair < ll , pair < pii , ll > >  > ,greater<pair < ll , pair < pii , ll > >  > > min_pq;
#define TRACE
#ifdef TRACE
#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
    template <typename Arg1>
    void __f(const char* name, Arg1&& arg1){
        cout << name << " : " << arg1 << std::endl;
        //use cerr if u want to display at the bottom
    }
    template <typename Arg1, typename... Args>
    void __f(const char* names, Arg1&& arg1, Args&&... args){
        const char* comma = strchr(names + 1, ','); cout.write(names, comma - names) << " : " << arg1<<" | ";__f(comma+1, args...);
    }
#else
#define trace(...)
#endif
bool visited[ N ];
ll n,m;
ll disc[ N ], low[ N ];
bool ap[ N ];
set < pii > bridges;
vector < vector < ll > > adjlist ( N );
vector < vector < ll > > scclist ( N );
vector < vector < pii > > treelist ( N );
map < pii, ll > cost;
vector < pair < ll, pii>  > edges;
ll col[ N ];
char c[ N ];
ll which = 0;
ll dist[ N ];
ll maxcost[ N ];
void dfs ( ll i, ll par , ll ti )
{
    visited[i] = 1;
    disc[i] = low[i] = ti;
    ll ch = 0;
    for ( auto it : adjlist[i] )
    {
        if ( !visited[it] )
        {
            dfs(it,i,ti+1);
            ch ++;
            low[i] = min(low[i],low[it]);
            if ( par == -1 and ch > 1 )
                ap[i]=1;
            if ( par != -1 and low[it] >= disc[i] )
                ap[i]=1;
            if ( low[it] > disc[i] )
                bridges.insert({min(i,it),max(it,i)});
        }
        else if ( it != par )
        {
            low[i] = min(low[i],disc[it]);
        }
    }
}
void dfs2 ( ll i ){
    visited[i] = 1;
    col[i] = (which);
    for ( auto it : scclist[i] ){
        if ( !visited[it] ){
            dfs2(it);
            maxcost[which] = max(maxcost[which],cost[{min(i,it),max(i,it)}]);
        }
    }
}
ll fans = 0;
void init ( ){
    memset(ap,0,sizeof ap);
    memset(visited,0,sizeof visited);
    which = 0;
    fans =0;
}
void dijkstra( )
{
    for ( ll i = 0; i <= n; i ++)
        dist[i] = INT_MAX,visited[i]=0;// check max
    set < pii > pq;
    // pq.insert({0,s});
    for ( ll i = 1; i <= n; i ++){
        if ( c[i] == 'A' ){
            pq.insert({0,col[i]});
            dist[col[i]] = 0;
        }
    }

    ll ansmax = INT_MIN, cnt = 0;
    while ( !pq.empty() )
    {
        ll node = (*pq.begin()).sec;
        ll d = (*pq.begin()).fi;
        visited[node] = 1;
        if ( d > ansmax )
            ansmax = d, cnt = 1;
        else if ( d == ansmax )
            cnt++;
        pq.erase(pq.begin());
        for ( auto it : treelist[node] )
        {
            if ( !visited[it.fi] and ((d+it.sec)<dist[it.fi]) )
            {
                if ( dist[it.fi] != INT_MAX )
                    pq.erase({dist[it.fi],it.fi});
                dist[it.fi] = d + it.sec;
                pq.insert({d+it.sec,it.fi});
            }
        }
    }
    ll fans = 0;
    for ( ll i = 1; i <= n; i ++)
        if ( c[i] == 'H' )
            fans += dist[col[i]];
    cout << fans <<"\n";
    // cout << ansmax <<" " << cnt <<"\n";
}
ll acnt[ N ], hcnt[ N ];
ll T[ N ], L[ N ];
map < pii, ll > treecost;
void dp ( ll i, ll par ){
    visited[i] =1;
    T[i] = par;
    L[i] = L[par] + 1;
    for ( auto it : treelist[i] ){
        if ( it.fi != par ){
            treecost[{min(i,it.fi),max(i,it.fi)}] = it.sec;
            dp(it.fi,i);
        }
    }
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    #ifndef ONLINE_JUDGE
    freopen("input.txt","r",stdin);
    freopen("output.txt","w",stdout);
    #endif
    ll t;
    // cin >> t;
    t = 1;
    while ( t-- ){
        init();
        cin >> n >> m;
        while ( m -- ){
            ll x,y,c;
            cin >> x >> y >> c;
            adjlist[x].pb(y);
            adjlist[y].pb(x);
            cost[{min(x,y),max(x,y)}]=c;
            edges.pb({c,{min(x,y),max(x,y)}});
        }
        for ( ll i = 1; i <= n; i ++)
            if (!visited[i] )
                dfs(i,-1,1);
        for ( auto it : edges)
        {
            if ( bridges.find(it.sec) == bridges.end() ){
                scclist[it.sec.fi].pb(it.sec.sec);
                scclist[it.sec.sec].pb(it.sec.fi);
            }
        }
        memset(visited,0,sizeof visited);
        for ( ll i = 1; i <= n; i ++){
            if ( !visited[i] ){
                which++;
                dfs2(i);
            }
        }
        // for ( ll i = 1; i <= n; i ++)
        //     trace(i,col[i]);
        // treesize = which
        ll u,v;
        for ( auto it : bridges ){
            u = min(it.fi,it.sec);
            v = max(it.fi,it.sec);
            // trace(u,v);
            treelist[col[u]].pb({col[v],cost[{u,v}]});
            treelist[col[v]].pb({col[u],cost[{u,v}]});
        }
        ll a,b;
        cin >> a >> b;
        a = col[a], b=col[b];
        dp(1,0);
        if ( L[a] > L[b] )
            swap(a,b);
        bool flg = 0;
        flg |= maxcost[a];
        flg |= maxcost[b];
        while ( L[b] > L[a] ){
            flg |= treecost[{min(T[b],b),max(T[b],b)}];
            b = T[b];
        }
        while ( a != b ){
            flg |= treecost[{min(T[b],b),max(T[b],b)}];
            flg |= treecost[{min(T[a],a),max(T[a],a)}];
            a = T[a];
            b = T[b];
        }
        assert(a != 0 );
        if ( flg )
            cout <<"YES";
        else
            cout <<"NO";

        // for ( ll i = 1; i <= n; i ++){
        //     if ( c[i] == 'H' )
        //         hcnt[col[i]]++;
        //     else if ( c[i] == 'A' )
        //         acnt[col[i]]++;
        // }
        // memset(visited,0,sizeof visited);
        // // trace(which);
        // for ( ll i = 1; i <= which; i ++){
        //     if ( !visited[i] ){
        //         // trace(i);
        //         dp(i,0);
        //     }
        // }
        // cout << fans <<"\n";
        // // dijkstra();
        // bridges.clear();
        // edges.clear();
        // for ( ll i = 1; i <= n; i ++){
        //     adjlist[i].clear();
        //     scclist[i].clear();
        //     treelist[i].clear();
        //     acnt[i] = 0, hcnt[i] = 0;
        // }
    }

}


#include<bits/stdc++.h>
using namespace std;
const int N=300004;
vector<pair<int,int> >g[N];
int vis[N];
int a,b;
void dfs(int u,int f)
{
    int i,v;
    vis[u]=1;
    for(i=0;i<g[u].size();i++)
    {
        v=g[u][i].first;
        if(v==b && f)
        {
            printf("YES\n");
            exit(0);
        }
        if(vis[v]) continue;
        dfs(v,f|g[u][i].second);
    }
}
int main()
{
    int n,m;
    scanf("%d %d",&n,&m);
    int i,x,y,z;
    for(i=1;i<=m;i++)
    {
        scanf("%d %d %d",&x,&y,&z);
        g[x].push_back(make_pair(y,z));
        g[y].push_back(make_pair(x,z));
    }
    scanf("%d %d",&a,&b);
    dfs(a,0);
    printf("NO\n");
    return 0;
}


#include<bits/stdc++.h>
#define F first
#define S second
using namespace std;
const int MX = 4e5+9;
typedef long long ll;
typedef pair<ll,ll> pll;
ll n,m,depth[MX],low[MX],timer,b[MX],S,T,st[MX],en[MX],par[MX];
bool vis[MX],big[MX];
vector<pll>v[MX],com[MX];
void dfs(int x,int p){
    if(vis[x])return;
    vis[x]=1;
    low[x]=depth[x]=++timer;
    st[x]=timer;
    for(auto pp:v[x]){
        int nxt=pp.F;
        if(nxt==p)continue;
        if(depth[nxt]==0){
            par[nxt]=x;
            dfs(nxt,x);
            low[x]=min(low[x],low[nxt]);
        }
        else low[x]=min(low[x],depth[nxt]);
    }
    en[x]=timer;
}
bool sol=0;
void dfs1(int x,int p){
    int End=0;
    for(auto pp:v[x]){
        int nxt=pp.F,art=pp.S;
        if(nxt==p)continue;
        if(par[nxt]!=x){
            sol|=art;
            continue;
        }
        if(low[nxt]<=depth[x]){
            sol|=art;
            dfs1(nxt,x);
        }
        else if(st[T]>=st[nxt]&&st[T]<=en[nxt]){
            End=nxt;
            sol|=art;
        }
    }
    if(End)dfs1(End,x);
}
int main(){
    scanf("%lld%lld",&n,&m);
    for(int i=0;i<m;i++){
        ll a,b,c;
        scanf("%lld%lld%lld",&a,&b,&c);
        v[a].pb({b,c});
        v[b].pb({a,c});
    }
    cin>>S>>T;
    dfs(S,-1);
    dfs1(S,-1);
    if(sol)puts("YES");
    else puts("NO");
}


#include<bits/stdc++.h>
#define MEM(dp,i) memset(dp,i,sizeof(dp))
#define pb push_back
#define F first
#define S second
using namespace std;
const int MX = 4e5+9;
const long long mod=1e9+7;
const long long inf = (1ll<<61);
typedef long long ll;
typedef pair<ll,ll> pll;
ll n,m,depth[MX],low[MX],timer,b[MX],S,T,st[MX],en[MX],par[MX];
bool vis[MX],big[MX];
vector<pll>v[MX],com[MX];
void dfs(int x,int p){
    if(vis[x])return;
    vis[x]=1;
    low[x]=depth[x]=++timer;
    st[x]=timer;
    for(auto pp:v[x]){
        int nxt=pp.F;
        if(nxt==p)continue;
        if(depth[nxt]==0){
            par[nxt]=x;
            dfs(nxt,x);
            low[x]=min(low[x],low[nxt]);
        }
        else low[x]=min(low[x],depth[nxt]);
    }
    en[x]=timer;
}
bool sol=0;
void dfs1(int x,int p){
    int End=0;
    for(auto pp:v[x]){
        int nxt=pp.F,art=pp.S;
        if(nxt==p)continue;
        if(par[nxt]!=x){
            sol|=art;
            continue;
        }
        if(low[nxt]<=depth[x]){
            sol|=art;
            dfs1(nxt,x);
        }
        else if(st[T]>=st[nxt]&&st[T]<=en[nxt]){
            End=nxt;
            sol|=art;
        }
    }
    if(End)dfs1(End,x);
}
int main(){
    scanf("%lld%lld",&n,&m);
    for(int i=0;i<m;i++){
        ll a,b,c;
        scanf("%lld%lld%lld",&a,&b,&c);
        v[a].pb({b,c});
        v[b].pb({a,c});
    }
    cin>>S>>T;
    dfs(S,-1);
    dfs1(S,-1);
    if(sol)puts("YES");
    else puts("NO");
}


#include<bits/stdc++.h>
using namespace std;
const int N=300004;
vector<pair<int,int> >g[N];
int vis[N],st[N],en[N],low[N],depth[N],par[N];
int a,b,timer;
int sol;
void dfs(int x,int p)
{
    if(vis[x]) return;
    int i,nxt;
    vis[x]=1;
    low[x]=depth[x]=++timer;
    st[x]=timer;
    for(i=0;i<g[x].size();i++)
    {
        nxt=g[x][i].first;
        if(nxt==p) continue;
        if(depth[nxt]==0)
        {
            par[nxt]=x;
            dfs(nxt,x);
            low[x]=min(low[x],low[nxt]);
        }
        else
            low[x]=min(low[x],depth[nxt]);
    }
    en[x]=timer;
}
void dfs1(int x,int p)
{
    int i,nxt,idx=0;
    for(i=0;i<g[x].size();i++)
    {
        nxt=g[x][i].first;
        int res=g[x][i].second;
        if(nxt==x) continue;
        if(par[nxt]!=x)
        {
            sol|=res;
            continue;
        }
        else if(low[nxt]<=depth[x])
        {
            sol|=res;
            dfs1(nxt,x);
        }
        else if(st[b]>=st[a] && st[b]<=en[a])
        {
            idx=nxt;
            sol|=res;
        }
    }
    if(idx) dfs1(idx,x);
}
int main()
{
    int n,m;
    scanf("%d %d",&n,&m);
    int i,x,y,z;
    for(i=1;i<=m;i++)
    {
        scanf("%d %d %d",&x,&y,&z);
        g[x].push_back(make_pair(y,z));
        g[y].push_back(make_pair(x,z));
    }
    scanf("%d %d",&a,&b);
    dfs(a,-1);
    dfs1(a,-1);
    if(sol) printf("YES\n");
    else printf("NO\n");
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define mp make_pair
#define vi vector< int >
#define vb vector< bool >
#define vl vector< ll >
#define ss second
#define ff first
#define ll long long
#define pii pair< int,int >
#define pll pair< ll,ll >
#define sz(a) a.size()
#define sort(a) sort(a.begin(),a.end())
#define inf (1000*1000*1000+5)
#define all(a) a.begin(),a.end()
#define tri pair<int,pii>
#define vii vector<pii>
#define vll vector<pll>
#define viii vector<tri>
#define mod (1000*1000*1000+7)
#define moddd (1000*1000*1000+9)
#define pqueue priority_queue< int >
#define pdqueue priority_queue< int,vi ,greater< int > >
#define endl "\n"
#define flush fflush(stdout)
#define pi 3.14159265358979323846264338327950
#define primeDEN 727999983
//cout<<fixed<<setprecision(15)<<ans;

template <typename T>
void printvec(vector<T>& vec){
	for(int i=0;i<vec.size();i++){
		cout<<vec[i]<<" ";
	}
	cout<<endl;
}

typedef struct edge{
	int a;
	int b;
	bool isartifact;
	bool isbridge;
}edge;

vector<vector<edge> > adj(300*1000);
vector<vector<edge> > tree(300*1000);
vector<edge> edgearr(300*1000);
vb visited(300*1000,false),isarti(300*1000,false);
vi disc(300*1000,INT_MAX),low(300*1000);
vi comp(300*1000);
int ctr=0;

void bridgedfs(int curr,int prev){
	visited[curr]=true;
	//cout<<curr<<" "<<ctr<<endl;
	disc[curr]=ctr;
	low[curr]=ctr;
	ctr++;
	int children=0;
	int i;
	for(i=0;i<adj[curr].size();i++){
		if(!visited[adj[curr][i].b]){
			children++;
			bridgedfs(adj[curr][i].b,curr);
			low[curr]=min(low[curr],low[adj[curr][i].b]);
			// if(prev==-1&&children>=2){
			// 	adj[curr][i].isbridge=true;
			// 	//cout<<adj[curr][i].a<<" "<<adj[curr][i].b<<endl;
			// 	if(children==2){
			// 		adj[curr][0].isbridge=true;
			// 		//cout<<adj[curr][i].a<<" "<<adj[curr][i].b<<endl;
			// 	}
			// }
			if(low[adj[curr][i].b]>disc[curr]){
				adj[curr][i].isbridge=true;
			}
		}
		else if(adj[curr][i].b!=prev){
			//if(curr==5) cout<<adj[curr][i].b<<disc[adj[curr][i].b]<<endl;
			low[curr]=min(low[curr],disc[adj[curr][i].b]);
		}
	}
}

void constructtree(int curr,int prev,int num){
	visited[curr]=true;
	comp[curr]=num;
	int i;
	int x=num;
	for(i=0;i<adj[curr].size();i++){
		if(visited[adj[curr][i].b]) continue;
		if(adj[curr][i].isbridge){
			constructtree(adj[curr][i].b,curr,++x);
			tree[comp[curr]].pb(edge{comp[curr],comp[adj[curr][i].b],adj[curr][i].isartifact,false});
			tree[comp[adj[curr][i].b]].pb(edge{comp[adj[curr][i].b],comp[curr],adj[curr][i].isartifact,false});
		}
		else{
			constructtree(adj[curr][i].b,curr,num);
			if(adj[curr][i].isartifact) isarti[num]=true;
		}
	}
}

int aa,bb;

void dfs(int curr,int prev,bool found){
	visited[curr]=true;
	found=found||isarti[curr];
	if(comp[bb]==curr&&found){
		cout<<"YES";
		exit(0);
	}
	int i;
	for(i=0;i<tree[curr].size();i++){
		if(!visited[tree[curr][i].b]){
			dfs(tree[curr][i].b,curr,tree[curr][i].isartifact||found);
		}
	}
}

int main(){
	std::ios::sync_with_stdio(false);
	int ttt=1;
	//cin>>ttt;
	while(ttt--){
		int n,m,ans=0;
		cin>>n>>m;
		int i;
		for(i=0;i<m;i++){
			int a,b,c;
			cin>>a>>b>>c;
			a--; b--;
			adj[a].pb(edge{a,b,c,false});
			adj[b].pb(edge{b,a,c,false});
		}
		bridgedfs(0,-1);
		for(i=0;i<n;i++){
			visited[i]=false;
		}
		constructtree(0,-1,0);
		cin>>aa>>bb;
		aa--; bb--;
		for(i=0;i<n;i++){
			visited[i]=false;
		}
		dfs(aa,-1,false);
		//for(int i=0;i<n;i++) cout<<comp[i]<<" ";
		cout<<"NO";
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define mp make_pair
#define vi vector< int >
#define vb vector< bool >
#define vl vector< ll >
#define ss second
#define ff first
#define ll long long
#define pii pair< int,int >
#define pll pair< ll,ll >
#define sz(a) a.size()
#define sort(a) sort(a.begin(),a.end())
#define inf (1000*1000*1000+5)
#define all(a) a.begin(),a.end()
#define tri pair<int,pii>
#define vii vector<pii>
#define vll vector<pll>
#define viii vector<tri>
#define mod (1000*1000*1000+7)
#define moddd (1000*1000*1000+9)
#define pqueue priority_queue< int >
#define pdqueue priority_queue< int,vi ,greater< int > >
#define endl "\n"
#define flush fflush(stdout)
#define pi 3.14159265358979323846264338327950
#define primeDEN 727999983
//cout<<fixed<<setprecision(15)<<ans;

template <typename T>
void printvec(vector<T>& vec){
	for(int i=0;i<vec.size();i++){
		cout<<vec[i]<<" ";
	}
	cout<<endl;
}

typedef struct edge{
	int a;
	int b;
	bool isartifact;
	bool isbridge;
}edge;

vector<vector<edge> > adj(300*1000);
vector<vector<edge> > tree(300*1000);
vector<edge> edgearr;
vb visited(300*1000,false),isarti(300*1000,false);
vi disc(300*1000,INT_MAX),low(300*1000);
vi comp(300*1000);
int ctr=0;

void bridgedfs(int curr,int prev){
	visited[curr]=true;
	//cout<<curr<<" "<<ctr<<endl;
	disc[curr]=ctr;
	low[curr]=ctr;
	ctr++;
	int children=0;
	int i;
	for(i=0;i<adj[curr].size();i++){
		if(!visited[adj[curr][i].b]){
			children++;
			bridgedfs(adj[curr][i].b,curr);
			low[curr]=min(low[curr],low[adj[curr][i].b]);
			// if(prev==-1&&children>=2){
			// 	adj[curr][i].isbridge=true;
			// 	//cout<<adj[curr][i].a<<" "<<adj[curr][i].b<<endl;
			// 	if(children==2){
			// 		adj[curr][0].isbridge=true;
			// 		//cout<<adj[curr][i].a<<" "<<adj[curr][i].b<<endl;
			// 	}
			// }
			if(low[adj[curr][i].b]>disc[curr]){
				adj[curr][i].isbridge=true;
			}
		}
		else if(adj[curr][i].b!=prev){
			//if(curr==5) cout<<adj[curr][i].b<<disc[adj[curr][i].b]<<endl;
			low[curr]=min(low[curr],disc[adj[curr][i].b]);
		}
	}
}

void constructtree(int curr,int prev,int num){
	visited[curr]=true;
	comp[curr]=num;
	int i;
	int x=num;
	for(i=0;i<adj[curr].size();i++){
		if(visited[adj[curr][i].b]){
			//cout<<curr<<" "<<adj[curr][i].b<<" "<<num<<" "<<isarti[num]<<endl;
			if(adj[curr][i].isartifact) isarti[num]=true;
			continue;
		}
		if(adj[curr][i].isbridge){
			continue;
			constructtree(adj[curr][i].b,curr,++x);
			tree[comp[curr]].pb(edge{comp[curr],comp[adj[curr][i].b],adj[curr][i].isartifact,false});
			tree[comp[adj[curr][i].b]].pb(edge{comp[adj[curr][i].b],comp[curr],adj[curr][i].isartifact,false});
		}
		else{
			constructtree(adj[curr][i].b,curr,num);
			if(adj[curr][i].isartifact) isarti[num]=true;
		}
	}
}

int aa,bb;

void dfs(int curr,int prev,bool found){
	visited[curr]=true;
	found=found||isarti[curr];
	if(comp[bb]==curr&&found){
		cout<<"YES";
		exit(0);
	}
	int i;
	for(i=0;i<tree[curr].size();i++){
		if(!visited[tree[curr][i].b]){
			dfs(tree[curr][i].b,curr,tree[curr][i].isartifact||found);
		}
	}
}

int main(){
	std::ios::sync_with_stdio(false);
	int ttt=1;
	//cin>>ttt;
	while(ttt--){
		int n,m,ans=0;
		cin>>n>>m;
		int i;
		for(i=0;i<m;i++){
			int a,b,c;
			cin>>a>>b>>c;
			a--; b--;
			adj[a].pb(edge{a,b,c,false});
			adj[b].pb(edge{b,a,c,false});
			edgearr.pb(edge{a,b,c,false});
			edgearr.pb(edge{b,a,c,false});
		}
		bridgedfs(0,-1);
		for(i=0;i<n;i++){
			visited[i]=false;
		}
		int x=0;
		for(i=0;i<n;i++){
			if(!visited[i]) constructtree(i,-1,x++);
		}
		for(i=0;i<edgearr.size();i++){
			if(comp[edgearr[i].a]==comp[edgearr[i].b]) continue;
			//cout<<comp[edgearr[i].a]<<" "<<comp[edgearr[i].b]<<" "<<edgearr[i].isartifact<<endl;
			tree[comp[edgearr[i].a]].pb(edge{comp[edgearr[i].a],comp[edgearr[i].b],edgearr[i].isartifact,false});
			tree[comp[edgearr[i].b]].pb(edge{comp[edgearr[i].b],comp[edgearr[i].a],edgearr[i].isartifact,false});
		}
		cin>>aa>>bb;
		aa--; bb--;
		for(i=0;i<n;i++){
			visited[i]=false;
		}
		//for(int i=0;i<n;i++) cout<<comp[i]<<" ";
		dfs(comp[aa],-1,false);

		//	cout<<isarti[0]<<endl;
		cout<<"NO";
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define mp make_pair
#define vi vector< int >
#define vb vector< bool >
#define vl vector< ll >
#define ss second
#define ff first
#define ll long long
#define pii pair< int,int >
#define pll pair< ll,ll >
#define sz(a) a.size()
#define sort(a) sort(a.begin(),a.end())
#define inf (1000*1000*1000+5)
#define all(a) a.begin(),a.end()
#define tri pair<int,pii>
#define vii vector<pii>
#define vll vector<pll>
#define viii vector<tri>
#define mod (1000*1000*1000+7)
#define moddd (1000*1000*1000+9)
#define pqueue priority_queue< int >
#define pdqueue priority_queue< int,vi ,greater< int > >
#define endl "\n"
#define flush fflush(stdout)
#define pi 3.14159265358979323846264338327950
#define primeDEN 727999983
//cout<<fixed<<setprecision(15)<<ans;

template <typename T>
void printvec(vector<T>& vec){
	for(int i=0;i<vec.size();i++){
		cout<<vec[i]<<" ";
	}
	cout<<endl;
}

typedef struct edge{
	int a;
	int b;
	bool isartifact;
	bool isbridge;
}edge;

vector<vector<edge> > adj(300*1000);
vector<vector<edge> > tree(300*1000);
vector<edge> edgearr(300*1000);
vb visited(300*1000,false),isarti(300*1000,false);
vi disc(300*1000,INT_MAX),low(300*1000);
vi comp(300*1000);
int ctr=0;

void bridgedfs(int curr,int prev){
	visited[curr]=true;
	//cout<<curr<<" "<<ctr<<endl;
	disc[curr]=ctr;
	low[curr]=ctr;
	ctr++;
	int children=0;
	int i;
	for(i=0;i<adj[curr].size();i++){
		if(!visited[adj[curr][i].b]){
			children++;
			bridgedfs(adj[curr][i].b,curr);
			low[curr]=min(low[curr],low[adj[curr][i].b]);
			if(prev==-1&&children>=2){
				adj[curr][i].isbridge=true;
				//cout<<adj[curr][i].a<<" "<<adj[curr][i].b<<endl;
				if(children==2){
					adj[curr][0].isbridge=true;
					//cout<<adj[curr][i].a<<" "<<adj[curr][i].b<<endl;
				}
			}
			if(prev!=-1&&low[adj[curr][i].b]>disc[curr]){
				adj[curr][i].isbridge=true;
			}
		}
		else if(adj[curr][i].b!=prev){
			//if(curr==5) cout<<adj[curr][i].b<<disc[adj[curr][i].b]<<endl;
			low[curr]=min(low[curr],disc[adj[curr][i].b]);
		}
	}
}

void constructtree(int curr,int prev,int num){
	visited[curr]=true;
	comp[curr]=num;
	int i;
	int x=num;
	for(i=0;i<adj[curr].size();i++){
		if(visited[adj[curr][i].b]) continue;
		if(adj[curr][i].isbridge){
			constructtree(adj[curr][i].b,curr,++x);
			tree[comp[curr]].pb(edge{comp[curr],comp[adj[curr][i].b],adj[curr][i].isartifact,false});
		}
		else{
			constructtree(adj[curr][i].b,curr,num);
			if(adj[curr][i].isartifact) isarti[num]=true;
		}
	}
}

int aa,bb;

void dfs(int curr,int prev,bool found){
	visited[curr]=true;
	found=found||isarti[curr];
	if(comp[bb]==curr&&found){
		cout<<"YES";
		exit(0);
	}
	int i;
	for(i=0;i<tree[curr].size();i++){
		if(!visited[tree[curr][i].b]){
			dfs(tree[curr][i].b,curr,tree[curr][i].isartifact||found);
		}
	}
}

int main(){
	std::ios::sync_with_stdio(false);
	int ttt=1;
	//cin>>ttt;
	while(ttt--){
		int n,m,ans=0;
		cin>>n>>m;
		int i;
		for(i=0;i<m;i++){
			int a,b,c;
			cin>>a>>b>>c;
			a--; b--;
			adj[a].pb(edge{a,b,c,false});
			adj[b].pb(edge{b,a,c,false});
		}
		bridgedfs(0,-1);
		for(i=0;i<n;i++){
			visited[i]=false;
		}
		constructtree(0,-1,0);
		cin>>aa>>bb;
		aa--; bb--;
		for(i=0;i<n;i++){
			visited[i]=false;
		}
		dfs(aa,-1,false);
		cout<<"NO";
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define mp make_pair
#define vi vector< int >
#define vb vector< bool >
#define vl vector< ll >
#define ss second
#define ff first
#define ll long long
#define pii pair< int,int >
#define pll pair< ll,ll >
#define sz(a) a.size()
#define sort(a) sort(a.begin(),a.end())
#define inf (1000*1000*1000+5)
#define all(a) a.begin(),a.end()
#define tri pair<int,pii>
#define vii vector<pii>
#define vll vector<pll>
#define viii vector<tri>
#define mod (1000*1000*1000+7)
#define moddd (1000*1000*1000+9)
#define pqueue priority_queue< int >
#define pdqueue priority_queue< int,vi ,greater< int > >
#define endl "\n"
#define flush fflush(stdout)
#define pi 3.14159265358979323846264338327950
#define primeDEN 727999983
//cout<<fixed<<setprecision(15)<<ans;

template <typename T>
void printvec(vector<T>& vec){
	for(int i=0;i<vec.size();i++){
		cout<<vec[i]<<" ";
	}
	cout<<endl;
}

typedef struct edge{
	int a;
	int b;
	bool isartifact;
	bool isbridge;
	int rev;
}edge;

vector<vector<edge> > adj(300*1000);
vector<vector<edge> > tree(300*1000);
vector<edge> edgearr;
vb visited(300*1000,false),isarti(300*1000,false);
vi disc(300*1000,INT_MAX),low(300*1000);
vi comp(300*1000);
int ctr=0;

void bridgedfs(int curr,int prev){
	visited[curr]=true;
	//cout<<curr<<" "<<ctr<<endl;
	disc[curr]=ctr;
	low[curr]=ctr;
	ctr++;
	int children=0;
	int i;
	for(i=0;i<adj[curr].size();i++){
		if(!visited[adj[curr][i].b]){
			children++;
			bridgedfs(adj[curr][i].b,curr);
			low[curr]=min(low[curr],low[adj[curr][i].b]);
			// if(prev==-1&&children>=2){
			// 	adj[curr][i].isbridge=true;
			// 	//cout<<adj[curr][i].a<<" "<<adj[curr][i].b<<endl;
			// 	if(children==2){
			// 		adj[curr][0].isbridge=true;
			// 		//cout<<adj[curr][i].a<<" "<<adj[curr][i].b<<endl;
			// 	}
			// }
			if(low[adj[curr][i].b]>disc[curr]){
				adj[curr][i].isbridge=true;
				adj[adj[curr][i].b][adj[curr][i].rev].isbridge=true;
			}
		}
		else if(adj[curr][i].b!=prev){
			//if(curr==5) cout<<adj[curr][i].b<<disc[adj[curr][i].b]<<endl;
			low[curr]=min(low[curr],disc[adj[curr][i].b]);
		}
	}
}

void constructtree(int curr,int prev,int num){
	visited[curr]=true;
	comp[curr]=num;
	int i;
	int x=num;
	for(i=0;i<adj[curr].size();i++){
		if(visited[adj[curr][i].b]){
			//cout<<curr<<" "<<adj[curr][i].b<<" "<<num<<" "<<isarti[num]<<endl;
			if(adj[curr][i].isartifact&&!adj[curr][i].isbridge) isarti[num]=true;
			continue;
		}
		if(adj[curr][i].isbridge){
			continue;
			constructtree(adj[curr][i].b,curr,++x);
			tree[comp[curr]].pb(edge{comp[curr],comp[adj[curr][i].b],adj[curr][i].isartifact,false,0});
			tree[comp[adj[curr][i].b]].pb(edge{comp[adj[curr][i].b],comp[curr],adj[curr][i].isartifact,false,0});
		}
		else{
			constructtree(adj[curr][i].b,curr,num);
			if(adj[curr][i].isartifact) isarti[num]=true;
		}
	}
}

int aa,bb;

void dfs(int curr,int prev,bool found){
	visited[curr]=true;
	//cout<<comp[bb]<<" "<<found<<endl;
	found=found||isarti[curr];
	if(comp[bb]==curr&&found){
		cout<<"YES";
		exit(0);
	}
	int i;
	for(i=0;i<tree[curr].size();i++){
		if(!visited[tree[curr][i].b]){
			//cout<<curr<<" "<<tree[curr][i].b<<" "<<found<<endl;
			dfs(tree[curr][i].b,curr,tree[curr][i].isartifact||found);
		}
	}
}

int main(){
	std::ios::sync_with_stdio(false);
	int ttt=1;
	//cin>>ttt;
	while(ttt--){
		int n,m,ans=0;
		cin>>n>>m;
		int i;
		for(i=0;i<m;i++){
			int a,b,c;
			cin>>a>>b>>c;
			a--; b--;
			adj[a].pb(edge{a,b,c,false,adj[b].size()});
			adj[b].pb(edge{b,a,c,false,adj[a].size()-1});
			edgearr.pb(edge{a,b,c,false});
			edgearr.pb(edge{b,a,c,false});
		}
		bridgedfs(0,-1);
		for(i=0;i<n;i++){
			visited[i]=false;
		}
		int x=0;
		for(i=0;i<n;i++){
			if(!visited[i]) constructtree(i,-1,x++);
		}
		for(i=0;i<edgearr.size();i++){
			if(comp[edgearr[i].a]==comp[edgearr[i].b]) continue;
			//cout<<comp[edgearr[i].a]<<" "<<comp[edgearr[i].b]<<" "<<edgearr[i].isartifact<<endl;
			tree[comp[edgearr[i].a]].pb(edge{comp[edgearr[i].a],comp[edgearr[i].b],edgearr[i].isartifact,false,0});
			tree[comp[edgearr[i].b]].pb(edge{comp[edgearr[i].b],comp[edgearr[i].a],edgearr[i].isartifact,false,0});
		}
		cin>>aa>>bb;
		aa--; bb--;
		for(i=0;i<n;i++){
			visited[i]=false;
		}
		//for(int i=0;i<n;i++) cout<<comp[i]<<" ";
		dfs(comp[aa],-1,false);

		//	cout<<isarti[0]<<endl;
		cout<<"NO";
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define mp make_pair
#define vi vector< int >
#define vb vector< bool >
#define vl vector< ll >
#define ss second
#define ff first
#define ll long long
#define pii pair< int,int >
#define pll pair< ll,ll >
#define sz(a) a.size()
#define sort(a) sort(a.begin(),a.end())
#define inf (1000*1000*1000+5)
#define all(a) a.begin(),a.end()
#define tri pair<int,pii>
#define vii vector<pii>
#define vll vector<pll>
#define viii vector<tri>
#define mod (1000*1000*1000+7)
#define moddd (1000*1000*1000+9)
#define pqueue priority_queue< int >
#define pdqueue priority_queue< int,vi ,greater< int > >
#define endl "\n"
#define flush fflush(stdout)
#define pi 3.14159265358979323846264338327950
#define primeDEN 727999983
//cout<<fixed<<setprecision(15)<<ans;

template <typename T>
void printvec(vector<T>& vec){
	for(int i=0;i<vec.size();i++){
		cout<<vec[i]<<" ";
	}
	cout<<endl;
}

typedef struct edge{
	int a;
	int b;
	bool isartifact;
	bool isbridge;
}edge;

vector<vector<edge> > adj(300*1000);
vector<vector<edge> > tree(300*1000);
vector<edge> edgearr;
vb visited(300*1000,false),isarti(300*1000,false);
vi disc(300*1000,INT_MAX),low(300*1000);
vi comp(300*1000);
int ctr=0;

void bridgedfs(int curr,int prev){
	visited[curr]=true;
	//cout<<curr<<" "<<ctr<<endl;
	disc[curr]=ctr;
	low[curr]=ctr;
	ctr++;
	int children=0;
	int i;
	for(i=0;i<adj[curr].size();i++){
		if(!visited[adj[curr][i].b]){
			children++;
			bridgedfs(adj[curr][i].b,curr);
			low[curr]=min(low[curr],low[adj[curr][i].b]);
			// if(prev==-1&&children>=2){
			// 	adj[curr][i].isbridge=true;
			// 	//cout<<adj[curr][i].a<<" "<<adj[curr][i].b<<endl;
			// 	if(children==2){
			// 		adj[curr][0].isbridge=true;
			// 		//cout<<adj[curr][i].a<<" "<<adj[curr][i].b<<endl;
			// 	}
			// }
			if(low[adj[curr][i].b]>disc[curr]){
				adj[curr][i].isbridge=true;
			}
		}
		else if(adj[curr][i].b!=prev){
			//if(curr==5) cout<<adj[curr][i].b<<disc[adj[curr][i].b]<<endl;
			low[curr]=min(low[curr],disc[adj[curr][i].b]);
		}
	}
}

void constructtree(int curr,int prev,int num){
	visited[curr]=true;
	comp[curr]=num;
	int i;
	int x=num;
	for(i=0;i<adj[curr].size();i++){
		if(visited[adj[curr][i].b]){
			//cout<<curr<<" "<<adj[curr][i].b<<" "<<num<<" "<<isarti[num]<<endl;
			if(adj[curr][i].isartifact) isarti[num]=true;
			continue;
		}
		if(adj[curr][i].isbridge){
			continue;
			constructtree(adj[curr][i].b,curr,++x);
			tree[comp[curr]].pb(edge{comp[curr],comp[adj[curr][i].b],adj[curr][i].isartifact,false});
			tree[comp[adj[curr][i].b]].pb(edge{comp[adj[curr][i].b],comp[curr],adj[curr][i].isartifact,false});
		}
		else{
			constructtree(adj[curr][i].b,curr,num);
			if(adj[curr][i].isartifact) isarti[num]=true;
		}
	}
}

int aa,bb;

void dfs(int curr,int prev,bool found){
	visited[curr]=true;
	found=found||isarti[curr];
	if(comp[bb]==curr&&found){
		cout<<"YES";
		exit(0);
	}
	int i;
	for(i=0;i<tree[curr].size();i++){
		if(!visited[tree[curr][i].b]){
			dfs(tree[curr][i].b,curr,tree[curr][i].isartifact||found);
		}
	}
}

int main(){
	std::ios::sync_with_stdio(false);
	int ttt=1;
	//cin>>ttt;
	while(ttt--){
		int n,m,ans=0;
		cin>>n>>m;
		int i;
		for(i=0;i<m;i++){
			int a,b,c;
			cin>>a>>b>>c;
			a--; b--;
			adj[a].pb(edge{a,b,c,false});
			adj[b].pb(edge{b,a,c,false});
			edgearr.pb(edge{a,b,c,false});
			edgearr.pb(edge{b,a,c,false});
		}
		bridgedfs(0,-1);
		for(i=0;i<n;i++){
			visited[i]=false;
		}
		int x=0;
		for(i=0;i<n;i++){
			if(!visited[i]) constructtree(i,-1,x++);
		}
		for(i=0;i<m;i++){
			if(comp[edgearr[i].a]==comp[edgearr[i].b]) continue;
			//cout<<comp[edgearr[i].a]<<" "<<comp[edgearr[i].b]<<" "<<edgearr[i].isartifact<<endl;
			tree[comp[edgearr[i].a]].pb(edge{comp[edgearr[i].a],comp[edgearr[i].b],edgearr[i].isartifact,false});
			tree[comp[edgearr[i].b]].pb(edge{comp[edgearr[i].b],comp[edgearr[i].a],edgearr[i].isartifact,false});
		}
		cin>>aa>>bb;
		aa--; bb--;
		for(i=0;i<n;i++){
			visited[i]=false;
		}
		//for(int i=0;i<n;i++) cout<<comp[i]<<" ";
		dfs(comp[aa],-1,false);

		//	cout<<isarti[0]<<endl;
		cout<<"NO";
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define mp make_pair
#define vi vector< int >
#define vb vector< bool >
#define vl vector< ll >
#define ss second
#define ff first
#define ll long long
#define pii pair< int,int >
#define pll pair< ll,ll >
#define sz(a) a.size()
#define sort(a) sort(a.begin(),a.end())
#define inf (1000*1000*1000+5)
#define all(a) a.begin(),a.end()
#define tri pair<int,pii>
#define vii vector<pii>
#define vll vector<pll>
#define viii vector<tri>
#define mod (1000*1000*1000+7)
#define moddd (1000*1000*1000+9)
#define pqueue priority_queue< int >
#define pdqueue priority_queue< int,vi ,greater< int > >
#define endl "\n"
#define flush fflush(stdout)
#define pi 3.14159265358979323846264338327950
#define primeDEN 727999983
//cout<<fixed<<setprecision(15)<<ans;

template <typename T>
void printvec(vector<T>& vec){
	for(int i=0;i<vec.size();i++){
		cout<<vec[i]<<" ";
	}
	cout<<endl;
}

typedef struct edge{
	int a;
	int b;
	bool isartifact;
	bool isbridge;
}edge;

vector<vector<edge> > adj(300*1000);
vector<vector<edge> > tree(300*1000);
vector<edge> edgearr(300*1000);
vb visited(300*1000,false),isarti(300*1000,false);
vi disc(300*1000,INT_MAX),low(300*1000);
vi comp(300*1000);
int ctr=0;

void bridgedfs(int curr,int prev){
	visited[curr]=true;
	//cout<<curr<<" "<<ctr<<endl;
	disc[curr]=ctr;
	low[curr]=ctr;
	ctr++;
	int children=0;
	int i;
	for(i=0;i<adj[curr].size();i++){
		if(!visited[adj[curr][i].b]){
			children++;
			bridgedfs(adj[curr][i].b,curr);
			low[curr]=min(low[curr],low[adj[curr][i].b]);
			// if(prev==-1&&children>=2){
			// 	adj[curr][i].isbridge=true;
			// 	//cout<<adj[curr][i].a<<" "<<adj[curr][i].b<<endl;
			// 	if(children==2){
			// 		adj[curr][0].isbridge=true;
			// 		//cout<<adj[curr][i].a<<" "<<adj[curr][i].b<<endl;
			// 	}
			// }
			if(low[adj[curr][i].b]>disc[curr]){
				adj[curr][i].isbridge=true;
			}
		}
		else if(adj[curr][i].b!=prev){
			//if(curr==5) cout<<adj[curr][i].b<<disc[adj[curr][i].b]<<endl;
			low[curr]=min(low[curr],disc[adj[curr][i].b]);
		}
	}
}

void constructtree(int curr,int prev,int num){
	visited[curr]=true;
	comp[curr]=num;
	int i;
	int x=num;
	for(i=0;i<adj[curr].size();i++){
		if(visited[adj[curr][i].b]){
			//cout<<curr<<" "<<adj[curr][i].b<<" "<<num<<" "<<isarti[num]<<endl;
			if(adj[curr][i].isartifact) isarti[num]=true;
			continue;
		}
		if(adj[curr][i].isbridge){
			constructtree(adj[curr][i].b,curr,++x);
			tree[comp[curr]].pb(edge{comp[curr],comp[adj[curr][i].b],adj[curr][i].isartifact,false});
			tree[comp[adj[curr][i].b]].pb(edge{comp[adj[curr][i].b],comp[curr],adj[curr][i].isartifact,false});
		}
		else{
			constructtree(adj[curr][i].b,curr,num);
			if(adj[curr][i].isartifact) isarti[num]=true;
		}
	}
}

int aa,bb;

void dfs(int curr,int prev,bool found){
	visited[curr]=true;
	found=found||isarti[curr];
	if(comp[bb]==curr&&found){
		cout<<"YES";
		exit(0);
	}
	int i;
	for(i=0;i<tree[curr].size();i++){
		if(!visited[tree[curr][i].b]){
			dfs(tree[curr][i].b,curr,tree[curr][i].isartifact||found);
		}
	}
}

int main(){
	std::ios::sync_with_stdio(false);
	int ttt=1;
	//cin>>ttt;
	while(ttt--){
		int n,m,ans=0;
		cin>>n>>m;
		int i;
		for(i=0;i<m;i++){
			int a,b,c;
			cin>>a>>b>>c;
			a--; b--;
			adj[a].pb(edge{a,b,c,false});
			adj[b].pb(edge{b,a,c,false});
		}
		bridgedfs(0,-1);
		for(i=0;i<n;i++){
			visited[i]=false;
		}
		constructtree(0,-1,0);
		cin>>aa>>bb;
		aa--; bb--;
		for(i=0;i<n;i++){
			visited[i]=false;
		}
		dfs(comp[aa],-1,false);
		//for(int i=0;i<n;i++) cout<<comp[i]<<" ";
		//	cout<<isarti[0]<<endl;
		cout<<"NO";
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define mp make_pair
#define vi vector< int >
#define vb vector< bool >
#define vl vector< ll >
#define ss second
#define ff first
#define ll long long
#define pii pair< int,int >
#define pll pair< ll,ll >
#define sz(a) a.size()
#define sort(a) sort(a.begin(),a.end())
#define inf (1000*1000*1000+5)
#define all(a) a.begin(),a.end()
#define tri pair<int,pii>
#define vii vector<pii>
#define vll vector<pll>
#define viii vector<tri>
#define mod (1000*1000*1000+7)
#define moddd (1000*1000*1000+9)
#define pqueue priority_queue< int >
#define pdqueue priority_queue< int,vi ,greater< int > >
#define endl "\n"
#define flush fflush(stdout)
#define pi 3.14159265358979323846264338327950
#define primeDEN 727999983
//cout<<fixed<<setprecision(15)<<ans;

template <typename T>
void printvec(vector<T>& vec){
	for(int i=0;i<vec.size();i++){
		cout<<vec[i]<<" ";
	}
	cout<<endl;
}

typedef struct edge{
	int a;
	int b;
	bool isartifact;
	bool isbridge;
	int rev;
}edge;

vector<vector<edge> > adj(300*1000);
vector<vector<edge> > tree(300*1000);
vector<edge> edgearr;
vb visited(300*1000,false),isarti(300*1000,false);
vi disc(300*1000,INT_MAX),low(300*1000);
vi comp(300*1000);
int ctr=0;

void bridgedfs(int curr,int prev){
	visited[curr]=true;
	//cout<<curr<<" "<<ctr<<endl;
	disc[curr]=ctr;
	low[curr]=ctr;
	ctr++;
	int children=0;
	int i;
	for(i=0;i<adj[curr].size();i++){
		if(!visited[adj[curr][i].b]){
			children++;
			bridgedfs(adj[curr][i].b,curr);
			low[curr]=min(low[curr],low[adj[curr][i].b]);
			// if(prev==-1&&children>=2){
			// 	adj[curr][i].isbridge=true;
			// 	//cout<<adj[curr][i].a<<" "<<adj[curr][i].b<<endl;
			// 	if(children==2){
			// 		adj[curr][0].isbridge=true;
			// 		//cout<<adj[curr][i].a<<" "<<adj[curr][i].b<<endl;
			// 	}
			// }
			if(low[adj[curr][i].b]>disc[curr]){
				adj[curr][i].isbridge=true;
				adj[adj[curr][i].b][adj[curr][i].rev].isbridge=true;
			}
		}
		else if(adj[curr][i].b!=prev){
			//if(curr==5) cout<<adj[curr][i].b<<disc[adj[curr][i].b]<<endl;
			low[curr]=min(low[curr],disc[adj[curr][i].b]);
		}
	}
}

void constructtree(int curr,int prev,int num){
	visited[curr]=true;
	comp[curr]=num;
	int i;
	int x=num;
	for(i=0;i<adj[curr].size();i++){
		if(visited[adj[curr][i].b]){
			//cout<<curr<<" "<<adj[curr][i].b<<" "<<num<<" "<<isarti[num]<<endl;
			if(adj[curr][i].isartifact&&!adj[curr][i].isbridge) isarti[num]=true;
			continue;
		}
		if(adj[curr][i].isbridge){
			continue;
			constructtree(adj[curr][i].b,curr,++x);
			tree[comp[curr]].pb(edge{comp[curr],comp[adj[curr][i].b],adj[curr][i].isartifact,false,0});
			tree[comp[adj[curr][i].b]].pb(edge{comp[adj[curr][i].b],comp[curr],adj[curr][i].isartifact,false,0});
		}
		else{
			constructtree(adj[curr][i].b,curr,num);
			if(adj[curr][i].isartifact) isarti[num]=true;
		}
	}
}

int aa,bb;

void dfs(int curr,int prev,bool found){
	visited[curr]=true;
	//cout<<comp[bb]<<" "<<found<<endl;
	found=found||isarti[curr];
	if(comp[bb]==curr&&found){
		cout<<"YES";
		exit(0);
	}
	int i;
	for(i=0;i<tree[curr].size();i++){
		if(!visited[tree[curr][i].b]){
			//cout<<curr<<" "<<tree[curr][i].b<<" "<<found<<endl;
			dfs(tree[curr][i].b,curr,tree[curr][i].isartifact||found);
		}
	}
}

int main(){
	std::ios::sync_with_stdio(false);
	int ttt=1;
	//cin>>ttt;
	while(ttt--){
		int n,m,ans=0;
		cin>>n>>m;
		int i;
		for(i=0;i<m;i++){
			int a,b,c;
			cin>>a>>b>>c;
			a--; b--;
			adj[a].pb(edge{a,b,c,false,adj[b].size()});
			adj[b].pb(edge{b,a,c,false,adj[a].size()});
			edgearr.pb(edge{a,b,c,false});
			edgearr.pb(edge{b,a,c,false});
		}
		bridgedfs(0,-1);
		for(i=0;i<n;i++){
			visited[i]=false;
		}
		int x=0;
		for(i=0;i<n;i++){
			if(!visited[i]) constructtree(i,-1,x++);
		}
		for(i=0;i<edgearr.size();i++){
			if(comp[edgearr[i].a]==comp[edgearr[i].b]) continue;
			//cout<<comp[edgearr[i].a]<<" "<<comp[edgearr[i].b]<<" "<<edgearr[i].isartifact<<endl;
			tree[comp[edgearr[i].a]].pb(edge{comp[edgearr[i].a],comp[edgearr[i].b],edgearr[i].isartifact,false,0});
			tree[comp[edgearr[i].b]].pb(edge{comp[edgearr[i].b],comp[edgearr[i].a],edgearr[i].isartifact,false,0});
		}
		cin>>aa>>bb;
		aa--; bb--;
		for(i=0;i<n;i++){
			visited[i]=false;
		}
		//for(int i=0;i<n;i++) cout<<comp[i]<<" ";
		dfs(comp[aa],-1,false);

		//	cout<<isarti[0]<<endl;
		cout<<"NO";
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define mp make_pair
#define vi vector< int >
#define vb vector< bool >
#define vl vector< ll >
#define ss second
#define ff first
#define ll long long
#define pii pair< int,int >
#define pll pair< ll,ll >
#define sz(a) a.size()
#define sort(a) sort(a.begin(),a.end())
#define inf (1000*1000*1000+5)
#define all(a) a.begin(),a.end()
#define tri pair<int,pii>
#define vii vector<pii>
#define vll vector<pll>
#define viii vector<tri>
#define mod (1000*1000*1000+7)
#define moddd (1000*1000*1000+9)
#define pqueue priority_queue< int >
#define pdqueue priority_queue< int,vi ,greater< int > >
#define endl "\n"
#define flush fflush(stdout)
#define pi 3.14159265358979323846264338327950
#define primeDEN 727999983
//cout<<fixed<<setprecision(15)<<ans;

template <typename T>
void printvec(vector<T>& vec){
	for(int i=0;i<vec.size();i++){
		cout<<vec[i]<<" ";
	}
	cout<<endl;
}

typedef struct edge{
	int a;
	int b;
	bool isartifact;
	bool isbridge;
}edge;

vector<vector<edge> > adj(300*1000);
vector<vector<edge> > tree(300*1000);
vector<edge> edgearr(300*1000);
vb visited(300*1000,false),isarti(300*1000,false);
vi disc(300*1000,INT_MAX),low(300*1000);
vi comp(300*1000);
int ctr=0;

void bridgedfs(int curr,int prev){
	visited[curr]=true;
	//cout<<curr<<" "<<ctr<<endl;
	disc[curr]=ctr;
	low[curr]=ctr;
	ctr++;
	int children=0;
	int i;
	for(i=0;i<adj[curr].size();i++){
		if(!visited[adj[curr][i].b]){
			children++;
			bridgedfs(adj[curr][i].b,curr);
			low[curr]=min(low[curr],low[adj[curr][i].b]);
			// if(prev==-1&&children>=2){
			// 	adj[curr][i].isbridge=true;
			// 	//cout<<adj[curr][i].a<<" "<<adj[curr][i].b<<endl;
			// 	if(children==2){
			// 		adj[curr][0].isbridge=true;
			// 		//cout<<adj[curr][i].a<<" "<<adj[curr][i].b<<endl;
			// 	}
			// }
			if(low[adj[curr][i].b]>disc[curr]){
				adj[curr][i].isbridge=true;
			}
		}
		else if(adj[curr][i].b!=prev){
			//if(curr==5) cout<<adj[curr][i].b<<disc[adj[curr][i].b]<<endl;
			low[curr]=min(low[curr],disc[adj[curr][i].b]);
		}
	}
}

void constructtree(int curr,int prev,int num){
	visited[curr]=true;
	comp[curr]=num;
	int i;
	int x=num;
	for(i=0;i<adj[curr].size();i++){
		if(visited[adj[curr][i].b]){
			//cout<<curr<<" "<<adj[curr][i].b<<" "<<num<<" "<<isarti[num]<<endl;
			if(adj[curr][i].isartifact) isarti[num]=true;
			continue;
		}
		if(adj[curr][i].isbridge){
			continue;
			constructtree(adj[curr][i].b,curr,++x);
			tree[comp[curr]].pb(edge{comp[curr],comp[adj[curr][i].b],adj[curr][i].isartifact,false});
			tree[comp[adj[curr][i].b]].pb(edge{comp[adj[curr][i].b],comp[curr],adj[curr][i].isartifact,false});
		}
		else{
			constructtree(adj[curr][i].b,curr,num);
			if(adj[curr][i].isartifact) isarti[num]=true;
		}
	}
}

int aa,bb;

void dfs(int curr,int prev,bool found){
	visited[curr]=true;
	found=found||isarti[curr];
	if(comp[bb]==curr&&found){
		cout<<"YES";
		exit(0);
	}
	int i;
	for(i=0;i<tree[curr].size();i++){
		if(!visited[tree[curr][i].b]){
			dfs(tree[curr][i].b,curr,tree[curr][i].isartifact||found);
		}
	}
}

int main(){
	std::ios::sync_with_stdio(false);
	int ttt=1;
	//cin>>ttt;
	while(ttt--){
		int n,m,ans=0;
		cin>>n>>m;
		int i;
		for(i=0;i<m;i++){
			int a,b,c;
			cin>>a>>b>>c;
			a--; b--;
			adj[a].pb(edge{a,b,c,false});
			adj[b].pb(edge{b,a,c,false});
		}
		bridgedfs(0,-1);
		for(i=0;i<n;i++){
			visited[i]=false;
		}
		int x=0;
		for(i=0;i<n;i++){
			if(!visited[i]) constructtree(i,-1,x++);
		}
		for(i=0;i<m;i++){
			if(comp[edgearr[i].a]==comp[edgearr[i].b]) continue;
			tree[comp[edgearr[i].a]].pb(edge{comp[edgearr[i].a],comp[edgearr[i].b],edgearr[i].isartifact,false});
			tree[comp[edgearr[i].b]].pb(edge{comp[edgearr[i].b],comp[edgearr[i].a],edgearr[i].isartifact,false});
		}
		cin>>aa>>bb;
		aa--; bb--;
		for(i=0;i<n;i++){
			visited[i]=false;
		}
		//for(int i=0;i<n;i++) cout<<comp[i]<<" ";
		dfs(comp[aa],-1,false);

		//	cout<<isarti[0]<<endl;
		cout<<"NO";
	}
	return 0;
}