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

char s[105][55];
int k=0;
int n,m;
char s1[10005];
int vis[105];
int flag=0;
int dis=-1;

bool check(int i,int j){
	for(int x=0;x<m;x++){
		if(s[i][x]!=s[j][m-x-1])
		    return false;
	}
	return true;
}

bool huiwei(int i){
	for(int j=0;j<=m/2;j++){
		if(s[i][j]!=s[i][m-1-j])
		    return false;
	}
	return true;
}

int main(){
	memset(vis,0,sizeof(vis));
	scanf("%d %d",&n,&m);
	//  cin >> n >> m;
	//getchar();
	for(int i=0;i<n;i++)//cin >> s[i];
	    scanf("%s",s[i]);
	for(int i=0;i<n;i++){
		if(vis[i]) continue;
		flag=0;
		for(int j = i+1;j<n;j++){
			if(check(i,j) && !vis[j]){
				vis[i]=1;
				vis[j]=1;
				for(int x=0;x<m;x++){
					s1[k++]=s[i][x];
				}
				flag=1;
				break;
			}
		}
		if(!flag && huiwei(i)){
				vis[i]=1;
		        dis=i;
		        //cout << dis << endl;
		}
	}
	if(dis>-1){
		for(int x=0;x<m/2;x++)
		    s1[k++]=s[dis][x];
	}
	if(k==0)
	    printf("0\n");
	else{
		if(dis>-1 && m%2==1)
		    printf("%d\n",2*k+1);
		else
		    printf("%d\n",2*k);
	}
	for(int i=0;i<k;i++)
	    printf("%c",s1[i]);
	if(dis>-1 && m%2==1)
	    printf("%c",s[dis][m/2]);
	for(int i=k-1;i>=0;i--)
	    printf("%c",s1[i]);
	printf("\n");
	return 0;
}


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

char s[105][55];
int k=0;
int n,m;
char s1[10005];
int vis[105]={0};
int flag=0;
int dis=-1;

bool check(int i,int j){
	for(int x=0;x<m;x++){
		if(s[i][x]!=s[j][m-x-1])
		    return false;
	}
	return true;
}

bool huiwei(int i){
	for(int j=0;i<=m/2;j++){
		if(s[i][j]!=s[i][m-1-j])
		    return false;
	}
	return true;
}

int main(){

	scanf("%d %d",&n,&m);
	for(int i=0;i<n;i++)
	    scanf("%s",s[i]);
	for(int i=0;i<n;i++){
		if(vis[i]) continue;
		flag=0;
		for(int j = i+1;j<n;j++){
			if(check(i,j) && !vis[j]){
				vis[i]=1;
				vis[j]=1;
				for(int x=0;x<m;x++){
					s1[k++]=s[i][x];
				}
				flag=1;
				break;
			}
		}
		if(!flag){
			if(huiwei(i) && dis==-1){
				vis[i]=1;
		        dis=i;
		    }
		}
	}
	if(dis>-1){
		for(int x=0;x<m/2;x++)
		    s1[k++]=s[dis][x];
	}
	for(int i=0;i<k;i++)
	    printf("%c",s1[i]);
	if(dis>-1 && m%2==1)
	    printf("%c",s[dis][m/2]);
	for(int i=k-1;i>=0;i--)
	    printf("%c",s1[i]);
	if(k==0) printf("0");
	printf("\n");
	return 0;
}


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

char s[105][55];
int k=0;
int n,m;
char s1[10005];
int vis[105]={0};
int flag=0;
int dis=-1;

bool check(int i,int j){
	for(int x=0;x<m;x++){
		if(s[i][x]!=s[j][m-x-1])
		    return false;
	}
	return true;
}

bool huiwei(int i){
	for(int j=0;i<=m/2;j++){
		if(s[i][j]!=s[i][m-1-j])
		    return false;
	}
	return true;
}

int main(){

	scanf("%d %d",&n,&m);
	for(int i=0;i<n;i++)
	    scanf("%s",s[i]);
	for(int i=0;i<n;i++){
		if(vis[i]) continue;
		flag=0;
		for(int j = i+1;j<n;j++){
			if(check(i,j) && !vis[j]){
				vis[i]=1;
				vis[j]=1;
				for(int x=0;x<m;x++){
					s1[k++]=s[i][x];
				}
				flag=1;
				break;
			}
		}
		if(!flag){
			if(huiwei(i) && dis==-1){
				vis[i]=1;
		        dis=i;
		    }
		}
	}
	if(dis>-1){
		for(int x=0;x<m/2;x++)
		    s1[k++]=s[dis][x];
	}
	if(k==0)
	    printf("0\n");
	else{
		if(dis>-1 && m%2==1)
		    printf("%d\n",2*k+1);
		else
		    printf("%d\n",2*k);
	}
	for(int i=0;i<k;i++)
	    printf("%c",s1[i]);
	if(dis>-1 && m%2==1)
	    printf("%c",s[dis][m/2]);
	for(int i=k-1;i>=0;i--)
	    printf("%c",s1[i]);
	printf("\n");
	return 0;
}


#include <bits/stdc++.h>
#define For(i,a,b) for ( int i=(a);i<=(b);i++ )
#define Dow(i,a,b) for ( int i=(a);i>=(b);i-- )
#define int long long
using namespace std;
const int N=3e5+5;
int n,m,x,y,ans,a[N],f[N],p[N];
signed main()
{
	scanf("%lld%lld",&n,&m);
	For(i,1,n) scanf("%lld",&a[i]),p[a[i]]=i,f[i]=1;
	For(i,1,m)
	{
		scanf("%lld%lld",&x,&y);
		x=p[x],y=p[y];
		if(x>y) swap(x,y);
		f[y]=max(f[y],x+1);
	}
	For(i,1,n) f[i]=max(f[i-1],f[i]);
	For(i,1,n) ans+=i-f[i]+1;
	printf("%lld\n",ans);
	return 0;
}


#include <bits/stdc++.h>
#define For(i,a,b) for ( int i=(a);i<=(b);i++ )
#define Dow(i,a,b) for ( int i=(a);i>=(b);i-- )
#define int long long
using namespace std;
const int N=3e5+5;
int n,m,x,y,ans,a[N],f[N],p[N];
signed main()
{
	scanf("%lld%lld",&n,&m);
	For(i,1,n) scanf("%lld",&a[i]),p[a[i]]=i,f[i]=n;
	For(i,1,m)
	{
		scanf("%lld%lld",&x,&y);
		x=p[x],y=p[y];
		if(x>y) swap(x,y);
		f[x]=min(f[x],y-1);
	}
	Dow(i,n-1,1) f[i]=min(f[i],f[i+1]);
	For(i,1,n) ans+=f[i]-i+1;
	printf("%lld\n",ans);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
int n,m,a[300000],aa[300000],f[300000],x,y;
long long sum=0;
int main()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
		aa[a[i]]=i;
		f[i]=n;
	}
	for(int i=1;i<=m;i++)
	{
		cin>>x>>y;
		x=min(aa[y],aa[x]);
		y=max(aa[y],aa[x]);
		f[x]=min(f[x],y-1);
	}
	for(int i=n-1;i>=1;i--)
	f[i]=min(f[i],f[i+1]);
	for(int i=1;i<=n;i++)
	sum+=f[i]-i+1;
//cout<<f[i]<<" ";
	cout<<sum;
}


#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll n,m,pos[300010],dp[300010],ans;
signed main()
{
    scanf("%lld%lld",&n,&m);
    for(ll i=1; i<=n; i++)
    {
        ll x;
        scanf("%lld",&x);
        pos[x]=i; dp[i]=n+1;
    }
    ans=1ll*n*(n-1)/2+n;
    while(m--)
    {
        ll u,v;
        scanf("%lld %lld",&u,&v);
        if(pos[u]>pos[v]) swap(u,v);
        dp[pos[u]]=min(dp[pos[u]],pos[v]);
    }
    for(ll i=n-1; i>=1; i--) dp[i]=min(dp[i],dp[i+1]);
    for(ll i=1; i<n; i++) ans-=n-dp[i]+1;
    printf("%lld",ans);
}


#include<bits/stdc++.h>
#include<iostream>
#include<string>
#include<cmath>
#include<cstdio>
#include<cctype>
#include<cstring>
#include<iomanip>
#include<cstdlib>
#include<ctime>
#include<set>
#include<map>
#include<utility>
#include<queue>
#include<vector>
#include<stack>
#include<sstream>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<pii,pii> piiii;
typedef vector<pii> vii;
typedef vector<int> vi;
typedef queue<int> qi;
typedef queue<char> qc;
typedef queue<string> qs;
typedef vector<char> vc;
typedef vector<string> vs;
typedef map<char,int> mpci;
typedef map<int,int> mpii;
typedef map<string,int> mpsi;
typedef set<int> sei;
typedef set<char> sec;
typedef set<string> ses;
typedef stack<ll> si;
typedef stack<char> sc;
typedef vector<ll> vll;
typedef vector<vi> vvi;
typedef vector<double> vd;
typedef pair<ll,ll> pll;
typedef pair<double,double> pdd;
typedef vector<pll> vpll;
typedef vector<pdd> vdd;
typedef unsigned int uint;
typedef long double ld;
typedef vector<bool> vb;
typedef vector<double> vd;
typedef vector<vi> vvi;
typedef vector<vvi> vvvi;
typedef vector<vii> vvii;
/*=====================================================================*/
#define pb push_back
#define rep(i,n) for(int i=0;i<(int)(n);i++)
#define sz(a) (int)(a.size())
#define len(a) (int)(a.length())
#define all(s) (s).begin(),(s).end()
#define fi first
#define se second
#define be begin
#define en end
#define m_p make_pair
#define repd(i,n) for(int i=n-1;i>=0;i--)
#define forn(i,p,n) for(int i=p;i<=n;i++)
#define ford(i,p,n) for(int i=n-1;i>=p;i--)
#define foreach(i,c) for(__typeof(c.begin())i=(c.begin());i!=(c).end();++i)
#define zero(a) memset(a,0,sizeof(a))
#define number(a,num) memeset(a,num,sizeof(a))

/*=====================================================================*/

inline void read(int &x)
{
	short negative=1;
    x=0;
    char c=getchar();
    while(c<'0' || c>'9')
    {
		if(c=='-')
			negative=-1;
		c=getchar();
	}
    while(c>='0' && c<='9')
        x=(x<<3)+(x<<1)+(c^48),c=getchar();
    x*=negative;
}
inline void write(long long x) {
  static long long sta[35];
  long long top = 0;
  do {
    sta[top++] = x % 10, x /= 10;
  } while (x);
  while (top) putchar(sta[--top] + 48);
  puts("");
}
/*======================================================================*/
bool prime(int n)
{
	if(n==0||n==1)
	  return false;
	for(int i=2;i*i<=n;i++)
	  if(n%i==0)
	    return false;
	return true;
}
const ll power(int n,int k)
{
	ll t=1;
	rep(i,k)
	  t*=n;
	return t;
}
const string turn2(int n)
{
	string s="";
	while(n!=0)
	{
		s+=(char)(n%2+'0');
		n/=2;
	}
	reverse(s.begin(),s.end());
	return s;
}
const string turn16(int n)
{
	string s="";
	while(n!=0)
	{
		if(n%16>9)
		  s+=(char)('A'+n%16-10);
		else
		  s+=(char)('0'+n%16);
		n/=16;
	}
	reverse(s.begin(),s.end());
	return s;
}
const ll quickpower(int n,int k)
{
	if(k==1)
	  return n;
	if(k%2==1)
	  return n*quickpower(n,k/2)*quickpower(n,k/2);
	else
	  return quickpower(n,k/2)*(quickpower(n,k/2));
}
/*
void merge(int a[],int left,int mid,int right)
{
	int n1=mid-left;
	int n2=right-mid;
	for(int i=0;i<n1;i++)
	{
	  l[i]=a[i+left];
    }
	for(int i=0;i<n2;i++)
	{
	  r[i]=a[mid+i];
	}
	r[n2]=l[n1]=INF;
	int i=0;
	int j=0;
	for(int k=left;k<right;k++)
	{
		if(l[i]<=r[j])
		{
			a[k]=l[i++];
		}
		else
		{
			a[k]=r[j++];
		}
	}
}
void mergesort(int a[],int left,int right)
{
	if(left+1<right)
	{
		int mid=(left+right)/2;
		mergesort(a,left,mid);
		mergesort(a,mid,right);
		merge(a,left,mid,right);
	}
}
int binsearch(int x,int v[],int n)
{
	int low=0,high=n-1;
	int mid;
	while(low<=high)
	{
		mid=(low+high)/2;
		if(x<v[mid])
		  high=mid-1;
		else
		  if(x>v[mid])
		    low=mid+1;
		  else
		    return mid+1;
	}
	return -1;
}
int partition(int a[],int left,int right)
{
	int p=a[left];
	int i=left;
	int j=right+1;
	for(;;)
	{
		while(a[++i]<p)
		  if(i>=right)
		    break;
		while(a[j--]>p)
		  if(j<=left)
		    break;
		if(i>=j)
		  break;
		else
		  swap(a[i],a[j]);
	}
	if(j>=left)
	  return j;
	swap(a[left],a[j]);
	return j;
}
void quicksort(int a[],int left,int right)
{
	int q;
	while(right>left)
	{
		q=partition(a,left,right);
	    if(n-q+1==k)
	    {
	        cout<<a[q];
	  		exit(0);
		}
		quicksort(a,left,q-1);
		quicksort(a,q+1,right);
	}
}
void dfs(int n)
{
	if(use[n])
	  return;
	use[n]=true;
	cout<<n<<endl;
	for(int i=0;i<v[n].size();i++)
	  dfs(v[n][i]);
}*/
/*======================================================================*/
const int dx[]={-1,0,1,0};
const int dy[]={0,-1,0,1};
ll p[300030],now[300030];
/*======================================================================*/
int main()
{
  /*
	freopen("input.txt","r",stdin);
	freopen("output.txt","w",stdout);
  */
  /*====================================================================*/
  int n,m;
  cin>>n>>m;
  rep(i,n)
  {
  	int a;
  	read(a);
  	p[a]=i+1;
  }
  int l,r;
  rep(i,m)
  {
  	read(l);
  	read(r);
  	ll a=p[l],b=p[r];
  	if(a>b)
  	  swap(a,b);
  	now[b-1]=max(now[b-1],a+1);
  }
  ll cnt=1;
  ll ans=0;
  rep(i,n)
  {
  	cnt=max(cnt,now[i]);
  	ans+=(i-cnt+2);
  }
  write(ans);
  return 0;
}


#include<bits/stdc++.h>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<vector>
#include<stack>
#include<queue>
#include<cmath>
#include<map>
#include<set>
#define ll long long
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
#define ull unsigned long long
#define pb push_back
using namespace std;
const int N=3e5+5;
int n,p[N],a[N],m;
int tr[N<<2];
//void push_up(int rt)
//{
//    tr[rt]=min(tr[rt<<1],tr[rt<<1|1]);
//}
//void build(int l,int r,int rt)
//{
//    if(l==r)
//    {
//        tr[rt]=n+1;
//        return ;
//    }
//    int m=l+r>>1;
//    build(ls);
//    build(rs);
//    push_up(rt);
//}
//void update(int pos,int val,int l,int r,int rt)
//{
//    if(l==r)
//    {
//        tr[l]=val;return;
//    }
//    int m=l+r>>1;
//    if(pos<=m)update(pos,val,ls);
//    else update(pos,val,rs);
//    push_up(rt);
//}
//int query(int L,int R,int l,int r,int rt)
//{
//    if(L<=l&&r<=R)
//    {
//        return tr[rt];
//    }
//    int ans=n+1;
//    int m=l+r>>1;
//    if(L<=m)ans=min(ans,query(L,R,ls));
//    if(R>m)ans=min(ans,query(L,R,rs));
//    return  ans;
//}
int pp[N];
int main()
{
    cin>>n>>m;
    //build(1,n,1);
    for(int i=1;i<=n;i++)pp[i]=n+1;
    for(int i=1;i<=n;i++)cin>>p[i],a[p[i]]=i;
    for(int i=0;i<m;i++)
    {
        int x,y;
        cin>>x>>y;
        pp[min(a[x],a[y])]=max(a[x],a[y]);
      //  cout<<"SS"<<a[x]<<" "<<a[y]<<endl;
        //update(a[x],a[y],1,n,1);
    }
    for(int i=n-1;i>=1;i--)
    {
        pp[i]=min(pp[i],pp[i+1]);
    }
    ll ans=0;
    for(int i=1;i<=n;i++)
    {
//        int tmp=query(i,n,1,n,1);
//        cout<<i<<" "<<tmp<<endl;
//        ans+=tmp-i;
            ans+=pp[i]-i;
    }
    cout<<ans<<endl;
    return 0;

}


#include<bits/stdc++.h>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<vector>
#include<stack>
#include<queue>
#include<cmath>
#include<map>
#include<set>
#define ll long long
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
#define ull unsigned long long
#define pb push_back
using namespace std;
const int N=3e5+5;
int n,p[N],a[N],m;
int pp[N];
int main()
{
    //cin>>n>>m;
    scanf("%d %d",&n,&m);
    for(int i=1;i<=n;i++)pp[i]=n+1;
    for(int i=1;i<=n;i++)scanf("%d",&p[i]),a[p[i]]=i;
    for(int i=0;i<m;i++)
    {
        int x,y;
        //cin>>x>>y;
        scanf("%d %d",&x,&y);
        pp[min(a[x],a[y])]=min(pp[min(a[x],a[y])],max(a[x],a[y]));
    }
    for(int i=n-1;i>=1;i--)
    {
        pp[i]=min(pp[i],pp[i+1]);
    }
//    for(int i=1;i<=n;i++)
//    {
//        cout<<pp[i]<< " ";
//    }cout<<endl;
    ll ans=0;
    for(int i=1;i<=n;i++)
    {
        //    cout<<pp[i]-i<<endl;
            ans+=pp[i]-i;
    }
    printf("%I64d\n",ans);

    //cout<<ans<<endl;
    return 0;

}


#include<bits/stdc++.h>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<vector>
#include<stack>
#include<queue>
#include<cmath>
#include<map>
#include<set>
#define ll long long
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
#define ull unsigned long long
#define pb push_back
using namespace std;
const int N=3e5+5;
int n,p[N],a[N],m;
int pp[N];
struct node
{
    int l,r;
    bool operator<(const node b)
    {
        if(b.r!=r)return r<b.r;
        return l<b.l;
    }
}st[N];
int main()
{
    cin>>n>>m;
    if(n>1000&&m>1000)
    {
            for(int i=1;i<=n;i++)pp[i]=n+1;
        for(int i=1;i<=n;i++)cin>>p[i],a[p[i]]=i;
        for(int i=0;i<m;i++)
        {
            int x,y;
            cin>>x>>y;
            pp[min(a[x],a[y])]=max(a[x],a[y]);
        }
        for(int i=n-1;i>=1;i--)
        {
            pp[i]=min(pp[i],pp[i+1]);
        }
             ll ans=0;
        for(int i=1;i<=n;i++)
        {
                ans+=pp[i]-i;
        }
        cout<<ans<<endl;
    }
    else
    {
               for(int i=1;i<=n;i++)cin>>p[i],a[p[i]]=i;
        for(int i=0;i<m;i++)
        {
            int x,y;
            cin>>x>>y;
            st[i].l=min(a[x],a[y]);
            st[i].r=max(a[x],a[y]);
        }
        sort(st,st+m);
    ////    for(int i=0;i<m;i++)
    ////    {
    ////        cout<<st[i].l<<" "<<st[i].r<<endl;
    ////    }
        ll ans=0;
        for(int i=1;i<=n;i++)
        {
            node tmp;
            tmp.l=tmp.r=i;
            int pos=lower_bound(st,st+m,tmp)-st;
         //   if(i==1)cout<<"SSS"<<pos<<endl;
            while(st[pos].l<i&&pos<=m)pos++;
            if(pos>m)
            {
                ans+=n-i+1;
                continue;
            }
            ans+=st[pos].r-i;
          //  cout<<i<<" "<<st[pos].r-i<<endl;
        }
        cout<<ans<<endl;
    }
//    for(int i=1;i<=n;i++)
//    {
//        cout<<pp[i]<<" ";
//    }

    return 0;

}


#include<bits/stdc++.h>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<vector>
#include<stack>
#include<queue>
#include<cmath>
#include<map>
#include<set>
#define ll long long
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
#define ull unsigned long long
#define pb push_back
using namespace std;
const int N=3e5+5;
int n,p[N],a[N],m;
int pp[N];
struct node
{
    int l,r;
    bool operator<(const node b)
    {
        if(b.r!=r)return r<b.r;
        return l<b.l;
    }
}st[N];
int main()
{
    cin>>n>>m;
    if(n>100&&m>100)
    {
            for(int i=1;i<=n;i++)pp[i]=n+1;
        for(int i=1;i<=n;i++)cin>>p[i],a[p[i]]=i;
        for(int i=0;i<m;i++)
        {
            int x,y;
            cin>>x>>y;
            pp[min(a[x],a[y])]=max(a[x],a[y]);
        }
        for(int i=n-1;i>=1;i--)
        {
            pp[i]=min(pp[i],pp[i+1]);
        }
             ll ans=0;
        for(int i=1;i<=n;i++)
        {
                ans+=pp[i]-i;
        }
        cout<<ans<<endl;
    }
    else
    {
               for(int i=1;i<=n;i++)cin>>p[i],a[p[i]]=i;
        for(int i=0;i<m;i++)
        {
            int x,y;
            cin>>x>>y;
            st[i].l=min(a[x],a[y]);
            st[i].r=max(a[x],a[y]);
        }
        sort(st,st+m);
    ////    for(int i=0;i<m;i++)
    ////    {
    ////        cout<<st[i].l<<" "<<st[i].r<<endl;
    ////    }
        ll ans=0;
        for(int i=1;i<=n;i++)
        {
            node tmp;
            tmp.l=tmp.r=i;
            int pos=lower_bound(st,st+m,tmp)-st;
         //   if(i==1)cout<<"SSS"<<pos<<endl;
            while(st[pos].l<i&&pos<=m)pos++;
            if(pos>m)
            {
                ans+=n-i+1;
                continue;
            }
            ans+=st[pos].r-i;
          //  cout<<i<<" "<<st[pos].r-i<<endl;
        }
        cout<<ans<<endl;
    }
//    for(int i=1;i<=n;i++)
//    {
//        cout<<pp[i]<<" ";
//    }

    return 0;

}


#include<bits/stdc++.h>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<vector>
#include<stack>
#include<queue>
#include<cmath>
#include<map>
#include<set>
#define ll long long
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
#define ull unsigned long long
#define pb push_back
using namespace std;
const int N=3e5+5;
int n,p[N],a[N],m;
int pp[N];
int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)pp[i]=n+1;
    for(int i=1;i<=n;i++)cin>>p[i],a[p[i]]=i;
    for(int i=0;i<m;i++)
    {
        int x,y;
        cin>>x>>y;
        pp[min(a[x],a[y])]=max(a[x],a[y]);
    }
    for(int i=n-1;i>=1;i--)
    {
        pp[i]=min(pp[i],pp[i+1]);
    }
    for(int i=1;i<=n;i++)
    {
        cout<<pp[i]<<" ";
    }
    ll ans=0;
    for(int i=1;i<=n;i++)
    {
            ans+=pp[i]-i;
    }
    cout<<ans<<endl;
    return 0;

}


#include<bits/stdc++.h>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<vector>
#include<stack>
#include<queue>
#include<cmath>
#include<map>
#include<set>
#define ll long long
#define ull unsigned long long
#define pb push_back
using namespace std;
const int N=3e5+5;
int n,p[N],a[N],m;
struct node
{
    int l,r;
    bool operator<(const node b)
    {
        if(b.r!=r)return r<b.r;
        return l<b.l;
    }
}st[N];
int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)cin>>p[i],a[p[i]]=i;
    for(int i=0;i<m;i++)
    {
        int x,y;
        cin>>x>>y;
        st[i].l=min(a[x],a[y]);
        st[i].r=max(a[x],a[y]);
    }
    sort(st,st+m);
////    for(int i=0;i<m;i++)
////    {
////        cout<<st[i].l<<" "<<st[i].r<<endl;
////    }
    ll ans=0;
    for(int i=1;i<=n;i++)
    {
        node tmp;
        tmp.l=tmp.r=i;
        int pos=lower_bound(st,st+m,tmp)-st;
     //   if(i==1)cout<<"SSS"<<pos<<endl;
        while(st[pos].l<i&&pos<=m)pos++;
        if(pos>m)
        {
            ans+=n-i+1;
            continue;
        }
        ans+=st[pos].r-i;
      //  cout<<i<<" "<<st[pos].r-i<<endl;
    }
    cout<<ans<<endl;
    return 0;

}


#include<bits/stdc++.h>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<vector>
#include<stack>
#include<queue>
#include<cmath>
#include<map>
#include<set>
#define ll long long
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
#define ull unsigned long long
#define pb push_back
using namespace std;
const int N=3e5+5;
int n,p[N],a[N],m;
int pp[N];
int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)pp[i]=n+1;
    for(int i=1;i<=n;i++)cin>>p[i],a[p[i]]=i;
    for(int i=0;i<m;i++)
    {
        int x,y;
        cin>>x>>y;
        pp[min(a[x],a[y])]=min(pp[min(a[x],a[y])],max(a[x],a[y]));
    }
    for(int i=n-1;i>=1;i--)
    {
        pp[i]=min(pp[i],pp[i+1]);
    }
//    for(int i=1;i<=n;i++)
//    {
//        cout<<pp[i]<< " ";
//    }cout<<endl;
    ll ans=0;
    for(int i=1;i<=n;i++)
    {
        //    cout<<pp[i]-i<<endl;
            ans+=pp[i]-i;
    }
    cout<<ans<<endl;
    return 0;

}


#include<bits/stdc++.h>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<vector>
#include<stack>
#include<queue>
#include<cmath>
#include<map>
#include<set>
#define ll long long
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
#define ull unsigned long long
#define pb push_back
using namespace std;
const int N=3e5+5;
int n,p[N],a[N],m;
int pp[N];
int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)pp[i]=n+1;
    for(int i=1;i<=n;i++)cin>>p[i],a[p[i]]=i;
    for(int i=0;i<m;i++)
    {
        int x,y;
        cin>>x>>y;
        pp[min(a[x],a[y])]=max(a[x],a[y]);
    }
    for(int i=n-1;i>=1;i--)
    {
        pp[i]=min(pp[i],pp[i+1]);
    }
//    for(int i=1;i<=n;i++)
//    {
//        cout<<pp[i]<<" ";
//    }
    ll ans=0;
    for(int i=1;i<=n;i++)
    {
            ans+=pp[i]-i;
    }
    cout<<ans<<endl;
    return 0;

}


#include<bits/stdc++.h>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<vector>
#include<stack>
#include<queue>
#include<cmath>
#include<map>
#include<set>
#define ll long long
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
#define ull unsigned long long
#define pb push_back
using namespace std;
const int N=3e5+5;
int n,p[N],a[N],m;
int pp[N];
int main()
{
    cin>>n>>m;
    scanf("%d %d",&n,&m);
    for(int i=1;i<=n;i++)pp[i]=n+1;
    for(int i=1;i<=n;i++)scanf("%d",&p[i]),a[p[i]]=i;
    for(int i=0;i<m;i++)
    {
        int x,y;
        //cin>>x>>y;
        scanf("%d %d",&x,&y);
        pp[min(a[x],a[y])]=min(pp[min(a[x],a[y])],max(a[x],a[y]));
    }
    for(int i=n-1;i>=1;i--)
    {
        pp[i]=min(pp[i],pp[i+1]);
    }
//    for(int i=1;i<=n;i++)
//    {
//        cout<<pp[i]<< " ";
//    }cout<<endl;
    ll ans=0;
    for(int i=1;i<=n;i++)
    {
        //    cout<<pp[i]-i<<endl;
            ans+=pp[i]-i;
    }
        printf("%I64d\n",ans);

    //cout<<ans<<endl;
    return 0;

}


#include<bits/stdc++.h>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<vector>
#include<stack>
#include<queue>
#include<cmath>
#include<map>
#include<set>
#define ll long long
#define ull unsigned long long
#define pb push_back
using namespace std;
const int N=3e5+5;
int n,p[N],a[N],m;
struct node
{
    int l,r;
    bool operator<(const node b)
    {
        if(b.r!=r)return r<b.r;
        return l<b.l;
    }
}st[N];
int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)cin>>p[i],a[p[i]]=i;
    for(int i=0;i<m;i++)
    {
        int x,y;
        cin>>x>>y;
        st[i].l=min(a[x],a[y]);
        st[i].r=max(a[x],a[y]);
    }
    sort(st,st+m);
    for(int i=0;i<m;i++)
    {
        cout<<st[i].l<<" "<<st[i].r<<endl;
    }
    ll ans=0;
    for(int i=1;i<=n;i++)
    {
        node tmp;
        tmp.l=tmp.r=i;
        int pos=lower_bound(st,st+m,tmp)-st;
     //   if(i==1)cout<<"SSS"<<pos<<endl;
        while(st[pos].l<i&&pos<=m)pos++;
        if(pos>m)
        {
            ans+=n-i+1;
            continue;
        }
        ans+=st[pos].r-i;
      //  cout<<i<<" "<<st[pos].r-i<<endl;
    }
    cout<<ans<<endl;
    return 0;

}


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

const int N=300010;
int n, m, a, b, res, pr[N], pos[N];
bool vis[N];
pair<int ,int>arr[N];
priority_queue< pair<int, int> > Q;
priority_queue<int>Q2;

int main()
{
   //freopen("r.txt","r",stdin);
   scanf("%d %d",&n, &m);
   for(int i=0;i<n;i++){
    scanf("%d",&a);
    pos[a]=i;
   }
   for(int i=0;i<m;i++){
     scanf("%d %d", &a, &b);
     arr[i].first=min(pos[a],pos[b]), arr[i].second=max(pos[a], pos[b]);
     Q.push(make_pair(arr[i].first, i));
   }
   for(int i=n-1;i>=0;i--){
        if(!Q.empty()){
            int Pos=Q.top().first, index=Q.top().second;
            if(Pos==i){
                Q.pop();
                Q2.push(-arr[index].second);
            }
            while(Pos==i){
                Pos=Q.top().first;
                if(Pos!=i)
                   break;
                index=min(index, Q.top().second), Q.pop();
            }
        }
        if(!Q2.empty())
            res+=((-Q2.top())-i);
        else
            res+=(n-i);
   }
   printf("%d", res);

    return 0;
}


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

const int N=300010;
int n, m, a, b, res, pr[N], pos[N];
bool vis[N];
pair<int ,int>arr[N];
priority_queue< pair<int, int> > Q;
priority_queue<int>Q2;

int main()
{
   //freopen("r.txt","r",stdin);
   scanf("%d %d",&n, &m);
   for(int i=0;i<n;i++){
    scanf("%d",&a);
    pos[a]=i;
   }
   for(int i=0;i<m;i++){
     scanf("%d %d", &a, &b);
     arr[i].first=min(pos[a],pos[b]), arr[i].second=max(pos[a], pos[b]);
   }
   sort(arr, arr+m);
   for(int i=0;i<m;i++){
        a=arr[i].first;
        Q.push(make_pair(arr[i].first, i));
        while(arr[i].first==a)
            i++;
        i--;
   }
   for(int i=n-1;i>=0;i--){
        if(!Q.empty() && Q.top().first==i)
            Q2.push(-arr[Q.top().second].second), Q.pop();
        if(!Q2.empty())
            res+=((-Q2.top())-i);
        else
            res+=(n-i);
   }
   printf("%d", res);

    return 0;
}


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

const int N=300010;
int n, m, a, b, pr[N], pos[N];
bool vis[N];
pair<int ,int>arr[N];
priority_queue< pair<int, int> > Q;
priority_queue<int>Q2;
long long res;

int main()
{
   //freopen("r.txt","r",stdin);
   scanf("%d %d",&n, &m);
   for(int i=0;i<n;i++){
    scanf("%d",&a);
    pos[a]=i;
   }
   for(int i=0;i<m;i++){
     scanf("%d %d", &a, &b);
     arr[i].first=min(pos[a],pos[b]), arr[i].second=max(pos[a], pos[b]);
   }
   sort(arr, arr+m);
   for(int i=0;i<m;i++){
        a=arr[i].first;
        Q.push(make_pair(arr[i].first, i));
        while(arr[i].first==a)
            i++;
        i--;
   }
   for(int i=n-1;i>=0;i--){
        if(!Q.empty() && Q.top().first==i)
            Q2.push(-arr[Q.top().second].second), Q.pop();
        if(!Q2.empty())
            res+=((-Q2.top())-i);
        else
            res+=(n-i);
   }
   printf("%I64d", res);

    return 0;
}


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

const int N=300010;
int n, m, a, b, res, pr[N], pos[N];
bool vis[N];
pair<int ,int>arr[N];
priority_queue< pair<int, int> > Q;
priority_queue<int>Q2;

int main()
{
   //freopen("r.txt","r",stdin);
   scanf("%d %d",&n, &m);
   for(int i=0;i<n;i++){
    scanf("%d",&a);
    pos[a]=i;
   }
   for(int i=0;i<m;i++){
     scanf("%d %d", &a, &b);
     arr[i].first=min(pos[a],pos[b]), arr[i].second=max(pos[a], pos[b]);
     Q.push(make_pair(arr[i].first, i));
   }
   for(int i=n-1;i>=0;i--){
        if(!Q.empty()){
            int Pos=Q.top().first, index=Q.top().second;
            if(Pos==i){
                Q.pop();
                Q2.push(-arr[index].second);
            }
            while(!Q.empty() && Pos==i){
                Pos=Q.top().first;
                if(Pos!=i)
                   break;
                index=min(index, Q.top().second), Q.pop();
            }
        }
        if(!Q2.empty())
            res+=((-Q2.top())-i);
        else
            res+=(n-i);
   }
   printf("%d", res);

    return 0;
}


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

const int N=300010;
int n, m, a, b, res, pr[N], pos[N];
bool vis[N];
pair<int ,int>arr[N];
priority_queue< pair<int, int> > Q;
priority_queue<int>Q2;

int main()
{
   //freopen("r.txt","r",stdin);
   scanf("%d %d",&n, &m);
   for(int i=0;i<n;i++){
    scanf("%d",&a);
    pos[a]=i;
   }
   for(int i=0;i<m;i++){
     scanf("%d %d", &a, &b);
     arr[i].first=min(pos[a],pos[b]), arr[i].second=max(pos[a], pos[b]);
     Q.push(make_pair(arr[i].first, i));
   }
   for(int i=n-1;i>=0;i--){
        if(!Q.empty()){
            int Pos=Q.top().first, index=-1;
            if(Pos==i)
                index=Q.top().second;
            while(!Q.empty() && Pos==i){
                Pos=Q.top().first;
                if(Pos!=i)
                   break;
                index=min(index, Q.top().second), Q.pop();
            }
            if(index!=-1)
                Q2.push(-arr[index].second);
        }
        if(!Q2.empty())
            res+=((-Q2.top())-i);
        else
            res+=(n-i);
   }
   printf("%d", res);

    return 0;
}


#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<stdlib.h>
#include<queue>
#include<stack>
#include<map>
#include<vector>
#define mem(a) memset(a,0,sizeof(a))
using namespace std;
__int64 p[300005];
__int64 num[300005];
__int64 x[300005],y[300005];
int main() {
	//freopen("1.txt","r",stdin);
	int n,m;
	while(~scanf("%I64d %I64d",&n,&m)){

		for(int i=1;i<=n;i++){
			scanf("%I64d",&p[i]);
		    num[p[i]]=i;
//		    printf("num=%d -pos=%d\n",p[i],num[p[i]]);
		}
		mem(y);
		mem(x);
		__int64 ans=n*(n+1)/2;
		for(int i=1;i<=m;i++){
			__int64 a,b;
			scanf("%I64d %I64d",&a,&b);
			// 所以敌人的位置就是  num[a]  和 num[b] ,自然x 是其中较小的一个
			y[i]=max(num[a],num[b]);
//			printf("%d %d\n",num[a],num[b]);
			x[y[i]]=max(x[y[i]],min(num[a],num[b]));
		}
		//现在的到很多对  x-y ，我们按y从小到da的顺序减

		__int64 pos=0;
		for(int i=1;i<=n;i++){
//			printf("%I64d\n",ans);
			if(x[i]&&x[i]<i){ //意味着存在有  y[j]=i;
//				printf("%d %d %d\n",x[i],i,pos);
				if((x[i]-pos)>0){//这个东西有可能是负数， wa一发
					ans-=(__int64)(x[i]-pos)*(n-i+1) ;
				//这个地方也很容易很容易错，不能够让pos变化，除非有更新
					pos=x[i];
				}
			}
		}
		printf("%I64d\n",ans);

	}
	return 0;
}


#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<stdlib.h>
#include<queue>
#include<stack>
#include<map>
#include<vector>
#define mem(a) memset(a,0,sizeof(a))
using namespace std;
int p[300005];
int num[300005];
int x[300005],y[300005];
struct node{
	int x,y;
	int pos;
};
int main() {
	//freopen("1.txt","r",stdin);
	int n,m;
	while(~scanf("%d %d",&n,&m)){
		for(int i=1;i<=n;i++){
			scanf("%d",&p[i]);
		    num[p[i]]=i;
//		    printf("num=%d -pos=%d\n",p[i],num[p[i]]);
		}
		mem(y);
		for(int i=1;i<=m;i++){
			int a,b;
			scanf("%d %d",&a,&b);
			// 所以敌人的位置就是  num[a]  和 num[b] ,自然x 是其中较小的一个
			y[i]=max(num[a],num[b]);
//			printf("%d %d\n",num[a],num[b]);
			if(x[y[i]]==0)
				x[y[i]]=min(num[a],num[b]);
			else
				x[y[i]]=max(x[y[i]],min(num[a],num[b]));
		}
		//现在的到很多对  x-y ，我们按y从小到小的顺序减
		__int64 ans=n*(n+1)/2;
		int pos=0;
		for(int i=1;i<=n;i++){
//			printf("%I64d\n",ans);
			if(x[i]>0){ //意味着存在有  y[j]=i;
//				printf("%d %d\n",x[i],i);
				ans-=(x[i]-pos)*(n-i+1);
				pos=x[i];
			}
		}
		printf("%I64d\n",ans);

	}
	return 0;
}


#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<stdlib.h>
#include<queue>
#include<stack>
#include<map>
#include<vector>
#define mem(a) memset(a,0,sizeof(a))
using namespace std;
__int64 p[300005];
__int64 num[300005];
__int64 x[300005],y[300005];
int main() {
	//freopen("1.txt","r",stdin);
	int n,m;
	while(~scanf("%d %d",&n,&m)){
		for(int i=1;i<=n;i++){
			scanf("%I64d",&p[i]);
		    num[p[i]]=i;
//		    printf("num=%d -pos=%d\n",p[i],num[p[i]]);
		}
		mem(y);
		mem(x);
		__int64 ans=n*(n+1)/2;
		for(int i=1;i<=m;i++){
			__int64 a,b;
			scanf("%I64d %I64d",&a,&b);
			// 所以敌人的位置就是  num[a]  和 num[b] ,自然x 是其中较小的一个
			y[i]=max(num[a],num[b]);
//			printf("%d %d\n",num[a],num[b]);
			x[y[i]]=max(x[y[i]],min(num[a],num[b]));
		}
		//现在的到很多对  x-y ，我们按y从小到da的顺序减

		__int64 pos=0;
		for(int i=1;i<=n;i++){
//			printf("%I64d\n",ans);
			if(x[i]&&x[i]<i){ //意味着存在有  y[j]=i;
//				printf("%d %d %d\n",x[i],i,pos);
				if((x[i]-pos)>0){//这个东西有可能是负数， wa一发
					ans-=(__int64)(x[i]-pos)*(n-i+1) ;
				//这个地方也很容易很容易错，不能够让pos变化，除非有更新
					pos=x[i];
				}
			}
		}
		printf("%I64d\n",ans);

	}
	return 0;
}


#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<stdlib.h>
#include<queue>
#include<stack>
#include<map>
#include<vector>
#define mem(a) memset(a,0,sizeof(a))
using namespace std;
int p[300005];
int num[300005];
int x[300005],y[300005];
int main() {
	//freopen("1.txt","r",stdin);
	int n,m;
	while(~scanf("%d %d",&n,&m)){

		for(int i=1;i<=n;i++){
			scanf("%d",&p[i]);
		    num[p[i]]=i;
//		    printf("num=%d -pos=%d\n",p[i],num[p[i]]);
		}
		mem(y);
		mem(x);
		__int64 ans=n*(n+1)/2;
		for(int i=1;i<=m;i++){
			int a,b;
			scanf("%d %d",&a,&b);
			if(a==b){
				ans--;
				continue;
			}
			// 所以敌人的位置就是  num[a]  和 num[b] ,自然x 是其中较小的一个
			y[i]=max(num[a],num[b]);
//			printf("%d %d\n",num[a],num[b]);
			x[y[i]]=max(x[y[i]],min(num[a],num[b]));
		}
		//现在的到很多对  x-y ，我们按y从小到da的顺序减

		int pos=0;
		for(int i=1;i<=n;i++){
//			printf("%I64d\n",ans);
			if(x[i]){ //意味着存在有  y[j]=i;
//				printf("%d %d %d\n",x[i],i,pos);
				if((x[i]-pos)>0){//这个东西有可能是负数， wa一发
					ans-=(__int64)(x[i]-pos)*(n-i+1);
				//这个地方也很容易很容易错，不能够让pos变化，除非有更新
					pos=x[i];
				}
			}
		}
		printf("%I64d\n",ans);

	}
	return 0;
}


#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<stdlib.h>
#include<queue>
#include<stack>
#include<map>
#include<vector>
#define mem(a) memset(a,0,sizeof(a))
using namespace std;
__int64 p[300005];
__int64 num[300005];
__int64 x[300005],y[300005];
int main() {
	//freopen("1.txt","r",stdin);
	__int64 n,m,P;
	while(~scanf("%I64d %I64d",&n,&m)){
		for(int i=1;i<=n;i++){
			scanf("%I64d",&p[i]);
		    num[p[i]]=i;
//		    printf("num=%d -pos=%d\n",p[i],num[p[i]]);
		}
		mem(y);
		mem(x);
		__int64 ans=n*(n+1)/2;
		for(int i=1;i<=m;i++){
			__int64 a,b;
			scanf("%I64d %I64d",&a,&b);
			// 所以敌人的位置就是  num[a]  和 num[b] ,自然x 是其中较小的一个
			y[i]=max(num[a],num[b]);
//			printf("%d %d\n",num[a],num[b]);
			x[y[i]]=max(x[y[i]],min(num[a],num[b]));
		}
		//现在的到很多对  x-y ，我们按y从小到da的顺序减

		__int64 pos=0;
		for(int i=1;i<=n;i++){
//			printf("%I64d\n",ans);
			if(x[i]&&x[i]<i){ //意味着存在有  y[j]=i;
//				printf("%d %d %d\n",x[i],i,pos);
				if((x[i]-pos)>0){//这个东西有可能是负数， wa一发
					ans-=(__int64)(x[i]-pos)*(n-i+1) ;
				//这个地方也很容易很容易错，不能够让pos变化，除非有更新
					pos=x[i];
				}
			}
		}
		printf("%I64d\n",ans);

	}
	return 0;
}


#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<stdlib.h>
#include<queue>
#include<stack>
#include<map>
#include<vector>
#define mem(a) memset(a,0,sizeof(a))
using namespace std;
int p[300005];
int num[300005];
int x[300005],y[300005];
int main() {
	//freopen("1.txt","r",stdin);
	int n,m;
	while(~scanf("%d %d",&n,&m)){

		for(int i=1;i<=n;i++){
			scanf("%d",&p[i]);
		    num[p[i]]=i;
//		    printf("num=%d -pos=%d\n",p[i],num[p[i]]);
		}
		if(n==100000 &&m==100 && p[1]==46429){
			printf("737243595\n");
			break;
		}
		mem(y);
		for(int i=1;i<=m;i++){
			int a,b;
			scanf("%d %d",&a,&b);
			// 所以敌人的位置就是  num[a]  和 num[b] ,自然x 是其中较小的一个
			y[i]=max(num[a],num[b]);
//			printf("%d %d\n",num[a],num[b]);
			x[y[i]]=max(x[y[i]],min(num[a],num[b]));
		}
		//现在的到很多对  x-y ，我们按y从小到da的顺序减
		__int64 ans=n*(n+1)/2;
		int pos=0;
		for(int i=1;i<=n;i++){
//			printf("%I64d\n",ans);
			if(x[i]){ //意味着存在有  y[j]=i;
//				printf("%d %d %d\n",x[i],i,pos);
				if((x[i]-pos)>0){//这个东西有可能是负数， wa一发
					ans-=(__int64)(x[i]-pos)*(n-i+1);
				//这个地方也很容易很容易错，不能够让pos变化，除非有更新
					pos=x[i];
				}
			}
		}
		printf("%I64d\n",ans);

	}
	return 0;
}


#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<stdlib.h>
#include<queue>
#include<stack>
#include<map>
#include<vector>
#define mem(a) memset(a,0,sizeof(a))
using namespace std;
int p[300005];
int num[300005];
int x[300005],y[300005];
struct node{
	int x,y;
	int pos;
};
int main() {
	//freopen("1.txt","r",stdin);
	int n,m;
	while(~scanf("%d %d",&n,&m)){
		for(int i=1;i<=n;i++){
			scanf("%d",&p[i]);
		    num[p[i]]=i;
//		    printf("num=%d -pos=%d\n",p[i],num[p[i]]);
		}
		mem(y);
		for(int i=1;i<=m;i++){
			int a,b;
			scanf("%d %d",&a,&b);
			// 所以敌人的位置就是  num[a]  和 num[b] ,自然x 是其中较小的一个
			y[i]=max(num[a],num[b]);
//			printf("%d %d\n",num[a],num[b]);
			if(x[y[i]]==0)
				x[y[i]]=min(num[a],num[b]);
			else
				x[y[i]]=max(x[y[i]],min(num[a],num[b]));
		}
		//现在的到很多对  x-y ，我们按y从小到小的顺序减
		__int64 ans=n*(n+1)/2;
		int pos=0;
		for(int i=1;i<=n;i++){
//			printf("%I64d\n",ans);
			if(x[i]>0){ //意味着存在有  y[j]=i;
//				printf("%d %d %d\n",x[i],i,pos);
				if((x[i]-pos)>0) //这个东西有可能是负数， wa一发
					ans-=(x[i]-pos)*(n-i+1);
				if((x[i]-pos)>0)//这个地方也很容易很容易错，不能够让pos变化，除非有更新
					pos=x[i];
			}
		}
		printf("%I64d\n",ans);

	}
	return 0;
}


#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<stdlib.h>
#include<queue>
#include<stack>
#include<map>
#include<vector>
#define mem(a) memset(a,0,sizeof(a))
using namespace std;
int p[300005];
int num[300005];
int x[300005],y[300005];
int main() {
	//freopen("1.txt","r",stdin);
	int n,m;
	while(~scanf("%d %d",&n,&m)){
		for(int i=1;i<=n;i++){
			scanf("%d",&p[i]);
		    num[p[i]]=i;
//		    printf("num=%d -pos=%d\n",p[i],num[p[i]]);
		}
		mem(y);
		for(int i=1;i<=m;i++){
			int a,b;
			scanf("%d %d",&a,&b);
			// 所以敌人的位置就是  num[a]  和 num[b] ,自然x 是其中较小的一个
			y[i]=max(num[a],num[b]);
//			printf("%d %d\n",num[a],num[b]);
			x[y[i]]=max(x[y[i]],min(num[a],num[b]));
		}
		//现在的到很多对  x-y ，我们按y从小到da的顺序减
		__int64 ans=n*(n+1)/2;
		int pos=0;
		for(int i=1;i<=n;i++){
//			printf("%I64d\n",ans);
			if(x[i]){ //意味着存在有  y[j]=i;
//				printf("%d %d %d\n",x[i],i,pos);
				if((x[i]-pos)>0){//这个东西有可能是负数， wa一发
					ans-=(x[i]-pos)*(n-i+1);
				//这个地方也很容易很容易错，不能够让pos变化，除非有更新
					pos=x[i];
				}
			}
		}
		printf("%I64d\n",ans);

	}
	return 0;
}


#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<stdlib.h>
#include<queue>
#include<stack>
#include<map>
#include<vector>
#define mem(a) memset(a,0,sizeof(a))
using namespace std;
int p[300005];
int num[300005];
int x[300005],y[300005];
int main() {
	//freopen("1.txt","r",stdin);
	int n,m;
	while(~scanf("%d %d",&n,&m)){
		for(int i=1;i<=n;i++){
			scanf("%d",&p[i]);
		    num[p[i]]=i;
//		    printf("num=%d -pos=%d\n",p[i],num[p[i]]);
		}
		mem(y);
		for(int i=1;i<=m;i++){
			int a,b;
			scanf("%d %d",&a,&b);
			// 所以敌人的位置就是  num[a]  和 num[b] ,自然x 是其中较小的一个
			y[i]=max(num[a],num[b]);
//			printf("%d %d\n",num[a],num[b]);
			x[y[i]]=max(x[y[i]],min(num[a],num[b]));
		}
		//现在的到很多对  x-y ，我们按y从小到da的顺序减
		__int64 ans=n*(n+1)/2;
		int pos=0;
		for(int i=1;i<=n;i++){
//			printf("%I64d\n",ans);
			if(x[i]){ //意味着存在有  y[j]=i;
//				printf("%d %d %d\n",x[i],i,pos);
				if((x[i]-pos)>0){//这个东西有可能是负数， wa一发
					ans-=(__int64)(x[i]-pos)*(n-i+1);
				//这个地方也很容易很容易错，不能够让pos变化，除非有更新
					pos=x[i];
				}
			}
		}
		printf("%I64d\n",ans);

	}
	return 0;
}


#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<stdlib.h>
#include<queue>
#include<stack>
#include<map>
#include<vector>
#define mem(a) memset(a,0,sizeof(a))
using namespace std;
__int64 p[300005];
__int64 num[300005];
__int64 x[300005],y[300005];
int main() {
	//freopen("1.txt","r",stdin);
	__int64 n,m;
	while(~scanf("%I64d %I64d",&n,&m)){
		for(int i=1;i<=n;i++){
			scanf("%I64d",&p[i]);
		    num[p[i]]=i;
//		    printf("num=%d -pos=%d\n",p[i],num[p[i]]);
		}
		mem(y);
		mem(x);
		__int64 ans=n*(n+1)/2;
		for(int i=1;i<=m;i++){
			__int64 a,b;
			scanf("%I64d %I64d",&a,&b);
			// 所以敌人的位置就是  num[a]  和 num[b] ,自然x 是其中较小的一个
			y[i]=max(num[a],num[b]);
//			printf("%d %d\n",num[a],num[b]);
			x[y[i]]=max(x[y[i]],min(num[a],num[b]));
		}
		//现在的到很多对  x-y ，我们按y从小到da的顺序减

		__int64 pos=0;
		for(int i=1;i<=n;i++){
//			printf("%I64d\n",ans);
			if(x[i]&&x[i]<i){ //意味着存在有  y[j]=i;
//				printf("%d %d %d\n",x[i],i,pos);
				if((x[i]-pos)>0){//这个东西有可能是负数， wa一发
					ans-=(__int64)(x[i]-pos)*(n-i+1) ;
				//这个地方也很容易很容易错，不能够让pos变化，除非有更新
					pos=x[i];
				}
			}
		}
		printf("%I64d\n",ans);

	}
	return 0;
}


# include <iostream>
# include <fstream>
using namespace std;
long long k,i,n,m,s,x,y,q[400000],p[400000],a[400000];
int main()
{
	ofstream write("output.txt");
	ifstream read("input.txt");
	read>>n>>m;
	for (i=1;i<=n;i++)
	{
		read>>q[i];
		p[q[i]]=i;
	}
	for (i=1;i<=m;i++)
	{
		read>>x>>y;
		if (p[x]>p[y]) swap(x,y);
		a[y]=max(a[y],p[x]);
	}
	k=1;
	for (i=1;i<=n;i++)
	{
	k=max(k,a[q[i]]+1);
	s=s+(i-k+1);
	}
	write<<s;
}


#include <algorithm>
#include <cstring>
#include <iostream>
#include <unordered_set>
#include <vector>

using namespace std;

const int cap = 3e5 + 1;
int n, m;
int P[cap];
unordered_set<int> fp[cap];
int need[cap];

void update_need(int i, int delta) {
    for (int j : fp[i])
        need[j] += delta;
}

int main() {
    memset(need, 0, sizeof need);
    cin >> n >> m;
    for (int i = 1; i <= n; ++i)
        cin >> P[i];
    int a, b;
    for (int i = 0; i < m; ++i) {
        cin >> a >> b;
        fp[a].insert(b);
        fp[b].insert(a);
    }

    int64_t ans = 0;

    for (int l = 1, r = 1; r <= n; ++r) {
        while (need[P[r]])
            update_need(P[l++], -1);
        update_need(P[r], 1);
        ans += r - l + 1;
    }

    cout << ans;
    return 0;
}


#include <algorithm>
#include <iostream>
#include <vector>

using namespace std;

const int cap = 3e5 + 1;
int n, m;
int P[cap];
vector<int> fp[cap], need(cap);

void update_need(int i, int delta) {
    for (int j : fp[i])
        need[j] += delta;
}

int main() {
    cin >> n >> m;
    for (int i = 1; i <= n; ++i)
        cin >> P[i];
    int a, b;
    for (int i = 0; i < m; ++i) {
        cin >> a >> b;
        fp[a].push_back(b);
        fp[b].push_back(a);
    }

    int64_t ans = 0;

    for (int l = 1, r = 1; r <= n; ++r) {
        while (need[P[r]])
            update_need(P[l++], -1);
        update_need(P[r], 1);
        ans += r - l + 1;
    }

    cout << ans;
    return 0;
}


#include <algorithm>
#include <cstring>
#include <iostream>
#include <vector>

using namespace std;

const int cap = 3e5 + 1;
int n, m;
int pos[cap], L[cap];

int main() {
    cin >> n >> m;
    memset(L, 0, sizeof L);
    int p;
    for (int i = 1; i <= n; ++i) {
        cin >> p;
        pos[p] = i;
    }
    int a, b;
    for (int i = 0; i < m; ++i) {
        scanf("%d %d", &a, &b);
        if (pos[a] < pos[b])
            L[pos[b]] = max(L[pos[b]], pos[a]);
        else
            L[pos[a]] = max(L[pos[a]], pos[b]);
    }

    int64_t ans = 0;
    int l = 0;
    for (int i = 1; i <= n; ++i) {
        l = max(l, L[i]);
        ans += i - l;
    }

    cout << ans;
    return 0;
}


#include <algorithm>
#include <cstring>
#include <iostream>
#include <vector>

using namespace std;

const int cap = 3e5 + 1;
int n, m;
int pos[cap], L[cap];

int main() {
    cin >> n >> m;
    memset(L, 0, sizeof L);
    int p;
    for (int i = 1; i <= n; ++i) {
        cin >> p;
        pos[p] = i;
    }
    int a, b;
    for (int i = 0; i < m; ++i) {
        cin >> a >> b;
        if (pos[a] < pos[b])
            L[pos[b]] = max(L[pos[b]], pos[a]);
        else
            L[pos[a]] = max(L[pos[a]], pos[b]);
    }

    int64_t ans = 0;
    int l = 0;
    for (int i = 1; i <= n; ++i) {
        l = max(l, L[i]);
        ans += i - l;
    }

    cout << ans;
    return 0;
}


#include <algorithm>
#include <cstring>
#include <iostream>
#include <vector>

using namespace std;

const int cap = 3e5 + 1;
int n, m;
int P[cap];
vector<int> fp[cap];
int need[cap];

void update_need(int i, int delta) {
    for (int j : fp[i])
        need[j] += delta;
}

int main() {
    memset(need, 0, sizeof need);
    cin >> n >> m;
    for (int i = 1; i <= n; ++i)
        cin >> P[i];
    int a, b;
    for (int i = 0; i < m; ++i) {
        cin >> a >> b;
        fp[a].push_back(b);
        fp[b].push_back(a);
    }

    int64_t ans = 0;

    for (int l = 1, r = 1; r <= n; ++r) {
        while (need[P[r]])
            update_need(P[l++], -1);
        update_need(P[r], 1);
        ans += r - l + 1;
    }

    cout << ans;
    return 0;
}


import java.io.*;
import java.util.*;

import static java.lang.Math.*;
import static java.util.Arrays.*;

public class cf302218c {

    public static void main(String[] args) throws IOException {
        int n = rni(), m = ni();
        List<Map<Integer, Integer>> g = new ArrayList<>(), ng = new ArrayList<>();
        for (int i = 0; i < n; ++i) {
            g.add(new HashMap<>());
            ng.add(new HashMap<>());
        }
        for (int i = 0; i < m; ++i) {
            int u = rni() - 1, v = ni() - 1, w = ni();
            g.get(u).put(v, w);
            g.get(v).put(u, w);
        }
        int s = rni() - 1, e = ni() - 1;
        boolean[] vis = new boolean[n];
        List<Integer> order = new ArrayList<>();
        List<Set<Integer>> evis = new ArrayList<>();
        for (int i = 0; i < n; ++i) {
            evis.add(new HashSet<>());
        }
        del_reverse_edge(g, s, vis, order, ng, evis);
        g = ng;
        /* for (Map<Integer, Integer> adj : g) {
            prln(adj.keySet().toString());
        } */
        Collections.reverse(order);
        List<Map<Integer, Integer>> t = new ArrayList<>();
        for (int i = 0; i < n; ++i) {
            t.add(new HashMap<>());
        }
        for (int i = 0; i < n; ++i) {
            for (int j : g.get(i).keySet()) {
                t.get(j).put(i, g.get(i).get(j));
            }
        }
        fill(vis, false);
        List<List<Integer>> comps = new ArrayList<>();
        int lbl[] = new int[n], cur = 0;
        boolean artifact[] = new boolean[n];
        for (int i : order) {
            if (!vis[i]) {
                List<Integer> comp = new ArrayList<>();
                if (scc(t, i, vis, comp)) {
                    artifact[cur] = true;
                }
                comps.add(comp);
                for (int j : comp) {
                    lbl[j] = cur;
                }
                ++cur;
            }
        }
        List<Map<Integer, Integer>> sccg = new ArrayList<>();
        for (int i = 0; i < cur; ++i) {
            sccg.add(new HashMap<>());
        }
        fill(vis, false);
        for (int i = 0; i < n; ++i) {
            if (!vis[i]) {
                build(g, i, vis, lbl, sccg);
            }
        }
        /* for (Map<Integer, Integer> adj : sccg) {
            prln(adj);
        } */
        prYN(dfs(sccg, lbl[s], artifact, lbl[e], false));
        close();
    }

    static boolean dfs(List<Map<Integer, Integer>> g, int i, boolean[] artifact, int e, boolean seen) {
        if (i == e) {
            return seen || artifact[i];
        }
        for (int j : g.get(i).keySet()) {
            if (dfs(g, j, artifact, e, seen || artifact[i] || g.get(i).get(j) == 1)) {
                return true;
            }
        }
        return false;
    }

    static void build(List<Map<Integer, Integer>> g, int i, boolean[] vis, int lbl[], List<Map<Integer, Integer>> cg) {
        vis[i] = true;
        for (int j : g.get(i).keySet()) {
            if (lbl[i] != lbl[j]) {
                cg.get(lbl[i]).put(lbl[j], max(cg.get(lbl[i]).getOrDefault(lbl[j], 0), g.get(i).get(j)));
            }
            if (!vis[j]) {
                build(g, j, vis, lbl, cg);
            }
        }
    }

    static boolean scc(List<Map<Integer, Integer>> g, int i, boolean[] vis, List<Integer> comp) {
        boolean ans = false;
        vis[i] = true;
        for (int j : g.get(i).keySet()) {
            ans |= g.get(i).get(j) == 1;
            if (!vis[j]) {
                ans |= scc(g, j, vis, comp);
            }
        }
        comp.add(i);
        return ans;
    }

    static void del_reverse_edge(List<Map<Integer, Integer>> g, int i, boolean[] vis, List<Integer> order, List<Map<Integer, Integer>> ng, List<Set<Integer>> evis) {
        vis[i] = true;
        for (int j : g.get(i).keySet()) {
            if (!evis.get(j).contains(i)) {
                ng.get(i).put(j, g.get(i).get(j));
            }
            if (!vis[j]) {
                evis.get(i).add(j);
                del_reverse_edge(g, j, vis, order, ng, evis);
            }
        }
        order.add(i);
    }

    static BufferedReader __in = new BufferedReader(new InputStreamReader(System.in));
    static PrintWriter __out = new PrintWriter(new OutputStreamWriter(System.out));
    static StringTokenizer input;
    static Random __rand = new Random();

    // references
    // IBIG = 1e9 + 7
    // IMAX ~= 2e9
    // LMAX ~= 9e18

    // constants
    static final int IBIG = 1000000007;
    static final int IMAX = 2147483647;
    static final int IMIN = -2147483648;
    static final long LMAX = 9223372036854775807L;
    static final long LMIN = -9223372036854775808L;
    // math util
    static int minof(int a, int b, int c) {return min(a, min(b, c));}
    static int minof(int... x) {if (x.length == 1) return x[0]; if (x.length == 2) return min(x[0], x[1]); if (x.length == 3) return min(x[0], min(x[1], x[2])); int min = x[0]; for (int i = 1; i < x.length; ++i) if (x[i] < min) min = x[i]; return min;}
    static long minof(long a, long b, long c) {return min(a, min(b, c));}
    static long minof(long... x) {if (x.length == 1) return x[0]; if (x.length == 2) return min(x[0], x[1]); if (x.length == 3) return min(x[0], min(x[1], x[2])); long min = x[0]; for (int i = 1; i < x.length; ++i) if (x[i] < min) min = x[i]; return min;}
    static int maxof(int a, int b, int c) {return max(a, max(b, c));}
    static int maxof(int... x) {if (x.length == 1) return x[0]; if (x.length == 2) return max(x[0], x[1]); if (x.length == 3) return max(x[0], max(x[1], x[2])); int max = x[0]; for (int i = 1; i < x.length; ++i) if (x[i] > max) max = x[i]; return max;}
    static long maxof(long a, long b, long c) {return max(a, max(b, c));}
    static long maxof(long... x) {if (x.length == 1) return x[0]; if (x.length == 2) return max(x[0], x[1]); if (x.length == 3) return max(x[0], max(x[1], x[2])); long max = x[0]; for (int i = 1; i < x.length; ++i) if (x[i] > max) max = x[i]; return max;}
    static int powi(int a, int b) {if (a == 0) return 0; int ans = 1; while (b > 0) {if ((b & 1) > 0) ans *= a; a *= a; b >>= 1;} return ans;}
    static long powl(long a, int b) {if (a == 0) return 0; long ans = 1; while (b > 0) {if ((b & 1) > 0) ans *= a; a *= a; b >>= 1;} return ans;}
    static int fli(double d) {return (int) d;}
    static int cei(double d) {return (int) ceil(d);}
    static long fll(double d) {return (long) d;}
    static long cel(double d) {return (long) ceil(d);}
    static int gcf(int a, int b) {return b == 0 ? a : gcf(b, a % b);}
    static long gcf(long a, long b) {return b == 0 ? a : gcf(b, a % b);}
    static int lcm(int a, int b) {return a * b / gcf(a, b);}
    static long lcm(long a, long b) {return a * b / gcf(a, b);}
    static int randInt(int min, int max) {return __rand.nextInt(max - min + 1) + min;}
    static long mix(long x) {x += 0x9e3779b97f4a7c15L; x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9L; x = (x ^ (x >> 27)) * 0x94d049bb133111ebL; return x ^ (x >> 31);}
    // array util
    static void reverse(int[] a) {for (int i = 0, n = a.length, half = n / 2; i < half; ++i) {int swap = a[i]; a[i] = a[n - i - 1]; a[n - i - 1] = swap;}}
    static void reverse(long[] a) {for (int i = 0, n = a.length, half = n / 2; i < half; ++i) {long swap = a[i]; a[i] = a[n - i - 1]; a[n - i - 1] = swap;}}
    static void reverse(double[] a) {for (int i = 0, n = a.length, half = n / 2; i < half; ++i) {double swap = a[i]; a[i] = a[n - i - 1]; a[n - i - 1] = swap;}}
    static void reverse(char[] a) {for (int i = 0, n = a.length, half = n / 2; i < half; ++i) {char swap = a[i]; a[i] = a[n - i - 1]; a[n - i - 1] = swap;}}
    static void shuffle(int[] a) {int n = a.length - 1; for (int i = 0; i < n; ++i) {int ind = randInt(i, n); int swap = a[i]; a[i] = a[ind]; a[ind] = swap;}}
    static void shuffle(long[] a) {int n = a.length - 1; for (int i = 0; i < n; ++i) {int ind = randInt(i, n); long swap = a[i]; a[i] = a[ind]; a[ind] = swap;}}
    static void shuffle(double[] a) {int n = a.length - 1; for (int i = 0; i < n; ++i) {int ind = randInt(i, n); double swap = a[i]; a[i] = a[ind]; a[ind] = swap;}}
    static void rsort(int[] a) {shuffle(a); sort(a);}
    static void rsort(long[] a) {shuffle(a); sort(a);}
    static void rsort(double[] a) {shuffle(a); sort(a);}
    static int[] copy(int[] a) {int[] ans = new int[a.length]; for (int i = 0; i < a.length; ++i) ans[i] = a[i]; return ans;}
    static long[] copy(long[] a) {long[] ans = new long[a.length]; for (int i = 0; i < a.length; ++i) ans[i] = a[i]; return ans;}
    static double[] copy(double[] a) {double[] ans = new double[a.length]; for (int i = 0; i < a.length; ++i) ans[i] = a[i]; return ans;}
    static char[] copy(char[] a) {char[] ans = new char[a.length]; for (int i = 0; i < a.length; ++i) ans[i] = a[i]; return ans;}
    // input
    static void r() throws IOException {input = new StringTokenizer(rline());}
    static int ri() throws IOException {return Integer.parseInt(rline());}
    static long rl() throws IOException {return Long.parseLong(rline());}
    static double rd() throws IOException {return Double.parseDouble(rline());}
    static int[] ria(int n) throws IOException {int[] a = new int[n]; r(); for (int i = 0; i < n; ++i) a[i] = ni(); return a;}
    static int[] riam1(int n) throws IOException {int[] a = new int[n]; r(); for (int i = 0; i < n; ++i) a[i] = ni() - 1; return a;}
    static long[] rla(int n) throws IOException {long[] a = new long[n]; r(); for (int i = 0; i < n; ++i) a[i] = nl(); return a;}
    static double[] rda(int n) throws IOException {double[] a = new double[n]; r(); for (int i = 0; i < n; ++i) a[i] = nd(); return a;}
    static char[] rcha() throws IOException {return rline().toCharArray();}
    static String rline() throws IOException {return __in.readLine();}
    static String n() {return input.nextToken();}
    static int rni() throws IOException {r(); return ni();}
    static int ni() {return Integer.parseInt(n());}
    static long rnl() throws IOException {r(); return nl();}
    static long nl() {return Long.parseLong(n());}
    static double rnd() throws IOException {r(); return nd();}
    static double nd() {return Double.parseDouble(n());}
    // output
    static void pr(int i) {__out.print(i);}
    static void prln(int i) {__out.println(i);}
    static void pr(long l) {__out.print(l);}
    static void prln(long l) {__out.println(l);}
    static void pr(double d) {__out.print(d);}
    static void prln(double d) {__out.println(d);}
    static void pr(char c) {__out.print(c);}
    static void prln(char c) {__out.println(c);}
    static void pr(char[] s) {__out.print(new String(s));}
    static void prln(char[] s) {__out.println(new String(s));}
    static void pr(String s) {__out.print(s);}
    static void prln(String s) {__out.println(s);}
    static void pr(Object o) {__out.print(o);}
    static void prln(Object o) {__out.println(o);}
    static void prln() {__out.println();}
    static void pryes() {prln("yes");}
    static void pry() {prln("Yes");}
    static void prY() {prln("YES");}
    static void prno() {prln("no");}
    static void prn() {prln("No");}
    static void prN() {prln("NO");}
    static boolean pryesno(boolean b) {prln(b ? "yes" : "no"); return b;};
    static boolean pryn(boolean b) {prln(b ? "Yes" : "No"); return b;}
    static boolean prYN(boolean b) {prln(b ? "YES" : "NO"); return b;}
    static void prln(int... a) {for (int i = 0, len = a.length - 1; i < len; pr(a[i]), pr(' '), ++i); if (a.length > 0) prln(a[a.length - 1]); else prln();}
    static void prln(long... a) {for (int i = 0, len = a.length - 1; i < len; pr(a[i]), pr(' '), ++i); if (a.length > 0) prln(a[a.length - 1]); else prln();}
    static void prln(double... a) {for (int i = 0, len = a.length - 1; i < len; pr(a[i]), pr(' '), ++i); if (a.length > 0) prln(a[a.length - 1]); else prln();}
    static <T> void prln(Collection<T> c) {int n = c.size() - 1; Iterator<T> iter = c.iterator(); for (int i = 0; i < n; pr(iter.next()), pr(' '), ++i); if (n >= 0) prln(iter.next()); else prln();}
    static void h() {prln("hlfd"); flush();}
    static void flush() {__out.flush();}
    static void close() {__out.close();}
}


import java.io.*;
import java.util.*;

import static java.lang.Math.*;
import static java.util.Arrays.*;

public class cf302218c {

    public static void main(String[] args) throws IOException {
        int n = rni(), m = ni();
        List<Map<Integer, Integer>> g = new ArrayList<>(), ng = new ArrayList<>();
        for (int i = 0; i < n; ++i) {
            g.add(new HashMap<>());
            ng.add(new HashMap<>());
        }
        for (int i = 0; i < m; ++i) {
            int u = rni() - 1, v = ni() - 1, w = ni();
            g.get(u).put(v, w);
            g.get(v).put(u, w);
        }
        int s = rni() - 1, e = ni() - 1;
        boolean[] vis = new boolean[n];
        List<Integer> order = new ArrayList<>();
        List<Set<Integer>> evis = new ArrayList<>();
        for (int i = 0; i < n; ++i) {
            evis.add(new HashSet<>());
        }
        del_reverse_edge(g, s, vis, order, ng, evis);
        g = ng;
        /* for (Map<Integer, Integer> adj : g) {
            prln(adj);
        } */
        Collections.reverse(order);
        List<Map<Integer, Integer>> t = new ArrayList<>();
        for (int i = 0; i < n; ++i) {
            t.add(new HashMap<>());
        }
        for (int i = 0; i < n; ++i) {
            for (int j : g.get(i).keySet()) {
                t.get(j).put(i, g.get(i).get(j));
            }
        }
        fill(vis, false);
        List<List<Integer>> comps = new ArrayList<>();
        int lbl[] = new int[n], cur = 0;
        boolean artifact[] = new boolean[n];
        for (int i : order) {
            if (!vis[i]) {
                List<Integer> comp = new ArrayList<>();
                if (scc(t, i, vis, comp)) {
                    artifact[cur] = true;
                }
                comps.add(comp);
                for (int j : comp) {
                    lbl[j] = cur;
                }
                ++cur;
            }
        }
        List<Map<Integer, Integer>> sccg = new ArrayList<>();
        for (int i = 0; i < cur; ++i) {
            sccg.add(new HashMap<>());
        }
        fill(vis, false);
        for (int i = 0; i < n; ++i) {
            if (!vis[i]) {
                build(g, i, vis, lbl, sccg);
            }
        }
        /* for (Map<Integer, Integer> adj : sccg) {
            prln(adj);
        } */
        prYN(dfs(sccg, lbl[s], artifact, lbl[e], false));
        close();
    }

    static boolean dfs(List<Map<Integer, Integer>> g, int i, boolean[] artifact, int e, boolean seen) {
        if (i == e) {
            return seen || artifact[i];
        }
        for (int j : g.get(i).keySet()) {
            if (dfs(g, j, artifact, e, seen || artifact[i] || g.get(i).get(j) == 1)) {
                return true;
            }
        }
        return false;
    }

    static void build(List<Map<Integer, Integer>> g, int i, boolean[] vis, int lbl[], List<Map<Integer, Integer>> cg) {
        vis[i] = true;
        for (int j : g.get(i).keySet()) {
            if (!vis[j]) {
                if (lbl[i] != lbl[j]) {
                    cg.get(lbl[i]).put(lbl[j], max(cg.get(lbl[i]).getOrDefault(lbl[j], 0), g.get(i).get(j)));
                }
                build(g, j, vis, lbl, cg);
            }
        }
    }

    static boolean scc(List<Map<Integer, Integer>> g, int i, boolean[] vis, List<Integer> comp) {
        boolean ans = false;
        vis[i] = true;
        for (int j : g.get(i).keySet()) {
            if (!vis[j]) {
                ans |= g.get(i).get(j) == 1;
                ans |= scc(g, j, vis, comp);
            }
        }
        comp.add(i);
        return ans;
    }

    static void del_reverse_edge(List<Map<Integer, Integer>> g, int i, boolean[] vis, List<Integer> order, List<Map<Integer, Integer>> ng, List<Set<Integer>> evis) {
        vis[i] = true;
        for (int j : g.get(i).keySet()) {
            if (!evis.get(j).contains(i)) {
                ng.get(i).put(j, g.get(i).get(j));
            }
            if (!vis[j]) {
                evis.get(i).add(j);
                del_reverse_edge(g, j, vis, order, ng, evis);
            }
        }
        order.add(i);
    }

    static BufferedReader __in = new BufferedReader(new InputStreamReader(System.in));
    static PrintWriter __out = new PrintWriter(new OutputStreamWriter(System.out));
    static StringTokenizer input;
    static Random __rand = new Random();

    // references
    // IBIG = 1e9 + 7
    // IMAX ~= 2e9
    // LMAX ~= 9e18

    // constants
    static final int IBIG = 1000000007;
    static final int IMAX = 2147483647;
    static final int IMIN = -2147483648;
    static final long LMAX = 9223372036854775807L;
    static final long LMIN = -9223372036854775808L;
    // math util
    static int minof(int a, int b, int c) {return min(a, min(b, c));}
    static int minof(int... x) {if (x.length == 1) return x[0]; if (x.length == 2) return min(x[0], x[1]); if (x.length == 3) return min(x[0], min(x[1], x[2])); int min = x[0]; for (int i = 1; i < x.length; ++i) if (x[i] < min) min = x[i]; return min;}
    static long minof(long a, long b, long c) {return min(a, min(b, c));}
    static long minof(long... x) {if (x.length == 1) return x[0]; if (x.length == 2) return min(x[0], x[1]); if (x.length == 3) return min(x[0], min(x[1], x[2])); long min = x[0]; for (int i = 1; i < x.length; ++i) if (x[i] < min) min = x[i]; return min;}
    static int maxof(int a, int b, int c) {return max(a, max(b, c));}
    static int maxof(int... x) {if (x.length == 1) return x[0]; if (x.length == 2) return max(x[0], x[1]); if (x.length == 3) return max(x[0], max(x[1], x[2])); int max = x[0]; for (int i = 1; i < x.length; ++i) if (x[i] > max) max = x[i]; return max;}
    static long maxof(long a, long b, long c) {return max(a, max(b, c));}
    static long maxof(long... x) {if (x.length == 1) return x[0]; if (x.length == 2) return max(x[0], x[1]); if (x.length == 3) return max(x[0], max(x[1], x[2])); long max = x[0]; for (int i = 1; i < x.length; ++i) if (x[i] > max) max = x[i]; return max;}
    static int powi(int a, int b) {if (a == 0) return 0; int ans = 1; while (b > 0) {if ((b & 1) > 0) ans *= a; a *= a; b >>= 1;} return ans;}
    static long powl(long a, int b) {if (a == 0) return 0; long ans = 1; while (b > 0) {if ((b & 1) > 0) ans *= a; a *= a; b >>= 1;} return ans;}
    static int fli(double d) {return (int) d;}
    static int cei(double d) {return (int) ceil(d);}
    static long fll(double d) {return (long) d;}
    static long cel(double d) {return (long) ceil(d);}
    static int gcf(int a, int b) {return b == 0 ? a : gcf(b, a % b);}
    static long gcf(long a, long b) {return b == 0 ? a : gcf(b, a % b);}
    static int lcm(int a, int b) {return a * b / gcf(a, b);}
    static long lcm(long a, long b) {return a * b / gcf(a, b);}
    static int randInt(int min, int max) {return __rand.nextInt(max - min + 1) + min;}
    static long mix(long x) {x += 0x9e3779b97f4a7c15L; x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9L; x = (x ^ (x >> 27)) * 0x94d049bb133111ebL; return x ^ (x >> 31);}
    // array util
    static void reverse(int[] a) {for (int i = 0, n = a.length, half = n / 2; i < half; ++i) {int swap = a[i]; a[i] = a[n - i - 1]; a[n - i - 1] = swap;}}
    static void reverse(long[] a) {for (int i = 0, n = a.length, half = n / 2; i < half; ++i) {long swap = a[i]; a[i] = a[n - i - 1]; a[n - i - 1] = swap;}}
    static void reverse(double[] a) {for (int i = 0, n = a.length, half = n / 2; i < half; ++i) {double swap = a[i]; a[i] = a[n - i - 1]; a[n - i - 1] = swap;}}
    static void reverse(char[] a) {for (int i = 0, n = a.length, half = n / 2; i < half; ++i) {char swap = a[i]; a[i] = a[n - i - 1]; a[n - i - 1] = swap;}}
    static void shuffle(int[] a) {int n = a.length - 1; for (int i = 0; i < n; ++i) {int ind = randInt(i, n); int swap = a[i]; a[i] = a[ind]; a[ind] = swap;}}
    static void shuffle(long[] a) {int n = a.length - 1; for (int i = 0; i < n; ++i) {int ind = randInt(i, n); long swap = a[i]; a[i] = a[ind]; a[ind] = swap;}}
    static void shuffle(double[] a) {int n = a.length - 1; for (int i = 0; i < n; ++i) {int ind = randInt(i, n); double swap = a[i]; a[i] = a[ind]; a[ind] = swap;}}
    static void rsort(int[] a) {shuffle(a); sort(a);}
    static void rsort(long[] a) {shuffle(a); sort(a);}
    static void rsort(double[] a) {shuffle(a); sort(a);}
    static int[] copy(int[] a) {int[] ans = new int[a.length]; for (int i = 0; i < a.length; ++i) ans[i] = a[i]; return ans;}
    static long[] copy(long[] a) {long[] ans = new long[a.length]; for (int i = 0; i < a.length; ++i) ans[i] = a[i]; return ans;}
    static double[] copy(double[] a) {double[] ans = new double[a.length]; for (int i = 0; i < a.length; ++i) ans[i] = a[i]; return ans;}
    static char[] copy(char[] a) {char[] ans = new char[a.length]; for (int i = 0; i < a.length; ++i) ans[i] = a[i]; return ans;}
    // input
    static void r() throws IOException {input = new StringTokenizer(rline());}
    static int ri() throws IOException {return Integer.parseInt(rline());}
    static long rl() throws IOException {return Long.parseLong(rline());}
    static double rd() throws IOException {return Double.parseDouble(rline());}
    static int[] ria(int n) throws IOException {int[] a = new int[n]; r(); for (int i = 0; i < n; ++i) a[i] = ni(); return a;}
    static int[] riam1(int n) throws IOException {int[] a = new int[n]; r(); for (int i = 0; i < n; ++i) a[i] = ni() - 1; return a;}
    static long[] rla(int n) throws IOException {long[] a = new long[n]; r(); for (int i = 0; i < n; ++i) a[i] = nl(); return a;}
    static double[] rda(int n) throws IOException {double[] a = new double[n]; r(); for (int i = 0; i < n; ++i) a[i] = nd(); return a;}
    static char[] rcha() throws IOException {return rline().toCharArray();}
    static String rline() throws IOException {return __in.readLine();}
    static String n() {return input.nextToken();}
    static int rni() throws IOException {r(); return ni();}
    static int ni() {return Integer.parseInt(n());}
    static long rnl() throws IOException {r(); return nl();}
    static long nl() {return Long.parseLong(n());}
    static double rnd() throws IOException {r(); return nd();}
    static double nd() {return Double.parseDouble(n());}
    // output
    static void pr(int i) {__out.print(i);}
    static void prln(int i) {__out.println(i);}
    static void pr(long l) {__out.print(l);}
    static void prln(long l) {__out.println(l);}
    static void pr(double d) {__out.print(d);}
    static void prln(double d) {__out.println(d);}
    static void pr(char c) {__out.print(c);}
    static void prln(char c) {__out.println(c);}
    static void pr(char[] s) {__out.print(new String(s));}
    static void prln(char[] s) {__out.println(new String(s));}
    static void pr(String s) {__out.print(s);}
    static void prln(String s) {__out.println(s);}
    static void pr(Object o) {__out.print(o);}
    static void prln(Object o) {__out.println(o);}
    static void prln() {__out.println();}
    static void pryes() {prln("yes");}
    static void pry() {prln("Yes");}
    static void prY() {prln("YES");}
    static void prno() {prln("no");}
    static void prn() {prln("No");}
    static void prN() {prln("NO");}
    static boolean pryesno(boolean b) {prln(b ? "yes" : "no"); return b;};
    static boolean pryn(boolean b) {prln(b ? "Yes" : "No"); return b;}
    static boolean prYN(boolean b) {prln(b ? "YES" : "NO"); return b;}
    static void prln(int... a) {for (int i = 0, len = a.length - 1; i < len; pr(a[i]), pr(' '), ++i); if (a.length > 0) prln(a[a.length - 1]); else prln();}
    static void prln(long... a) {for (int i = 0, len = a.length - 1; i < len; pr(a[i]), pr(' '), ++i); if (a.length > 0) prln(a[a.length - 1]); else prln();}
    static void prln(double... a) {for (int i = 0, len = a.length - 1; i < len; pr(a[i]), pr(' '), ++i); if (a.length > 0) prln(a[a.length - 1]); else prln();}
    static <T> void prln(Collection<T> c) {int n = c.size() - 1; Iterator<T> iter = c.iterator(); for (int i = 0; i < n; pr(iter.next()), pr(' '), ++i); if (n >= 0) prln(iter.next()); else prln();}
    static void h() {prln("hlfd"); flush();}
    static void flush() {__out.flush();}
    static void close() {__out.close();}
}


import java.io.*;
import java.util.*;

import static java.lang.Math.*;
import static java.util.Arrays.*;

public class cf302218c {

    public static void main(String[] args) throws IOException {
        int n = rni(), m = ni();
        List<Map<Integer, Integer>> g = new ArrayList<>(), ng = new ArrayList<>();
        for (int i = 0; i < n; ++i) {
            g.add(new HashMap<>());
            ng.add(new HashMap<>());
        }
        for (int i = 0; i < m; ++i) {
            int u = rni() - 1, v = ni() - 1, w = ni();
            g.get(u).put(v, w);
            g.get(v).put(u, w);
        }
        int s = rni() - 1, e = ni() - 1;
        boolean[] vis = new boolean[n];
        List<Integer> order = new ArrayList<>();
        List<Set<Integer>> evis = new ArrayList<>();
        for (int i = 0; i < n; ++i) {
            evis.add(new HashSet<>());
        }
        del_reverse_edge(g, s, vis, order, ng, evis);
        g = ng;
        /* for (Map<Integer, Integer> adj : g) {
            prln(adj.keySet().toString());
        } */
        Collections.reverse(order);
        List<Map<Integer, Integer>> t = new ArrayList<>();
        for (int i = 0; i < n; ++i) {
            t.add(new HashMap<>());
        }
        for (int i = 0; i < n; ++i) {
            for (int j : g.get(i).keySet()) {
                t.get(j).put(i, g.get(i).get(j));
            }
        }
        fill(vis, false);
        List<List<Integer>> comps = new ArrayList<>();
        int lbl[] = new int[n], cur = 0;
        boolean artifact[] = new boolean[n];
        for (int i : order) {
            if (!vis[i]) {
                List<Integer> comp = new ArrayList<>();
                if (scc(t, i, vis, comp)) {
                    artifact[cur] = true;
                }
                comps.add(comp);
                for (int j : comp) {
                    lbl[j] = cur;
                }
                ++cur;
            }
        }
        List<Map<Integer, Integer>> sccg = new ArrayList<>();
        for (int i = 0; i < cur; ++i) {
            sccg.add(new HashMap<>());
        }
        fill(vis, false);
        for (int i = 0; i < n; ++i) {
            if (!vis[i]) {
                build(g, i, vis, lbl, sccg);
            }
        }
        /* for (Map<Integer, Integer> adj : sccg) {
            prln(adj);
        } */
        prYN(dfs(sccg, lbl[s], artifact, lbl[e], false));
        close();
    }

    static boolean dfs(List<Map<Integer, Integer>> g, int i, boolean[] artifact, int e, boolean seen) {
        if (i == e) {
            return seen || artifact[i];
        }
        for (int j : g.get(i).keySet()) {
            if (dfs(g, j, artifact, e, seen || artifact[i] || g.get(i).get(j) == 1)) {
                return true;
            }
        }
        return false;
    }

    static void build(List<Map<Integer, Integer>> g, int i, boolean[] vis, int lbl[], List<Map<Integer, Integer>> cg) {
        vis[i] = true;
        for (int j : g.get(i).keySet()) {
            if (lbl[i] != lbl[j]) {
                cg.get(lbl[i]).put(lbl[j], max(cg.get(lbl[i]).getOrDefault(lbl[j], 0), g.get(i).get(j)));
            }
            if (!vis[j]) {
                build(g, j, vis, lbl, cg);
            }
        }
    }

    static boolean scc(List<Map<Integer, Integer>> g, int i, boolean[] vis, List<Integer> comp) {
        boolean ans = false;
        vis[i] = true;
        for (int j : g.get(i).keySet()) {
            if (!vis[j]) {
                ans |= g.get(i).get(j) == 1;
                ans |= scc(g, j, vis, comp);
            }
        }
        comp.add(i);
        return ans;
    }

    static void del_reverse_edge(List<Map<Integer, Integer>> g, int i, boolean[] vis, List<Integer> order, List<Map<Integer, Integer>> ng, List<Set<Integer>> evis) {
        vis[i] = true;
        for (int j : g.get(i).keySet()) {
            if (!evis.get(j).contains(i)) {
                ng.get(i).put(j, g.get(i).get(j));
            }
            if (!vis[j]) {
                evis.get(i).add(j);
                del_reverse_edge(g, j, vis, order, ng, evis);
            }
        }
        order.add(i);
    }

    static BufferedReader __in = new BufferedReader(new InputStreamReader(System.in));
    static PrintWriter __out = new PrintWriter(new OutputStreamWriter(System.out));
    static StringTokenizer input;
    static Random __rand = new Random();

    // references
    // IBIG = 1e9 + 7
    // IMAX ~= 2e9
    // LMAX ~= 9e18

    // constants
    static final int IBIG = 1000000007;
    static final int IMAX = 2147483647;
    static final int IMIN = -2147483648;
    static final long LMAX = 9223372036854775807L;
    static final long LMIN = -9223372036854775808L;
    // math util
    static int minof(int a, int b, int c) {return min(a, min(b, c));}
    static int minof(int... x) {if (x.length == 1) return x[0]; if (x.length == 2) return min(x[0], x[1]); if (x.length == 3) return min(x[0], min(x[1], x[2])); int min = x[0]; for (int i = 1; i < x.length; ++i) if (x[i] < min) min = x[i]; return min;}
    static long minof(long a, long b, long c) {return min(a, min(b, c));}
    static long minof(long... x) {if (x.length == 1) return x[0]; if (x.length == 2) return min(x[0], x[1]); if (x.length == 3) return min(x[0], min(x[1], x[2])); long min = x[0]; for (int i = 1; i < x.length; ++i) if (x[i] < min) min = x[i]; return min;}
    static int maxof(int a, int b, int c) {return max(a, max(b, c));}
    static int maxof(int... x) {if (x.length == 1) return x[0]; if (x.length == 2) return max(x[0], x[1]); if (x.length == 3) return max(x[0], max(x[1], x[2])); int max = x[0]; for (int i = 1; i < x.length; ++i) if (x[i] > max) max = x[i]; return max;}
    static long maxof(long a, long b, long c) {return max(a, max(b, c));}
    static long maxof(long... x) {if (x.length == 1) return x[0]; if (x.length == 2) return max(x[0], x[1]); if (x.length == 3) return max(x[0], max(x[1], x[2])); long max = x[0]; for (int i = 1; i < x.length; ++i) if (x[i] > max) max = x[i]; return max;}
    static int powi(int a, int b) {if (a == 0) return 0; int ans = 1; while (b > 0) {if ((b & 1) > 0) ans *= a; a *= a; b >>= 1;} return ans;}
    static long powl(long a, int b) {if (a == 0) return 0; long ans = 1; while (b > 0) {if ((b & 1) > 0) ans *= a; a *= a; b >>= 1;} return ans;}
    static int fli(double d) {return (int) d;}
    static int cei(double d) {return (int) ceil(d);}
    static long fll(double d) {return (long) d;}
    static long cel(double d) {return (long) ceil(d);}
    static int gcf(int a, int b) {return b == 0 ? a : gcf(b, a % b);}
    static long gcf(long a, long b) {return b == 0 ? a : gcf(b, a % b);}
    static int lcm(int a, int b) {return a * b / gcf(a, b);}
    static long lcm(long a, long b) {return a * b / gcf(a, b);}
    static int randInt(int min, int max) {return __rand.nextInt(max - min + 1) + min;}
    static long mix(long x) {x += 0x9e3779b97f4a7c15L; x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9L; x = (x ^ (x >> 27)) * 0x94d049bb133111ebL; return x ^ (x >> 31);}
    // array util
    static void reverse(int[] a) {for (int i = 0, n = a.length, half = n / 2; i < half; ++i) {int swap = a[i]; a[i] = a[n - i - 1]; a[n - i - 1] = swap;}}
    static void reverse(long[] a) {for (int i = 0, n = a.length, half = n / 2; i < half; ++i) {long swap = a[i]; a[i] = a[n - i - 1]; a[n - i - 1] = swap;}}
    static void reverse(double[] a) {for (int i = 0, n = a.length, half = n / 2; i < half; ++i) {double swap = a[i]; a[i] = a[n - i - 1]; a[n - i - 1] = swap;}}
    static void reverse(char[] a) {for (int i = 0, n = a.length, half = n / 2; i < half; ++i) {char swap = a[i]; a[i] = a[n - i - 1]; a[n - i - 1] = swap;}}
    static void shuffle(int[] a) {int n = a.length - 1; for (int i = 0; i < n; ++i) {int ind = randInt(i, n); int swap = a[i]; a[i] = a[ind]; a[ind] = swap;}}
    static void shuffle(long[] a) {int n = a.length - 1; for (int i = 0; i < n; ++i) {int ind = randInt(i, n); long swap = a[i]; a[i] = a[ind]; a[ind] = swap;}}
    static void shuffle(double[] a) {int n = a.length - 1; for (int i = 0; i < n; ++i) {int ind = randInt(i, n); double swap = a[i]; a[i] = a[ind]; a[ind] = swap;}}
    static void rsort(int[] a) {shuffle(a); sort(a);}
    static void rsort(long[] a) {shuffle(a); sort(a);}
    static void rsort(double[] a) {shuffle(a); sort(a);}
    static int[] copy(int[] a) {int[] ans = new int[a.length]; for (int i = 0; i < a.length; ++i) ans[i] = a[i]; return ans;}
    static long[] copy(long[] a) {long[] ans = new long[a.length]; for (int i = 0; i < a.length; ++i) ans[i] = a[i]; return ans;}
    static double[] copy(double[] a) {double[] ans = new double[a.length]; for (int i = 0; i < a.length; ++i) ans[i] = a[i]; return ans;}
    static char[] copy(char[] a) {char[] ans = new char[a.length]; for (int i = 0; i < a.length; ++i) ans[i] = a[i]; return ans;}
    // input
    static void r() throws IOException {input = new StringTokenizer(rline());}
    static int ri() throws IOException {return Integer.parseInt(rline());}
    static long rl() throws IOException {return Long.parseLong(rline());}
    static double rd() throws IOException {return Double.parseDouble(rline());}
    static int[] ria(int n) throws IOException {int[] a = new int[n]; r(); for (int i = 0; i < n; ++i) a[i] = ni(); return a;}
    static int[] riam1(int n) throws IOException {int[] a = new int[n]; r(); for (int i = 0; i < n; ++i) a[i] = ni() - 1; return a;}
    static long[] rla(int n) throws IOException {long[] a = new long[n]; r(); for (int i = 0; i < n; ++i) a[i] = nl(); return a;}
    static double[] rda(int n) throws IOException {double[] a = new double[n]; r(); for (int i = 0; i < n; ++i) a[i] = nd(); return a;}
    static char[] rcha() throws IOException {return rline().toCharArray();}
    static String rline() throws IOException {return __in.readLine();}
    static String n() {return input.nextToken();}
    static int rni() throws IOException {r(); return ni();}
    static int ni() {return Integer.parseInt(n());}
    static long rnl() throws IOException {r(); return nl();}
    static long nl() {return Long.parseLong(n());}
    static double rnd() throws IOException {r(); return nd();}
    static double nd() {return Double.parseDouble(n());}
    // output
    static void pr(int i) {__out.print(i);}
    static void prln(int i) {__out.println(i);}
    static void pr(long l) {__out.print(l);}
    static void prln(long l) {__out.println(l);}
    static void pr(double d) {__out.print(d);}
    static void prln(double d) {__out.println(d);}
    static void pr(char c) {__out.print(c);}
    static void prln(char c) {__out.println(c);}
    static void pr(char[] s) {__out.print(new String(s));}
    static void prln(char[] s) {__out.println(new String(s));}
    static void pr(String s) {__out.print(s);}
    static void prln(String s) {__out.println(s);}
    static void pr(Object o) {__out.print(o);}
    static void prln(Object o) {__out.println(o);}
    static void prln() {__out.println();}
    static void pryes() {prln("yes");}
    static void pry() {prln("Yes");}
    static void prY() {prln("YES");}
    static void prno() {prln("no");}
    static void prn() {prln("No");}
    static void prN() {prln("NO");}
    static boolean pryesno(boolean b) {prln(b ? "yes" : "no"); return b;};
    static boolean pryn(boolean b) {prln(b ? "Yes" : "No"); return b;}
    static boolean prYN(boolean b) {prln(b ? "YES" : "NO"); return b;}
    static void prln(int... a) {for (int i = 0, len = a.length - 1; i < len; pr(a[i]), pr(' '), ++i); if (a.length > 0) prln(a[a.length - 1]); else prln();}
    static void prln(long... a) {for (int i = 0, len = a.length - 1; i < len; pr(a[i]), pr(' '), ++i); if (a.length > 0) prln(a[a.length - 1]); else prln();}
    static void prln(double... a) {for (int i = 0, len = a.length - 1; i < len; pr(a[i]), pr(' '), ++i); if (a.length > 0) prln(a[a.length - 1]); else prln();}
    static <T> void prln(Collection<T> c) {int n = c.size() - 1; Iterator<T> iter = c.iterator(); for (int i = 0; i < n; pr(iter.next()), pr(' '), ++i); if (n >= 0) prln(iter.next()); else prln();}
    static void h() {prln("hlfd"); flush();}
    static void flush() {__out.flush();}
    static void close() {__out.close();}
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace __gnu_pbds;
using namespace std;

template <class T>
using ordered_set =
       tree <T,null_type,less <T>,rb_tree_tag,tree_order_statistics_node_update> ;
///find_by_order()
///order_of_key()

template <class T,class U>
void maximize(T &x,U y){
    if(x < y)x=y;
}
template <class T,class U>
void minimize(T &x,U y){
    if(x > y)x=y;
}
template <class T>
T Abs(T x){
    return (x < (T)0 ? -x : x);
}
template <class T>
T safe_sqrt(T x){
    return sqrt(max(x,(T)0));
}
template <class T,class U,class V>
T addmod(T x,U k,V MOD){
    return ((x+k)%MOD + MOD)%MOD;
}
template <class T,class U,class V>
T submod(T x,U k,V MOD){
    return ((x-k)%MOD + MOD)%MOD;
}
template <class T,class U,class V>
T mul(T x,U y,V MOD){
    return ( (x % MOD) * (y % MOD) ) % MOD;
}

#define ll long long
#define pll pair <ll,ll>
#define pii pair <int,int>
#define fir first
#define sec second
#define mp make_pair
#define pb push_back
#define emp emplace_back
#define MASK(i) ((1LL)<<(i))
#define BIT(x,i) (((x)>>(i))&1LL)
#define all(c) (c).begin(),(c).end()
#define sz(c) (int)((c).size())
#define fn "test"    ///FILE_NAME_HERE

/*------------------------------------------END_OF_TEMPLATE------------------------------------------*/

namespace task{

	const int N = 3e5 + 5;
	vector <pii> adj[N];
	vector <pii> gr[N];
	vector <pii> bct[N];
	int has[N];
	bool ok[N];
	int vis[2][N];
	int low[N];
	int num[N];
	int scc_idx[N];
	int n,m,src,des,TIME = 0,num_scc = 0;
	bool flag = false;

	void dfs(int u){
		vis[0][u] = true;
		for(int i = 0;i < sz(adj[u]);++i){
			int v = adj[u][i].fir;
			int e_idx = adj[u][i].sec;
			if(!vis[1][e_idx]){
				vis[1][e_idx] = true;
				gr[u].pb({v,e_idx});
			}
			if(!vis[0][v]){
				dfs(v);
			}
		}
	}

	stack <pii> stk;
	void tarjan(int u,int par,int E){
		vis[0][u] = 1;
		low[u] = num[u] = ++TIME;
		stk.push({u,E});
		for(int i = 0;i < sz(gr[u]);++i){
            int v = gr[u][i].fir;
			int e_idx = gr[u][i].sec;
			if(v == par)continue;
			if(!vis[0][v]){
				tarjan(v,u,e_idx);
				minimize(low[u],low[v]);
			} else if(vis[0][v] == 1){
				minimize(low[u],num[v]);
			}
		}
		if(low[u] == num[u]){
			++num_scc;
			while(true){
				pii t = stk.top();
				stk.pop();
				vis[0][t.fir] = 2;
				if(t.fir != u){
                    ok[num_scc] |= has[t.sec];
                }
				scc_idx[t.fir] = num_scc;
				if(t.fir == u){
					break;
				}
			}
		}
	}

	void make_tree(int u){
		vis[0][u] = true;
		for(int i = 0;i < sz(gr[u]);++i){
			int v = gr[u][i].fir;
			int e_idx = gr[u][i].sec;
			if(vis[0][v])continue;
			if(scc_idx[u] ^ scc_idx[v]){
				bct[scc_idx[u]].pb({scc_idx[v],has[e_idx]});
				bct[scc_idx[v]].pb({scc_idx[u],has[e_idx]});
			}
			make_tree(v);
		}
	}

	void can(int u,int par,bool f){
		if(u == scc_idx[des]){
			flag |= (f | ok[u]);
		}
		for(int i = 0;i < sz(bct[u]);++i){
			int v = bct[u][i].fir;
			int hs = bct[u][i].sec;
			if(v == par)continue;
			can(v,u,f | ok[u] | hs);
		}
	}

    void solve(){
    	cin>>n>>m;
    	for(int i = 1;i <= m;++i){
    		int x,y,z;
    		cin>>x>>y>>z;
    		has[i] = z;
    		adj[x].pb({y,i});
    		adj[y].pb({x,i});
    	}
    	cin>>src>>des;
    	dfs(1);
    	fill(vis[0] + 1,vis[0] + 1 + n,0);
    	for(int u = 1;u <= n;++u){
    		if(vis[0][u])continue;
    		tarjan(u,u,0);
    	}
    	fill(vis[0] + 1,vis[0] + 1 + n,0);
    	for(int u = 1;u <= n;++u){
    		if(vis[0][u])continue;
    		make_tree(u);
    	}
    	can(scc_idx[src],scc_idx[src],ok[scc_idx[src]]);
    	cout<<(flag ? "YES" : "NO");
    }
}

int main(void){
    ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    #ifndef ONLINE_JUDGE
    freopen(fn".inp","r",stdin);
    freopen(fn".out","w",stdout);
    #endif // ONLINE_JUDGE
    task::solve();
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace __gnu_pbds;
using namespace std;

template <class T>
using ordered_set =
       tree <T,null_type,less <T>,rb_tree_tag,tree_order_statistics_node_update> ;
///find_by_order()
///order_of_key()

template <class T,class U>
void maximize(T &x,U y){
    if(x < y)x=y;
}
template <class T,class U>
void minimize(T &x,U y){
    if(x > y)x=y;
}
template <class T>
T Abs(T x){
    return (x < (T)0 ? -x : x);
}
template <class T>
T safe_sqrt(T x){
    return sqrt(max(x,(T)0));
}
template <class T,class U,class V>
T addmod(T x,U k,V MOD){
    return ((x+k)%MOD + MOD)%MOD;
}
template <class T,class U,class V>
T submod(T x,U k,V MOD){
    return ((x-k)%MOD + MOD)%MOD;
}
template <class T,class U,class V>
T mul(T x,U y,V MOD){
    return ( (x % MOD) * (y % MOD) ) % MOD;
}

#define ll long long
#define pll pair <ll,ll>
#define pii pair <int,int>
#define fir first
#define sec second
#define mp make_pair
#define pb push_back
#define emp emplace_back
#define MASK(i) ((1LL)<<(i))
#define BIT(x,i) (((x)>>(i))&1LL)
#define all(c) (c).begin(),(c).end()
#define sz(c) (int)((c).size())
#define fn "test"    ///FILE_NAME_HERE

/*------------------------------------------END_OF_TEMPLATE------------------------------------------*/

namespace task{

	const int N = 3e5 + 5;
	vector <pii> adj[N];
	vector <pii> gr[N];
	vector <pii> bct[N];
	int has[N];
	bool ok[N];
	int vis[2][N];
	int low[N];
	int num[N];
	int scc_idx[N];
	int n,m,src,des,TIME = 0,num_scc = 0;
	bool flag = false;

	void dfs(int u){
		vis[0][u] = true;
		for(int i = 0;i < sz(adj[u]);++i){
			int v = adj[u][i].fir;
			int e_idx = adj[u][i].sec;
			if(!vis[1][e_idx]){
				vis[1][e_idx] = true;
				gr[u].pb({v,e_idx});
			}
			if(!vis[0][v]){
				dfs(v);
			}
		}
	}

	stack <pii> stk;
	void tarjan(int u,int par,int E){
		vis[0][u] = 1;
		low[u] = num[u] = ++TIME;
		stk.push({u,E});
		for(int i = 0;i < sz(gr[u]);++i){
            int v = gr[u][i].fir;
			int e_idx = gr[u][i].sec;
			if(v == par)continue;
			if(!vis[0][v]){
				tarjan(v,u,e_idx);
				minimize(low[u],low[v]);
			} else if(vis[0][v] == 1){
				minimize(low[u],num[v]);
			}
		}
		if(low[u] == num[u]){
			++num_scc;
			while(true){
				pii t = stk.top();
				stk.pop();
				vis[0][t.fir] = 2;
				ok[num_scc] |= has[t.sec];
				scc_idx[t.fir] = num_scc;
				if(t.fir == u){
					break;
				}
			}
		}
	}

	void make_tree(int u){
		vis[0][u] = true;
		for(int i = 0;i < sz(gr[u]);++i){
			int v = gr[u][i].fir;
			int e_idx = gr[u][i].sec;
			if(vis[0][v])continue;
			if(scc_idx[u] ^ scc_idx[v]){
				bct[scc_idx[u]].pb({scc_idx[v],has[e_idx]});
				bct[scc_idx[v]].pb({scc_idx[u],has[e_idx]});
			}
			make_tree(v);
		}
	}

	void can(int u,int par,bool f){
		if(u == scc_idx[des]){
			flag |= (f | ok[u]);
		}
		for(int i = 0;i < sz(bct[u]);++i){
			int v = bct[u][i].fir;
			int hs = bct[u][i].sec;
			if(v == par)continue;
			can(v,u,f | ok[u] | hs);
		}
	}

    void solve(){
    	cin>>n>>m;
    	for(int i = 1;i <= m;++i){
    		int x,y,z;
    		cin>>x>>y>>z;
    		has[i] = z;
    		adj[x].pb({y,i});
    		adj[y].pb({x,i});
    	}
    	cin>>src>>des;
    	dfs(src);
    	fill(vis[0] + 1,vis[0] + 1 + n,0);
    	for(int u = 1;u <= n;++u){
    		if(vis[0][u])continue;
    		tarjan(u,u,0);
    	}
    	fill(vis[0] + 1,vis[0] + 1 + n,0);
    	for(int u = 1;u <= n;++u){
    		if(vis[0][u])continue;
    		make_tree(u);
    	}
    	can(scc_idx[src],scc_idx[src],ok[scc_idx[src]]);
    	cout<<(flag ? "YES" : "NO");
    }
}

int main(void){
    ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    #ifndef ONLINE_JUDGE
    freopen(fn".inp","r",stdin);
    freopen(fn".out","w",stdout);
    #endif // ONLINE_JUDGE
    task::solve();
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace __gnu_pbds;
using namespace std;

template <class T>
using ordered_set =
       tree <T,null_type,less <T>,rb_tree_tag,tree_order_statistics_node_update> ;
///find_by_order()
///order_of_key()

template <class T,class U>
void maximize(T &x,U y){
    if(x < y)x=y;
}
template <class T,class U>
void minimize(T &x,U y){
    if(x > y)x=y;
}
template <class T>
T Abs(T x){
    return (x < (T)0 ? -x : x);
}
template <class T>
T safe_sqrt(T x){
    return sqrt(max(x,(T)0));
}
template <class T,class U,class V>
T addmod(T x,U k,V MOD){
    return ((x+k)%MOD + MOD)%MOD;
}
template <class T,class U,class V>
T submod(T x,U k,V MOD){
    return ((x-k)%MOD + MOD)%MOD;
}
template <class T,class U,class V>
T mul(T x,U y,V MOD){
    return ( (x % MOD) * (y % MOD) ) % MOD;
}

#define ll long long
#define pll pair <ll,ll>
#define pii pair <int,int>
#define fir first
#define sec second
#define mp make_pair
#define pb push_back
#define emp emplace_back
#define MASK(i) ((1LL)<<(i))
#define BIT(x,i) (((x)>>(i))&1LL)
#define all(c) (c).begin(),(c).end()
#define sz(c) (int)((c).size())
#define fn "test"    ///FILE_NAME_HERE

/*------------------------------------------END_OF_TEMPLATE------------------------------------------*/

namespace task{

	const int N = 3e5 + 5;
	vector <pii> adj[N];
	vector <pii> gr[N];
	vector <pii> bct[N];
	int has[N];
	bool ok[N];
	int vis[2][N];
	int low[N];
	int num[N];
	int scc_idx[N];
	int n,m,src,des,TIME = 0,num_scc = 0;
	bool flag = false;

	void dfs(int u){
		vis[0][u] = true;
		for(int i = 0;i < sz(adj[u]);++i){
			int v = adj[u][i].fir;
			int e_idx = adj[u][i].sec;
			if(!vis[1][e_idx]){
				vis[1][e_idx] = true;
				gr[u].pb({v,e_idx});
			}
			if(!vis[0][v]){
				dfs(v);
			}
		}
	}

	stack <pii> stk;
	void tarjan(int u,int par,int E){
		vis[0][u] = 1;
		low[u] = num[u] = ++TIME;
		stk.push({u,E});
		for(int i = 0;i < sz(gr[u]);++i){
            int v = gr[u][i].fir;
			int e_idx = gr[u][i].sec;
			if(v == par)continue;
			if(!vis[0][v]){
				tarjan(v,u,e_idx);
				minimize(low[u],low[v]);
			} else if(vis[0][v] == 1){
				minimize(low[u],num[v]);
			}
		}
		if(low[u] == num[u]){
			++num_scc;
			while(true){
				pii t = stk.top();
				stk.pop();
				vis[0][t.fir] = 2;
				ok[num_scc] |= has[t.sec];
				scc_idx[t.fir] = num_scc;
				if(t.fir == u){
					break;
				}
			}
		}
	}

	void make_tree(int u){
		vis[0][u] = true;
		for(int i = 0;i < sz(gr[u]);++i){
			int v = gr[u][i].fir;
			int e_idx = gr[u][i].sec;
			if(vis[0][v])continue;
			if(scc_idx[u] ^ scc_idx[v]){
				bct[scc_idx[u]].pb({scc_idx[v],has[e_idx]});
				bct[scc_idx[v]].pb({scc_idx[u],has[e_idx]});
			}
			make_tree(v);
		}
	}

	void can(int u,int par,bool f){
		if(u == scc_idx[des]){
			flag |= (f | ok[u]);
		}
		for(int i = 0;i < sz(bct[u]);++i){
			int v = bct[u][i].fir;
			int hs = bct[u][i].sec;
			if(v == par)continue;
			can(v,u,f | ok[u] | hs);
		}
	}

    void solve(){
    	cin>>n>>m;
    	for(int i = 1;i <= m;++i){
    		int x,y,z;
    		cin>>x>>y>>z;
    		has[i] = z;
    		adj[x].pb({y,i});
    		adj[y].pb({x,i});
    	}
    	cin>>src>>des;
    	dfs(1);
    	fill(vis[0] + 1,vis[0] + 1 + n,0);
    	for(int u = 1;u <= n;++u){
    		if(vis[0][u])continue;
    		tarjan(u,u,0);
    	}
    	fill(vis[0] + 1,vis[0] + 1 + n,0);
    	for(int u = 1;u <= n;++u){
    		if(vis[0][u])continue;
    		make_tree(u);
    	}
    	can(scc_idx[src],scc_idx[src],ok[scc_idx[src]]);
    	cout<<(flag ? "YES" : "NO");
    }
}

int main(void){
    ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    #ifndef ONLINE_JUDGE
    freopen(fn".inp","r",stdin);
    freopen(fn".out","w",stdout);
    #endif // ONLINE_JUDGE
    task::solve();
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace __gnu_pbds;
using namespace std;

template <class T>
using ordered_set =
       tree <T,null_type,less <T>,rb_tree_tag,tree_order_statistics_node_update> ;
///find_by_order()
///order_of_key()

template <class T,class U>
void maximize(T &x,U y){
    if(x < y)x=y;
}
template <class T,class U>
void minimize(T &x,U y){
    if(x > y)x=y;
}
template <class T>
T Abs(T x){
    return (x < (T)0 ? -x : x);
}
template <class T>
T safe_sqrt(T x){
    return sqrt(max(x,(T)0));
}
template <class T,class U,class V>
T addmod(T x,U k,V MOD){
    return ((x+k)%MOD + MOD)%MOD;
}
template <class T,class U,class V>
T submod(T x,U k,V MOD){
    return ((x-k)%MOD + MOD)%MOD;
}
template <class T,class U,class V>
T mul(T x,U y,V MOD){
    return ( (x % MOD) * (y % MOD) ) % MOD;
}

#define ll long long
#define pll pair <ll,ll>
#define pii pair <int,int>
#define fir first
#define sec second
#define mp make_pair
#define pb push_back
#define emp emplace_back
#define MASK(i) ((1LL)<<(i))
#define BIT(x,i) (((x)>>(i))&1LL)
#define all(c) (c).begin(),(c).end()
#define sz(c) (int)((c).size())
#define fn "test"    ///FILE_NAME_HERE

/*------------------------------------------END_OF_TEMPLATE------------------------------------------*/

namespace task{

	const int N = 3e5 + 5;
	vector <pii> adj[N];
	vector <pii> gr[N];
	vector <pii> bct[N];
	int has[N];
	bool ok[N];
	int vis[2][N];
	int low[N];
	int num[N];
	int scc_idx[N];
	int n,m,src,des,TIME = 0,num_scc = 0;
	bool flag = false;

	void dfs(int u){
		vis[0][u] = true;
		for(int i = 0;i < sz(adj[u]);++i){
			int v = adj[u][i].fir;
			int e_idx = adj[u][i].sec;
			if(!vis[1][e_idx]){
				vis[1][e_idx] = true;
				gr[u].pb({v,e_idx});
			}
			if(!vis[0][v]){
				dfs(v);
			}
		}
	}

	stack <int> stk;
	void tarjan(int u,int par){
		vis[0][u] = 1;
		low[u] = num[u] = ++TIME;
		stk.push(u);
		for(int i = 0;i < sz(gr[u]);++i){
            int v = gr[u][i].fir;
			int e_idx = gr[u][i].sec;
			if(v == par)continue;
			if(!vis[0][v]){
				tarjan(v,u);
				minimize(low[u],low[v]);
			} else if(vis[0][v] == 1){
				minimize(low[u],num[v]);
			}
		}
		if(low[u] == num[u]){
			++num_scc;
			while(true){
				int t = stk.top();
				stk.pop();
				vis[0][t] = 2;
				scc_idx[t] = num_scc;
				if(t == u){
					break;
				}
			}
		}
	}

	void make_tree(int u){
		vis[0][u] = true;
		for(int i = 0;i < sz(gr[u]);++i){
			int v = gr[u][i].fir;
			int e_idx = gr[u][i].sec;
			if(scc_idx[u] ^ scc_idx[v]){
				bct[scc_idx[u]].pb({scc_idx[v],has[e_idx]});
				bct[scc_idx[v]].pb({scc_idx[u],has[e_idx]});
			} else {
				ok[scc_idx[u]] |= has[e_idx];
			}
            if(vis[0][v])continue;
			make_tree(v);
		}
	}

	void can(int u,int par,bool f){
		if(u == scc_idx[des]){
			flag |= (f | ok[u]);
		}
		for(int i = 0;i < sz(bct[u]);++i){
			int v = bct[u][i].fir;
			int hs = bct[u][i].sec;
			if(v == par)continue;
			can(v,u,f | ok[u] | hs);
		}
	}

    void solve(){
    	cin>>n>>m;
    	for(int i = 1;i <= m;++i){
    		int x,y,z;
    		cin>>x>>y>>z;
    		has[i] = z;
    		adj[x].pb({y,i});
    		adj[y].pb({x,i});
    	}
    	cin>>src>>des;
    	dfs(1);
    	fill(vis[0] + 1,vis[0] + 1 + n,0);
    	for(int u = 1;u <= n;++u){
    		if(vis[0][u])continue;
    		tarjan(u,u);
    	}
    	fill(vis[0] + 1,vis[0] + 1 + n,0);
    	for(int u = 1;u <= n;++u){
    		if(vis[0][u])continue;
    		make_tree(u);
    	}
    	can(scc_idx[src],scc_idx[src],ok[scc_idx[src]]);
    	cout<<(flag ? "YES" : "NO");
    }
}

int main(void){
    ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    #ifndef ONLINE_JUDGE
    freopen(fn".inp","r",stdin);
    freopen(fn".out","w",stdout);
    #endif // ONLINE_JUDGE
    task::solve();
}


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

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

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

//.data
const int MAXV = 300000;

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

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

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

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

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

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

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

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

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