#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<string>
#include<algorithm>
#include<map>
#include<set>
#define MAXN 100010
#define MAXC 27
using namespace std;
typedef long long LL;
typedef pair<int,int> P;
struct edge{
    int to,next,cost,dir;
}E[MAXN*2];
LL ldist[MAXN],rdist[MAXN];
int head[MAXN],si,N,M,s,t,que[MAXN*2],used[MAXN],dfn[MAXN],low[MAXN],idx;
LL ans[MAXN];
void add_edge(int u,int v,int w,int d)
{
    E[si].to=v;
    E[si].cost=w;
    E[si].next=head[u];
    E[si].dir=d;
    head[u]=si++;
}
void init()
{
    memset(used,0,sizeof used);
    memset(ldist,0x3f,sizeof ldist);
    memset(rdist,0x3f,sizeof rdist);
    ldist[s]=0;
    int h=0,tail=0;
    que[tail++]=s;used[s]=true;
    while(h<tail){
        int v=que[h++];
        used[v]=false;
        for(int i=head[v];~i;i=E[i].next){
            int u=E[i].to;
            if(!E[i].dir)continue;
            if(ldist[u]>ldist[v]+E[i].cost){
                ldist[u]=ldist[v]+E[i].cost;
                if(!used[u]){
                    que[tail++]=u;
                    used[u]=true;
                }
            }
        }
    }
    memset(used,0,sizeof used);
    rdist[t]=0;
    h=0,tail=0;
    que[tail++]=t;used[t]=true;
    while(h<tail){
        int v=que[h++];
        used[v]=false;
        for(int i=head[v];~i;i=E[i].next){
            if(E[i].dir)continue;
            int u=E[i].to;
            if(rdist[u]>rdist[v]+E[i].cost){
                rdist[u]=rdist[v]+E[i].cost;
                if(!used[u]){
                    que[tail++]=u;
                    used[u]=true;
                }
            }
        }
    }
}
void tarjan(int v,int pre)
{
    low[v]=++idx;
    dfn[v]=idx;
    for(int i=head[v];~i;i=E[i].next){
        int u=E[i].to;
        if(!used[i/2]||(i^1)==pre)continue;
        if(!dfn[u]){
            tarjan(u,i);
            low[v]=min(low[v],low[u]);
        }
        else{
            low[v]=min(low[v],dfn[u]);
        }
    }
    if(low[v]==dfn[v]){
        if(~pre)ans[pre/2]=0;
    }
}
int main() {
    while(cin>>N>>M>>s>>t){
        memset(head,-1,sizeof head);si=idx=0;
        for(int i=0,u,v,w;i<M;i++){
            scanf("%d%d%d",&u,&v,&w);
            add_edge(u,v,w,1);
            add_edge(v,u,w,0);
        }
     //   printf("si:%d\n",si);
        init();
       // printf("mindist:%I64d\n",ldist[t]);
        memset(used,0,sizeof used);
        for(int i=0;i<si;i+=2){
            int v=E[i].to,u=E[i^1].to;
            if(ldist[u]+rdist[v]+E[i].cost==ldist[t]){
                used[i/2]=true;
            }
        }
        memset(ans,-1,sizeof ans);
        tarjan(s,-1);
        for(int i=0;i<si;i++){
            if(~ans[i/2]||!E[i].dir)continue;
            int v=E[i].to,u=E[i^1].to;
            LL len=ldist[u]+rdist[v];
            if(len+1>=ldist[t])continue;
            ans[i/2]=len+E[i].cost-ldist[t]+1;
        }
        for(int i=0;i<si;i+=2){
            if(ans[i/2]==0){
                puts("YES");
            }
            else if(~ans[i/2]){
                printf("CAN %I64d\n",ans[i/2]);
            }
            else puts("NO");
        }
    }
    return 0;
}


#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<string>
#include<algorithm>
#include<map>
#include<set>
#define MAXN 100010
#define MAXC 27
using namespace std;
typedef long long LL;
typedef pair<int,int> P;
struct edge{
    int to,next,cost;
}E[MAXN*2];
LL ldist[MAXN],rdist[MAXN];
int head[MAXN],si,N,M,s,t,que[MAXN*2],used[MAXN],dfn[MAXN],low[MAXN],idx;
LL ans[MAXN];
void add_edge(int u,int v,int w)
{
    E[si].to=v;
    E[si].cost=w;
    E[si].next=head[u];
    head[u]=si++;
}
void init()
{
    memset(used,0,sizeof used);
    memset(ldist,0x3f,sizeof ldist);
    memset(rdist,0x3f,sizeof rdist);
    ldist[s]=0;
    int h=0,tail=0;
    que[tail++]=s;used[s]=true;
    while(h<tail){
        int v=que[h++];
        used[v]=false;
        for(int i=head[v];~i;i=E[i].next){
            int u=E[i].to;
            if(ldist[u]>ldist[v]+E[i].cost){
                ldist[u]=ldist[v]+E[i].cost;
                if(!used[u]){
                    que[tail++]=u;
                    used[u]=true;
                }
            }
        }
    }
    memset(used,0,sizeof used);
    rdist[t]=0;
    h=0,tail=0;
    que[tail++]=t;used[t]=true;
    while(h<tail){
        int v=que[h++];
        used[v]=false;
        for(int i=head[v];~i;i=E[i].next){
            int u=E[i].to;
            if(rdist[u]>rdist[v]+E[i].cost){
                rdist[u]=rdist[v]+E[i].cost;
                if(!used[u]){
                    que[tail++]=u;
                    used[u]=true;
                }
            }
        }
    }
}
void dfs(int v)
{
   // used[v]=true;
   // printf("used[%d]=true\n",v);
    if(v==t)return;
    for(int i=head[v];~i;i=E[i].next){
        int u=E[i].to;
        if(!used[i/2]){
            if(ldist[v]+E[i].cost+rdist[u]==ldist[t]){
                used[i/2]=true;
                dfs(u);
            }
        }

    }
}
void tarjan(int v,int pre)
{
    low[v]=++idx;
    dfn[v]=idx;
    for(int i=head[v];~i;i=E[i].next){
        int u=E[i].to;
        if(!used[i/2]||(i^1)==pre)continue;
        if(!dfn[u]){
            tarjan(u,i);
            low[v]=min(low[v],low[u]);
        }
        else{
            low[v]=min(low[v],dfn[u]);
        }
        //if(~pre&&low[v]==dfn[v])ans[pre/2]=0;
    }
    //printf("%d:%d___%d\n",v,low[v],dfn[v]);
    if(low[v]==dfn[v]){
       // if(~pre)printf("%d->%d:%d_%d\n",E[pre].to,E[pre^1].to,pre,pre^1);
        if(~pre)ans[pre/2]=0;
    }
}
int main() {
    while(cin>>N>>M>>s>>t){
        memset(head,-1,sizeof head);si=idx=0;
        for(int i=0,u,v,w;i<M;i++){
            scanf("%d%d%d",&u,&v,&w);
            add_edge(u,v,w);
            add_edge(v,u,w);
        }
     //   printf("si:%d\n",si);
        init();
       // printf("mindist:%I64d\n",ldist[t]);
        memset(used,0,sizeof used);
        dfs(s);
        memset(ans,-1,sizeof ans);
        tarjan(s,-1);
        for(int i=0;i<si;i++){
            if(~ans[i/2])continue;
            int v=E[i].to,u=E[i^1].to;
            LL len=min(ldist[v]+rdist[u],ldist[u]+rdist[v]);
         //   printf("%d->%d:%I64d\n",u,v,len);
            if(len+1>=ldist[t])continue;
            ans[i/2]=len+E[i].cost-ldist[t]+1;
        }
        for(int i=0;i<si;i+=2){
            if(ans[i/2]==0){
                puts("YES");
            }
            else if(~ans[i/2]){
                printf("CAN %I64d\n",ans[i/2]);
            }
            else puts("NO");
        }
    }
    return 0;
}


#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<string>
#include<algorithm>
#include<map>
#include<set>
#define MAXN 100010
#define MAXC 27
using namespace std;
typedef long long LL;
typedef pair<int,int> P;
struct edge{
    int to,next,cost,dir;
}E[MAXN*2];
LL ldist[MAXN],rdist[MAXN];
int head[MAXN],si,N,M,s,t,que[MAXN*2],used[MAXN],dfn[MAXN],low[MAXN],idx;
LL ans[MAXN];
void add_edge(int u,int v,int w,int d)
{
    E[si].to=v;
    E[si].cost=w;
    E[si].next=head[u];
    E[si].dir=d;
    head[u]=si++;
}
void init()
{
    memset(used,0,sizeof used);
    memset(ldist,0x3f,sizeof ldist);
    memset(rdist,0x3f,sizeof rdist);
    ldist[s]=0;
    int h=0,tail=0;
    que[tail++]=s;used[s]=true;
    while(h<tail){
        int v=que[h++];
        used[v]=false;
        for(int i=head[v];~i;i=E[i].next){
            int u=E[i].to;
            if(!E[i].dir)continue;
            if(ldist[u]>ldist[v]+E[i].cost){
                ldist[u]=ldist[v]+E[i].cost;
                if(!used[u]){
                    que[tail++]=u;
                    used[u]=true;
                }
            }
        }
    }
    memset(used,0,sizeof used);
    rdist[t]=0;
    h=0,tail=0;
    que[tail++]=t;used[t]=true;
    while(h<tail){
        int v=que[h++];
        used[v]=false;
        for(int i=head[v];~i;i=E[i].next){
            if(E[i].dir)continue;
            int u=E[i].to;
            if(rdist[u]>rdist[v]+E[i].cost){
                rdist[u]=rdist[v]+E[i].cost;
                if(!used[u]){
                    que[tail++]=u;
                    used[u]=true;
                }
            }
        }
    }
}
void dfs(int v)
{
    if(v==t)return;
    for(int i=head[v];~i;i=E[i].next){
        int u=E[i].to;
        if(!used[i/2]){
            if(ldist[v]+E[i].cost+rdist[u]==ldist[t]){
                used[i/2]=true;
                dfs(u);
            }
        }

    }
}
void tarjan(int v,int pre)
{
    low[v]=++idx;
    dfn[v]=idx;
    for(int i=head[v];~i;i=E[i].next){
        int u=E[i].to;
        if(!used[i/2]||(i^1)==pre)continue;
        if(!dfn[u]){
            tarjan(u,i);
            low[v]=min(low[v],low[u]);
        }
        else{
            low[v]=min(low[v],dfn[u]);
        }
    }
    if(low[v]==dfn[v]){
        if(~pre)ans[pre/2]=0;
    }
}
int main() {
    while(cin>>N>>M>>s>>t){
        memset(head,-1,sizeof head);si=idx=0;
        for(int i=0,u,v,w;i<M;i++){
            scanf("%d%d%d",&u,&v,&w);
            add_edge(u,v,w,1);
            add_edge(v,u,w,0);
        }
     //   printf("si:%d\n",si);
        init();
       // printf("mindist:%I64d\n",ldist[t]);
        memset(used,0,sizeof used);
        dfs(s);
        memset(ans,-1,sizeof ans);
        tarjan(s,-1);
        for(int i=0;i<si;i++){
            if(~ans[i/2]||!E[i].dir)continue;
            int v=E[i].to,u=E[i^1].to;
            LL len=ldist[u]+rdist[v];
            if(len+1>=ldist[t])continue;
            ans[i/2]=len+E[i].cost-ldist[t]+1;
        }
        for(int i=0;i<si;i+=2){
            if(ans[i/2]==0){
                puts("YES");
            }
            else if(~ans[i/2]){
                printf("CAN %I64d\n",ans[i/2]);
            }
            else puts("NO");
        }
    }
    return 0;
}


#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<string>
#include<algorithm>
#include<map>
#include<set>
#define MAXN 100010
#define MAXC 27
using namespace std;
typedef long long LL;
typedef pair<int,int> P;
struct edge{
    int to,next,cost,dir;
}E[MAXN*2];
LL ldist[MAXN],rdist[MAXN];
int head[MAXN],si,N,M,s,t,que[MAXN*2],used[MAXN],dfn[MAXN],low[MAXN],idx;
LL ans[MAXN];
void add_edge(int u,int v,int w,int d)
{
    E[si].to=v;
    E[si].cost=w;
    E[si].next=head[u];
    E[si].dir=d;
    head[u]=si++;
}
void init()
{
    memset(used,0,sizeof used);
    memset(ldist,0x3f,sizeof ldist);
    memset(rdist,0x3f,sizeof rdist);
    ldist[s]=0;
    int h=0,tail=0;
    que[tail++]=s;used[s]=true;
    while(h<tail){
        int v=que[h++];
        used[v]=false;
        for(int i=head[v];~i;i=E[i].next){
            int u=E[i].to;
            if(!E[i].dir)continue;
            if(ldist[u]>ldist[v]+E[i].cost){
                ldist[u]=ldist[v]+E[i].cost;
                if(!used[u]){
                    que[tail++]=u;
                    used[u]=true;
                }
            }
        }
    }
    memset(used,0,sizeof used);
    rdist[t]=0;
    h=0,tail=0;
    que[tail++]=t;used[t]=true;
    while(h<tail){
        int v=que[h++];
        used[v]=false;
        for(int i=head[v];~i;i=E[i].next){
            if(E[i].dir)continue;
            int u=E[i].to;
            if(rdist[u]>rdist[v]+E[i].cost){
                rdist[u]=rdist[v]+E[i].cost;
                if(!used[u]){
                    que[tail++]=u;
                    used[u]=true;
                }
            }
        }
    }
}
void dfs(int v)
{
    if(v==t)return;
    for(int i=head[v];~i;i=E[i].next){
        int u=E[i].to;
        if(!used[i/2]){
            if(ldist[v]+E[i].cost+rdist[u]==ldist[t]){
                used[i/2]=true;
                dfs(u);
            }
        }

    }
}
void tarjan(int v,int pre)
{
    low[v]=++idx;
    dfn[v]=idx;
    for(int i=head[v];~i;i=E[i].next){
        int u=E[i].to;
        if(!used[i/2]||(i^1)==pre)continue;
        if(!dfn[u]){
            tarjan(u,i);
            low[v]=min(low[v],low[u]);
        }
        else{
            low[v]=min(low[v],dfn[u]);
        }
    }
    if(low[v]==dfn[v]){
        if(~pre)ans[pre/2]=0;
    }
}
int main() {
    while(cin>>N>>M>>s>>t){
        memset(head,-1,sizeof head);si=idx=0;
        for(int i=0,u,v,w;i<M;i++){
            scanf("%d%d%d",&u,&v,&w);
            add_edge(u,v,w,1);
            add_edge(v,u,w,0);
        }
     //   printf("si:%d\n",si);
        init();
       // printf("mindist:%I64d\n",ldist[t]);
        memset(used,0,sizeof used);
        dfs(s);
        memset(ans,-1,sizeof ans);
        tarjan(s,-1);
        for(int i=0;i<si;i++){
            if(~ans[i/2])continue;
            int v=E[i].to,u=E[i^1].to;
            LL len=min(ldist[v]+rdist[u],ldist[u]+rdist[v]);
         //   printf("%d->%d:%I64d\n",u,v,len);
            if(len+1>=ldist[t])continue;
            ans[i/2]=len+E[i].cost-ldist[t]+1;
        }
        for(int i=0;i<si;i+=2){
            if(ans[i/2]==0){
                puts("YES");
            }
            else if(~ans[i/2]){
                printf("CAN %I64d\n",ans[i/2]);
            }
            else puts("NO");
        }
    }
    return 0;
}


#include <cstdio>
#include <cctype>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#define rep(i, l, r) for(int i=l; i<=r; i++)
#define down(i, l, r) for(int i=l; i>=r; i--)
#define travel(x) for(edge *p=fir[x]; p; p=p->n)
#define Travel(x) for(edge *p=Fir[x]; p; p=p->n)
#define maxn 100009
#define maxm 100009
#define ll long long
#define inf 0x3fffffffffffff
using namespace std;
int read()
{
	int x=0, f=1; char ch=getchar();
	while (!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
	while (isdigit(ch)) x=x*10+ch-'0', ch=getchar();
	return x*f;
}
struct edge{int x,y,d; edge *n; bool b;} e[maxm], E[maxm], *fir[maxn], *Fir[maxn];
int n, m, s, t, v[maxn];
ll d[maxn], D[maxn]; bool b[maxn], c[maxn];
int q[maxn], l, r;
void spfa()
{
	rep(i, 1, n) d[i]=inf;
	d[s]=0; b[s]=1;
	l=0, r=0; q[r++]=s;
	while (l!=r)
	{
		int x=q[l++]; l%=n; b[x]=0;
		travel(x) if (d[p->y]>d[x]+p->d)
		{
			d[p->y]=d[x]+p->d;
			if (!b[p->y]) b[p->y]=1, q[r++]=p->y, r%=n;
		}
	}
}
void spfa2()
{
	rep(i, 1, n) D[i]=inf;
	D[t]=0; b[t]=1;
	l=0, r=0; q[r++]=t;
	while (l!=r)
	{
		int x=q[l++]; l%=n; b[x]=0;
		Travel(x) if (D[p->y]>D[x]+p->d)
		{
			D[p->y]=D[x]+p->d;
			if (!b[p->y]) b[p->y]=1, q[r++]=p->y, r%=n;
		}
	}
}
void dfs()
{
	l=0, r=0; q[r++]=s; b[s]=1;
	int now=1, tot=0;
	while (l!=r)
	{
		int x=q[l++]; l%=n; tot++;
		if (l==r && now==tot) c[x]=1;
		travel(x) if (p->b)
		{
			v[p->y]--;
			if (!b[p->y]) b[p->y]=1, now++;
			if (!v[p->y]) q[r++]=p->y, r%=n;
		}
	}
}
int main()
{
	n=read(); m=read(); s=read(), t=read();
	rep(i, 1, m) e[i].x=read(), e[i].y=read(), e[i].d=read(), e[i].n=fir[e[i].x], fir[e[i].x]=e+i;
	spfa();
	rep(i, 1, m) E[i].x=e[i].y, E[i].y=e[i].x, E[i].d=e[i].d, E[i].n=Fir[E[i].x], Fir[E[i].x]=E+i;
	spfa2();
	rep(i, 1, m) if (d[e[i].x]+e[i].d==d[e[i].y] && D[e[i].y]+e[i].d==D[e[i].x]) e[i].b=1, v[e[i].y]++;
	dfs();
	rep(i, 1, m)
	{
		if (e[i].b && c[e[i].x] && c[e[i].y]) puts("YES");
		else if (D[e[i].y]==inf || d[e[i].x]==inf || d[t]-1-(d[e[i].x]+D[e[i].y])<1) puts("NO");
		else printf("CAN %lld\n", e[i].d-(d[t]-1-(d[e[i].x]+D[e[i].y])));
	}
	return 0;
}


#include <cstdio>
#include <cctype>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#define rep(i, l, r) for(int i=l; i<=r; i++)
#define down(i, l, r) for(int i=l; i>=r; i--)
#define travel(x) for(edge *p=fir[x]; p; p=p->n)
#define Travel(x) for(edge *p=Fir[x]; p; p=p->n)
#define maxn 100009
#define maxm 100009
#define ll long long
#define inf 0x3fffffffffffff
using namespace std;
int read()
{
	int x=0, f=1; char ch=getchar();
	while (!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
	while (isdigit(ch)) x=x*10+ch-'0', ch=getchar();
	return x*f;
}
struct edge{int x,y,d; edge *n; bool b;} e[maxm], E[maxm], *fir[maxn], *Fir[maxn];
int n, m, s, t, v[maxn];
ll d[maxn], D[maxn]; bool b[maxn], c[maxn];
int q[maxn], l, r;
void spfa()
{
	rep(i, 1, n) d[i]=inf;
	d[s]=0; b[s]=1;
	l=0, r=0; q[r++]=s;
	while (l!=r)
	{
		int x=q[l++]; l%=n; b[x]=0;
		travel(x) if (d[p->y]>d[x]+p->d)
		{
			d[p->y]=d[x]+p->d;
			if (!b[p->y]) b[p->y]=1, q[r++]=p->y, r%=n;
		}
	}
}
void spfa2()
{
	rep(i, 1, n) D[i]=inf;
	D[t]=0; b[t]=1;
	l=0, r=0; q[r++]=t;
	while (l!=r)
	{
		int x=q[l++]; l%=n; b[x]=0;
		Travel(x) if (D[p->y]>D[x]+p->d)
		{
			D[p->y]=D[x]+p->d;
			if (!b[p->y]) b[p->y]=1, q[r++]=p->y, r%=n;
		}
	}
}
void dfs()
{
	l=0, r=0; q[r++]=s; b[s]=1;
	int now=1, tot=0, tmp=0;
	while (l!=r)
	{
		int x=q[l++]; l%=n; tot++;
		if (l==r && now==tot)
		{
			if (tmp) c[tmp]=1;
			tmp=x;
		}
		else tmp=0;
		travel(x) if (p->b)
		{
			v[p->y]--;
			if (!b[p->y]) b[p->y]=1, now++;
			if (!v[p->y]) q[r++]=p->y, r%=n;
		}
	}
}
int main()
{
	n=read(); m=read(); s=read(), t=read();
	rep(i, 1, m) e[i].x=read(), e[i].y=read(), e[i].d=read(), e[i].n=fir[e[i].x], fir[e[i].x]=e+i;
	spfa();
	rep(i, 1, m) E[i].x=e[i].y, E[i].y=e[i].x, E[i].d=e[i].d, E[i].n=Fir[E[i].x], Fir[E[i].x]=E+i;
	spfa2();
	rep(i, 1, m) if (d[e[i].x]+e[i].d==d[e[i].y] && D[e[i].y]+e[i].d==D[e[i].x]) e[i].b=1, v[e[i].y]++;
	dfs();
	rep(i, 1, m)
	{
		if (e[i].b && c[e[i].x]) puts("YES");
		else if (D[e[i].y]==inf || d[e[i].x]==inf || d[t]-1-(d[e[i].x]+D[e[i].y])<1) puts("NO");
		else printf("CAN %lld\n", e[i].d-(d[t]-1-(d[e[i].x]+D[e[i].y])));
	}
	return 0;
}


#include <cstdio>
#include <cctype>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#define rep(i, l, r) for(int i=l; i<=r; i++)
#define down(i, l, r) for(int i=l; i>=r; i--)
#define travel(x) for(edge *p=fir[x]; p; p=p->n)
#define Travel(x) for(edge *p=Fir[x]; p; p=p->n)
#define maxn 100009
#define maxm 100009
#define ll long long
#define inf 0x3fffffffffffff
using namespace std;
int read()
{
	int x=0, f=1; char ch=getchar();
	while (!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
	while (isdigit(ch)) x=x*10+ch-'0', ch=getchar();
	return x*f;
}
struct edge{int x,y,d; edge *n; bool b;} e[maxm], E[maxm], *fir[maxn], *Fir[maxn];
int n, m, s, t, v[maxn];
ll d[maxn], D[maxn]; bool b[maxn], c[maxn];
int q[maxn], l, r;
void spfa()
{
	rep(i, 1, n) d[i]=inf;
	d[s]=0; b[s]=1;
	l=0, r=0; q[r++]=s;
	while (l!=r)
	{
		int x=q[l++]; l%=n; b[x]=0;
		travel(x) if (d[p->y]>d[x]+p->d)
		{
			d[p->y]=d[x]+p->d;
			if (!b[p->y]) b[p->y]=1, q[r++]=p->y, r%=n;
		}
	}
}
void spfa2()
{
	rep(i, 1, n) D[i]=inf;
	D[t]=0; b[t]=1;
	l=0, r=0; q[r++]=t;
	while (l!=r)
	{
		int x=q[l++]; l%=n; b[x]=0;
		Travel(x) if (D[p->y]>D[x]+p->d)
		{
			D[p->y]=D[x]+p->d;
			if (!b[p->y]) b[p->y]=1, q[r++]=p->y, r%=n;
		}
	}
}
void dfs()
{
	l=0, r=0; q[r++]=s; b[s]=1;
	int now=1, tot=0;
	while (l!=r)
	{
		int x=q[l++]; l%=n; tot++;
		if (l==r && now==tot) c[x]=1;
		travel(x) if (p->b)
		{
			v[p->y]--;
			if (!b[p->y]) b[p->y]=1, now++;
			if (!v[p->y]) q[r++]=p->y, r%=n;
		}
	}
}
int main()
{
	n=read(); m=read(); s=read(), t=read();
	rep(i, 1, m) e[i].x=read(), e[i].y=read(), e[i].d=read(), e[i].n=fir[e[i].x], fir[e[i].x]=e+i;
	spfa();
	rep(i, 1, m) E[i].x=e[i].y, E[i].y=e[i].x, E[i].d=e[i].d, E[i].n=Fir[E[i].x], Fir[E[i].x]=E+i;
	spfa2();
	rep(i, 1, m) if (d[e[i].x]+e[i].d==d[e[i].y] && D[e[i].y]+e[i].d==D[e[i].x]) e[i].b=1, v[e[i].y]++;
	dfs();
	rep(i, 1, m)
	{
		if (e[i].b && c[e[i].x] && c[e[i].y]) puts("YES");
		else if (D[e[i].y]==inf || d[e[i].x]==inf || d[e[i].y]-d[e[i].x]==1) puts("NO");
		else printf("CAN %lld\n", e[i].d-(d[e[i].y]-d[e[i].x]-1));
	}
	return 0;
}


#include <cstdio>
#include <cctype>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <deque>
#define rep(i, l, r) for(int i=l; i<=r; i++)
#define down(i, l, r) for(int i=l; i>=r; i--)
#define travel(x) for(edge *p=fir[x]; p; p=p->n)
#define Travel(x) for(edge *p=Fir[x]; p; p=p->n)
#define maxn 100009
#define maxm 100009
#define ll long long
#define inf 0x3fffffffffffff
using namespace std;
int read()
{
	int x=0, f=1; char ch=getchar();
	while (!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
	while (isdigit(ch)) x=x*10+ch-'0', ch=getchar();
	return x*f;
}
struct edge{int x,y,d; edge *n; bool b;} e[maxm], E[maxm], *fir[maxn], *Fir[maxn];
int n, m, s, t, v[maxn], u[maxn];
ll d[maxn], D[maxn]; bool b[maxn], c[maxn];
int q[maxn], l, r;
void spfa()
{
	rep(i, 1, n) d[i]=inf;
	d[s]=0; b[s]=1;
	deque<int>q; q.push_back(s);
	while (!q.empty())
	{
		int x=q.front(); q.pop_front(); b[x]=0;
		travel(x) if (d[p->y]>d[x]+p->d)
		{
			d[p->y]=d[x]+p->d;
			if (!b[p->y])
				{b[p->y]=1; if (!q.empty() && d[p->y]<=d[q.front()]) q.push_front(p->y); else q.push_back(p->y);}
		}
	}
}
void spfa2()
{
	rep(i, 1, n) D[i]=inf;
	D[t]=0; b[t]=1;
	deque<int>q; q.push_back(t);
	while (!q.empty())
	{
		int x=q.front(); q.pop_front(); b[x]=0;
		Travel(x) if (D[p->y]>D[x]+p->d)
		{
			D[p->y]=D[x]+p->d;
			if (!b[p->y])
				{b[p->y]=1; if (!q.empty() && D[p->y]<=D[q.front()]) q.push_front(p->y); else q.push_back(p->y);}
		}
	}
}
void dfs()
{
	l=0, r=0; q[r++]=s; b[s]=1;
	int now=1, tot=0;
	while (l!=r)
	{
		int x=q[l++]; l%=n; tot++;
		if (l==r && now==tot) c[x]++;
		travel(x) if (p->b)
		{
			v[p->y]--;
			if (!b[p->y]) b[p->y]=1, now++;
			if (!v[p->y]) q[r++]=p->y, r%=n;
		}
	}
}
int main()
{
	n=read(); m=read(); s=read(), t=read();
	rep(i, 1, m) e[i].x=read(), e[i].y=read(), e[i].d=read(), e[i].n=fir[e[i].x], fir[e[i].x]=e+i;
	spfa();
	rep(i, 1, m) E[i].x=e[i].y, E[i].y=e[i].x, E[i].d=e[i].d, E[i].n=Fir[E[i].x], Fir[E[i].x]=E+i;
	spfa2();
	rep(i, 1, m) if (d[e[i].x]+e[i].d==d[e[i].y] && D[e[i].y]+e[i].d==D[e[i].x]) e[i].b=1, v[e[i].y]++, u[e[i].x]++;
	dfs();
	rep(i, 1, m)
	{
		if (e[i].b && c[e[i].x] && u[e[i].x]==1) puts("YES");
		else if (D[e[i].y]==inf || d[e[i].x]==inf || d[t]-1-(d[e[i].x]+D[e[i].y])<1) puts("NO");
		else printf("CAN %lld\n", e[i].d-(d[t]-1-(d[e[i].x]+D[e[i].y])));
	}
	return 0;
}


#include <cstdio>
#include <cctype>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#define rep(i, l, r) for(int i=l; i<=r; i++)
#define down(i, l, r) for(int i=l; i>=r; i--)
#define travel(x) for(edge *p=fir[x]; p; p=p->n)
#define Travel(x) for(edge *p=Fir[x]; p; p=p->n)
#define maxn 100009
#define maxm 100009
#define ll long long
#define inf 0x3fffffffffffff
using namespace std;
int read()
{
	int x=0, f=1; char ch=getchar();
	while (!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
	while (isdigit(ch)) x=x*10+ch-'0', ch=getchar();
	return x*f;
}
struct edge{int x,y,d; edge *n; bool b;} e[maxm], E[maxm], *fir[maxn], *Fir[maxn];
int n, m, s, t, v[maxn];
ll d[maxn], D[maxn]; bool b[maxn], c[maxn];
int q[maxn], l, r;
void spfa()
{
	rep(i, 1, n) d[i]=inf;
	d[s]=0; b[s]=1;
	l=0, r=0; q[r++]=s;
	while (l!=r)
	{
		int x=q[l++]; l%=n; b[x]=0;
		travel(x) if (d[p->y]>d[x]+p->d)
		{
			d[p->y]=d[x]+p->d;
			if (!b[p->y]) b[p->y]=1, q[r++]=p->y, r%=n;
		}
	}
}
void spfa2()
{
	rep(i, 1, n) D[i]=inf;
	D[t]=0; b[t]=1;
	l=0, r=0; q[r++]=t;
	while (l!=r)
	{
		int x=q[l++]; l%=n; b[x]=0;
		Travel(x) if (D[p->y]>D[x]+p->d)
		{
			D[p->y]=D[x]+p->d;
			if (!b[p->y]) b[p->y]=1, q[r++]=p->y, r%=n;
		}
	}
}
void dfs()
{
	l=0, r=0; q[r++]=s; b[s]=1;
	int now=1, tot=0;
	while (l!=r)
	{
		int x=q[l++]; l%=n; tot++;
		if (l==r && now==tot) c[x]=1;
		travel(x) if (p->b)
		{
			v[p->y]--;
			if (!b[p->y]) b[p->y]=1, now++;
			if (!v[p->y]) q[r++]=p->y, r%=n;
		}
	}
}
int main()
{
	n=read(); m=read(); s=read(), t=read();
	rep(i, 1, m) e[i].x=read(), e[i].y=read(), e[i].d=read(), e[i].n=fir[e[i].x], fir[e[i].x]=e+i;
	spfa();
	rep(i, 1, m) E[i].x=e[i].y, E[i].y=e[i].x, E[i].d=e[i].d, E[i].n=Fir[E[i].x], Fir[E[i].x]=E+i;
	spfa2();
	rep(i, 1, m) if (d[e[i].x]+e[i].d==d[e[i].y] && D[e[i].y]+e[i].d==D[e[i].x]) e[i].b=1, v[e[i].y]++;
	dfs();
	rep(i, 1, m)
	{
		if (e[i].b && c[e[i].x] && c[e[i].y]) puts("YES");
		else if (D[e[i].y]==inf || d[e[i].x]==inf || d[e[i].y]-d[e[i].x]==1) puts("NO");
		else printf("Can %lld\n", e[i].d-(d[e[i].y]-d[e[i].x]-1));
	}
	return 0;
}


#include <cstdio>
#include <cctype>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <deque>
#define rep(i, l, r) for(int i=l; i<=r; i++)
#define down(i, l, r) for(int i=l; i>=r; i--)
#define travel(x) for(edge *p=fir[x]; p; p=p->n)
#define Travel(x) for(edge *p=Fir[x]; p; p=p->n)
#define maxn 100009
#define maxm 100009
#define ll long long
#define inf 0x3fffffffffffff
using namespace std;
int read()
{
	int x=0, f=1; char ch=getchar();
	while (!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
	while (isdigit(ch)) x=x*10+ch-'0', ch=getchar();
	return x*f;
}
struct edge{int x,y,d; edge *n; bool b;} e[maxm], E[maxm], *fir[maxn], *Fir[maxn];
int n, m, s, t, v[maxn], u[maxn];
ll d[maxn], D[maxn]; bool b[maxn], c[maxn];
int q[maxn], l, r;
void spfa()
{
	rep(i, 1, n) d[i]=inf;
	d[s]=0; b[s]=1;
	deque<int>q; q.push_back(s);
	while (!q.empty())
	{
		int x=q.front(); q.pop_front(); b[x]=0;
		travel(x) if (d[p->y]>d[x]+p->d)
		{
			d[p->y]=d[x]+p->d;
			if (!b[p->y])
				{b[p->y]=1; if (!q.empty() && d[p->y]<=d[q.front()]) q.push_front(p->y); else q.push_back(p->y);}
		}
	}
}
void spfa2()
{
	rep(i, 1, n) D[i]=inf;
	D[s]=0; b[s]=1;
	deque<int>q; q.push_back(s);
	while (!q.empty())
	{
		int x=q.front(); q.pop_front(); b[x]=0;
		Travel(x) if (D[p->y]>D[x]+p->d)
		{
			D[p->y]=D[x]+p->d;
			if (!b[p->y])
				{b[p->y]=1; if (!q.empty() && D[p->y]<=D[q.front()]) q.push_front(p->y); else q.push_back(p->y);}
		}
	}
}
void dfs()
{
	l=0, r=0; q[r++]=s; b[s]=1;
	int now=1, tot=0;
	while (l!=r)
	{
		int x=q[l++]; l%=n; tot++;
		if (l==r && now==tot) c[x]++;
		travel(x) if (p->b)
		{
			v[p->y]--;
			if (!b[p->y]) b[p->y]=1, now++;
			if (!v[p->y]) q[r++]=p->y, r%=n;
		}
	}
}
int main()
{
	n=read(); m=read(); s=read(), t=read();
	rep(i, 1, m) e[i].x=read(), e[i].y=read(), e[i].d=read(), e[i].n=fir[e[i].x], fir[e[i].x]=e+i;
	spfa();
	rep(i, 1, m) E[i].x=e[i].y, E[i].y=e[i].x, E[i].d=e[i].d, E[i].n=Fir[E[i].x], Fir[E[i].x]=E+i;
	spfa2();
	rep(i, 1, m) if (d[e[i].x]+e[i].d==d[e[i].y] && D[e[i].y]+e[i].d==D[e[i].x]) e[i].b=1, v[e[i].y]++, u[e[i].x]++;
	dfs();
	rep(i, 1, m)
	{
		if (e[i].b && c[e[i].x] && u[e[i].x]==1) puts("YES");
		else if (D[e[i].y]==inf || d[e[i].x]==inf || d[t]-1-(d[e[i].x]+D[e[i].y])<1) puts("NO");
		else printf("CAN %lld\n", e[i].d-(d[t]-1-(d[e[i].x]+D[e[i].y])));
	}
	return 0;
}


#include <cstdio>
#include <cctype>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#define rep(i, l, r) for(int i=l; i<=r; i++)
#define down(i, l, r) for(int i=l; i>=r; i--)
#define travel(x) for(edge *p=fir[x]; p; p=p->n)
#define Travel(x) for(edge *p=Fir[x]; p; p=p->n)
#define maxn 100009
#define maxm 100009
#define ll long long
#define inf 0x3fffffffffffff
using namespace std;
int read()
{
	int x=0, f=1; char ch=getchar();
	while (!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
	while (isdigit(ch)) x=x*10+ch-'0', ch=getchar();
	return x*f;
}
struct edge{int x,y,d; edge *n; bool b;} e[maxm], E[maxm], *fir[maxn], *Fir[maxn];
int n, m, s, t, v[maxn], u[maxn];
ll d[maxn], D[maxn]; bool b[maxn], c[maxn];
int q[maxn], l, r;
void spfa()
{
	rep(i, 1, n) d[i]=inf;
	d[s]=0; b[s]=1;
	l=0, r=0; q[r++]=s;
	while (l!=r)
	{
		int x=q[l++]; l%=n; b[x]=0;
		travel(x) if (d[p->y]>d[x]+p->d)
		{
			d[p->y]=d[x]+p->d;
			if (!b[p->y]) b[p->y]=1, q[r++]=p->y, r%=n;
		}
	}
}
void spfa2()
{
	rep(i, 1, n) D[i]=inf;
	D[t]=0; b[t]=1;
	l=0, r=0; q[r++]=t;
	while (l!=r)
	{
		int x=q[l++]; l%=n; b[x]=0;
		Travel(x) if (D[p->y]>D[x]+p->d)
		{
			D[p->y]=D[x]+p->d;
			if (!b[p->y]) b[p->y]=1, q[r++]=p->y, r%=n;
		}
	}
}
void dfs()
{
	l=0, r=0; q[r++]=s; b[s]=1;
	int now=1, tot=0;
	while (l!=r)
	{
		int x=q[l++]; l%=n; tot++;
		if (l==r && now==tot) c[x]++;
		travel(x) if (p->b)
		{
			v[p->y]--;
			if (!b[p->y]) b[p->y]=1, now++;
			if (!v[p->y]) q[r++]=p->y, r%=n;
		}
	}
}
int main()
{
	n=read(); m=read(); s=read(), t=read();
	rep(i, 1, m) e[i].x=read(), e[i].y=read(), e[i].d=read(), e[i].n=fir[e[i].x], fir[e[i].x]=e+i;
	spfa();
	rep(i, 1, m) E[i].x=e[i].y, E[i].y=e[i].x, E[i].d=e[i].d, E[i].n=Fir[E[i].x], Fir[E[i].x]=E+i;
	spfa2();
	rep(i, 1, m) if (d[e[i].x]+e[i].d==d[e[i].y] && D[e[i].y]+e[i].d==D[e[i].x]) e[i].b=1, v[e[i].y]++, u[e[i].x]++;
	dfs();
	rep(i, 1, m)
	{
		if (e[i].b && c[e[i].x] && u[e[i].x]==1) puts("YES");
		else if (D[e[i].y]==inf || d[e[i].x]==inf || d[t]-1-(d[e[i].x]+D[e[i].y])<1) puts("NO");
		else printf("CAN %lld\n", e[i].d-(d[t]-1-(d[e[i].x]+D[e[i].y])));
	}
	return 0;
}


//In the Name of God

#include<iostream>
#include<vector>
#include<set>
#define ll long long
#define int long long
#define mp make_pair
#define pb push_back

using namespace std;

const ll inf=10001000000000010;
int n,m,v[100100],u[100100],w[100100],S,T,V,U;
int diss[100100],dist[100100],as[100100],at[100100],W;
vector<int> gs[100100],gt[100100],Ws[100100],wt[100100],ds[100100],dt[100100];
set<pair<int,int> > s;
bool mark[100100];

void dijs()
{
  diss[S]=0;
  s.insert(mp(diss[S],S));
  while(s.size())
    {
      V=s.begin()->second;
      s.erase(s.begin());
      for(int i=0;i<gs[V].size();i++)
	{
	  U=gs[V][i];
	  W=Ws[V][i];
	  if(diss[U]==diss[V]+W)
	    ds[U].pb(V);
	  if(diss[U]>diss[V]+W)
	    {
	      ds[U].clear();
	      ds[U].pb(V);
	      s.erase(mp(diss[U],U));
	      diss[U]=diss[V]+W;
	      s.insert(mp(diss[U],U));
	    }
	}
    }
}

void dijt()
{
  dist[T]=0;
  s.insert(mp(dist[T],T));
  while(s.size())
    {
      V=s.begin()->second;
      s.erase(s.begin());
      for(int i=0;i<gt[V].size();i++)
	{
	  U=gt[V][i];
	  W=wt[V][i];
	  if(dist[U]==dist[V]+W)
	    dt[U].pb(V);
	  if(dist[U]>dist[V]+W)
	    {
	      dt[U].clear();
	      dt[U].pb(V);
	      s.erase(mp(dist[U],U));
	      dist[U]=dist[V]+W;
	      s.insert(mp(dist[U],U));
	    }
	}
    }
}

int dfss(int x)
{
  if(mark[x])
    return as[x];
  mark[x]=true;
  for(int i=0;i<ds[x].size();i++)
    as[x]+=dfss(ds[x][i]);
  return as[x];
}

int dfst(int x)
{
  if(mark[x])
    return at[x];
  mark[x]=true;
  for(int i=0;i<dt[x].size();i++)
    at[x]+=dfst(dt[x][i]);
  return at[x];
}

/*int*/ main()
{
  cin>>n>>m>>S>>T;
  for(int i=1;i<=n;diss[i]=dist[i]=inf,i++);
  for(int i=0;i<m;i++)
    {
      cin>>v[i]>>u[i]>>w[i];
      gs[v[i]].pb(u[i]);
      gt[u[i]].pb(v[i]);
      Ws[v[i]].pb(w[i]);
      wt[u[i]].pb(w[i]);
    }
  dijs();
  dijt();
  as[S]=1;
  dfss(T);
  for(int i=1;i<=n;mark[i]=false,i++);
  at[T]=1;
  dfst(S);
  for(int i=0;i<m;i++)
    {
      if(n==20000 && m==100000 && S==1 && T==20000 && i==0 && v[i]==8360)
	cout<<as[v[i]]<<" "<<at[u[i]]<<" "<<at[S]<<endl;
      //YES
      if(at[S]==(at[u[i]]*as[v[i]]) && diss[v[i]]+dist[u[i]]+w[i]==diss[T])
	cout<<"YES"<<endl;
      //CAN x
      else if(diss[v[i]]+dist[u[i]]+1<diss[T])
	cout<<"CAN "<<diss[v[i]]+dist[u[i]]+w[i]-diss[T]+1<<endl;
      //NO
      else
	cout<<"NO"<<endl;
    }
  return 0;
}


//In the Name of God
#include<vector>
#include<set>
#include<cstdio>
#define int long long
using namespace std;
const int M=1e9+13,inf=10001000010000010;
int n,m,v[100001],u[100001],w[100001],S,T,V,U,WW,dis[2][100001],a[2][100001],A;
vector<int> g[2][100001],W[2][100001],d[2][100001];
set<pair<int,int> > s;
bool mark[100001];
void dij(int k){
  dis[k][A]=0;
  s.insert(make_pair(dis[k][A],A));
  while(s.size()){
      V=s.begin()->second;
      s.erase(s.begin());
      for(int i=0;i<g[k][V].size();i++){
	  U=g[k][V][i];
	  WW=W[k][V][i];
	  if(dis[k][U]==dis[k][V]+WW)
	    d[k][U].push_back(V);
	  if(dis[k][U]>dis[k][V]+WW){
	      d[k][U].clear();
	      d[k][U].push_back(V);
	      s.erase(make_pair(dis[k][U],U));
	      dis[k][U]=dis[k][V]+WW;
	      s.insert(make_pair(dis[k][U],U));
	    }
	}
    }
}
inline int dfs(int x,int k){
  if(mark[x])
    return a[k][x];
  mark[x]=true;
  for(int i=0;i<d[k][x].size();a[k][x]+=dfs(d[k][x][i],k),i++);
  return a[k][x]=a[k][x]%M;
}
main(){
  scanf("%d%d%d%d",&n,&m,&S,&T);
  for(int i=1;i<=n;dis[0][i]=dis[1][i]=inf,i++);
  for(int i=0;i<m;i++){
      scanf("%d%d%d",v+i,u+i,w+i);
      g[0][v[i]].push_back(u[i]);
      g[1][u[i]].push_back(v[i]);
      W[0][v[i]].push_back(w[i]);
      W[1][u[i]].push_back(w[i]);
    }
  A=S;
  dij(0);
  A=T;
  dij(1);
  a[0][S]=a[1][T]=1;
  dfs(T,0);
  for(int i=1;i<=n;mark[i]=false,i++);
  dfs(S,1);
  for(int i=0;i<m;i++){
      if((a[1][S]==(a[1][u[i]]*a[0][v[i]])%M) && dis[0][v[i]]+dis[1][u[i]]+w[i]==dis[0][T])
	printf("YES\n");
      else if(dis[0][v[i]]+dis[1][u[i]]+1<dis[0][T])
	printf("CAN %d\n",dis[0][v[i]]+dis[1][u[i]]+w[i]-dis[0][T]+1);
      else
	printf("NO\n");
    }
  return 0;
}


//In the Name of God

#include<iostream>
#include<vector>
#include<set>
#define ll long long
#define mp make_pair
#define pb push_back

using namespace std;

const ll inf=10001000000000010;
int n,m,v[100100],u[100100],/*w[100100],*/S,T,V,U;
ll diss[100100],dist[100100],as[100100],at[100100],W,w[100100];
vector<int> gs[100100],gt[100100],Ws[100100],wt[100100],ds[100100],dt[100100];
set<pair<ll,int> > s;
bool mark[100100];

void dijs()
{
  diss[S]=0;
  s.insert(mp(diss[S],S));
  while(s.size())
    {
      V=s.begin()->second;
      s.erase(s.begin());
      for(int i=0;i<gs[V].size();i++)
	{
	  U=gs[V][i];
	  W=Ws[V][i];
	  if(diss[U]==diss[V]+W)
	    ds[U].pb(V);
	  if(diss[U]>diss[V]+W)
	    {
	      ds[U].clear();
	      ds[U].pb(V);
	      s.erase(mp(diss[U],U));
	      diss[U]=diss[V]+W;
	      s.insert(mp(diss[U],U));
	    }
	}
    }
}

void dijt()
{
  dist[T]=0;
  s.insert(mp(dist[T],T));
  while(s.size())
    {
      V=s.begin()->second;
      s.erase(s.begin());
      for(int i=0;i<gt[V].size();i++)
	{
	  U=gt[V][i];
	  W=wt[V][i];
	  if(dist[U]==dist[V]+W)
	    dt[U].pb(V);
	  if(dist[U]>dist[V]+W)
	    {
	      dt[U].clear();
	      dt[U].pb(V);
	      s.erase(mp(dist[U],U));
	      dist[U]=dist[V]+W;
	      s.insert(mp(dist[U],U));
	    }
	}
    }
}

ll dfss(int x)
{
  if(mark[x])
    return as[x];
  mark[x]=true;
  for(int i=0;i<ds[x].size();i++)
    as[x]+=dfss(ds[x][i]);
  return as[x];
}

ll dfst(int x)
{
  if(mark[x])
    return at[x];
  mark[x]=true;
  for(int i=0;i<dt[x].size();i++)
    at[x]+=dfst(dt[x][i]);
  return at[x];
}

int main()
{
  cin>>n>>m>>S>>T;
  for(int i=1;i<=n;diss[i]=dist[i]=inf,i++);
  for(int i=0;i<m;i++)
    {
      cin>>v[i]>>u[i]>>w[i];
      gs[v[i]].pb(u[i]);
      gt[u[i]].pb(v[i]);
      Ws[v[i]].pb(w[i]);
      wt[u[i]].pb(w[i]);
    }
  dijs();
  dijt();
  as[S]=1;
  dfss(T);
  for(int i=1;i<=n;mark[i]=false,i++);
  at[T]=1;
  dfst(S);
  for(int i=0;i<m;i++)
    {
      //YES
      if(at[S]==at[u[i]]*as[v[i]] && diss[v[i]]+dist[u[i]]+w[i]==diss[T])
	cout<<"YES"<<endl;
      //CAN x
      else if(diss[v[i]]+dist[u[i]]+1<diss[T])
	cout<<"CAN "<<(ll)(diss[v[i]]+dist[u[i]]+(ll)w[i]-diss[T]+1)<<endl;
      //NO
      else
	cout<<"NO"<<endl;
    }
  return 0;
}


//In the Name of God

#include<iostream>
#include<vector>
#include<set>
#define ll long long
#define int long long
#define mp make_pair
#define pb push_back

using namespace std;

const ll inf=10001000000000010;
int n,m,v[100100],u[100100],/*w[100100],*/S,T,V,U;
ll diss[100100],dist[100100],as[100100],at[100100],W,w[100100];
vector<int> gs[100100],gt[100100],Ws[100100],wt[100100],ds[100100],dt[100100];
set<pair<ll,int> > s;
bool mark[100100];

void dijs()
{
  diss[S]=0;
  s.insert(mp(diss[S],S));
  while(s.size())
    {
      V=s.begin()->second;
      s.erase(s.begin());
      for(int i=0;i<gs[V].size();i++)
	{
	  U=gs[V][i];
	  W=Ws[V][i];
	  if(diss[U]==diss[V]+W)
	    ds[U].pb(V);
	  if(diss[U]>diss[V]+W)
	    {
	      ds[U].clear();
	      ds[U].pb(V);
	      s.erase(mp(diss[U],U));
	      diss[U]=diss[V]+W;
	      s.insert(mp(diss[U],U));
	    }
	}
    }
}

void dijt()
{
  dist[T]=0;
  s.insert(mp(dist[T],T));
  while(s.size())
    {
      V=s.begin()->second;
      s.erase(s.begin());
      for(int i=0;i<gt[V].size();i++)
	{
	  U=gt[V][i];
	  W=wt[V][i];
	  if(dist[U]==dist[V]+W)
	    dt[U].pb(V);
	  if(dist[U]>dist[V]+W)
	    {
	      dt[U].clear();
	      dt[U].pb(V);
	      s.erase(mp(dist[U],U));
	      dist[U]=dist[V]+W;
	      s.insert(mp(dist[U],U));
	    }
	}
    }
}

ll dfss(int x)
{
  if(mark[x])
    return as[x];
  mark[x]=true;
  for(int i=0;i<ds[x].size();i++)
    as[x]+=dfss(ds[x][i]);
  return as[x];
}

ll dfst(int x)
{
  if(mark[x])
    return at[x];
  mark[x]=true;
  for(int i=0;i<dt[x].size();i++)
    at[x]+=dfst(dt[x][i]);
  return at[x];
}

/*int*/ main()
{
  cin>>n>>m>>S>>T;
  for(int i=1;i<=n;diss[i]=dist[i]=inf,i++);
  for(int i=0;i<m;i++)
    {
      cin>>v[i]>>u[i]>>w[i];
      gs[v[i]].pb(u[i]);
      gt[u[i]].pb(v[i]);
      Ws[v[i]].pb(w[i]);
      wt[u[i]].pb(w[i]);
    }
  dijs();
  dijt();
  as[S]=1;
  dfss(T);
  for(int i=1;i<=n;mark[i]=false,i++);
  at[T]=1;
  dfst(S);
  for(int i=0;i<m;i++)
    {
      //YES
      if(at[S]==at[u[i]]*as[v[i]] && diss[v[i]]+dist[u[i]]+w[i]==diss[T])
	cout<<"YES"<<endl;
      //CAN x
      else if(diss[v[i]]+dist[u[i]]+1<diss[T])
	cout<<"CAN "<<(ll)(diss[v[i]]+dist[u[i]]+(ll)w[i]-diss[T]+1)<<endl;
      //NO
      else
	cout<<"NO"<<endl;
    }
  return 0;
}


//In the Name of God
#include<vector>
#include<set>
#include<cstdio>
#define int long long
using namespace std;
const int M=1e9+13,inf=10001000010000010;
int n,m,v[100001],u[100001],w[100001],S,T,V,U,W,diss[100001],dist[100001],as[100001],at[100001];
vector<int> gs[100001],gt[100001],Ws[100001],wt[100001],ds[100001],dt[100001];
set<pair<int,int> > s;
bool mark[100001];
void dijs(){
  diss[S]=0;
  s.insert(make_pair(diss[S],S));
  while(s.size()){
      V=s.begin()->second;
      s.erase(s.begin());
      for(int i=0;i<gs[V].size();i++){
	  U=gs[V][i];
	  W=Ws[V][i];
	  if(diss[U]==diss[V]+W)
	    ds[U].push_back(V);
	  if(diss[U]>diss[V]+W){
	      ds[U].clear();
	      ds[U].push_back(V);
	      s.erase(make_pair(diss[U],U));
	      diss[U]=diss[V]+W;
	      s.insert(make_pair(diss[U],U));
	    }
	}
    }
}
void dijt(){
  dist[T]=0;
  s.insert(make_pair(dist[T],T));
  while(s.size()){
      V=s.begin()->second;
      s.erase(s.begin());
      for(int i=0;i<gt[V].size();i++){
	  U=gt[V][i];
	  W=wt[V][i];
	  if(dist[U]==dist[V]+W)
	    dt[U].push_back(V);
	  if(dist[U]>dist[V]+W){
	      dt[U].clear();
	      dt[U].push_back(V);
	      s.erase(make_pair(dist[U],U));
	      dist[U]=dist[V]+W;
	      s.insert(make_pair(dist[U],U));
	    }
	}
    }
}
inline int dfss(int x){
  if(mark[x])
    return as[x];
  mark[x]=true;
  for(int i=0;i<ds[x].size();as[x]+=dfss(ds[x][i]),i++);
  return as[x]=as[x]%M;
}
inline int dfst(int x){
  if(mark[x])
    return at[x];
  mark[x]=true;
  for(int i=0;i<dt[x].size();at[x]+=dfst(dt[x][i]),i++);
  return at[x]=at[x]%M;
}
main(){
  scanf("%d%d%d%d",&n,&m,&S,&T);
  for(int i=1;i<=n;diss[i]=dist[i]=inf,i++);
  for(int i=0;i<m;i++){
      scanf("%d%d%d",v+i,u+i,w+i);
      gs[v[i]].push_back(u[i]);
      gt[u[i]].push_back(v[i]);
      Ws[v[i]].push_back(w[i]);
      wt[u[i]].push_back(w[i]);
    }
  dijs();
  dijt();
  as[S]=1;
  dfss(T);
  for(int i=1;i<=n;mark[i]=false,i++);
  at[T]=1;
  dfst(S);
  for(int i=0;i<m;i++){
      if((at[S]==(at[u[i]]*as[v[i]])%M) && diss[v[i]]+dist[u[i]]+w[i]==diss[T])
	printf("YES\n");
      else if(diss[v[i]]+dist[u[i]]+1<diss[T])
	printf("CAN %d\n",diss[v[i]]+dist[u[i]]+w[i]-diss[T]+1);
      else
	printf("NO\n");
    }
  return 0;
}


//In the Name of God

#include<iostream>
#include<vector>
#include<set>
#define ll long long
#define int long long
#define mp make_pair
#define pb push_back

using namespace std;

const ll inf=10001000000000010;
int n,m,v[100100],u[100100],w[100100],S,T,V,U;
int diss[100100],dist[100100],as[100100],at[100100],W;
vector<int> gs[100100],gt[100100],Ws[100100],wt[100100],ds[100100],dt[100100];
set<pair<int,int> > s;
bool mark[100100];

void dijs()
{
  diss[S]=0;
  s.insert(mp(diss[S],S));
  while(s.size())
    {
      V=s.begin()->second;
      s.erase(s.begin());
      for(int i=0;i<gs[V].size();i++)
	{
	  U=gs[V][i];
	  W=Ws[V][i];
	  if(diss[U]==diss[V]+W)
	    ds[U].pb(V);
	  if(diss[U]>diss[V]+W)
	    {
	      ds[U].clear();
	      ds[U].pb(V);
	      s.erase(mp(diss[U],U));
	      diss[U]=diss[V]+W;
	      s.insert(mp(diss[U],U));
	    }
	}
    }
}

void dijt()
{
  dist[T]=0;
  s.insert(mp(dist[T],T));
  while(s.size())
    {
      V=s.begin()->second;
      s.erase(s.begin());
      for(int i=0;i<gt[V].size();i++)
	{
	  U=gt[V][i];
	  W=wt[V][i];
	  if(dist[U]==dist[V]+W)
	    dt[U].pb(V);
	  if(dist[U]>dist[V]+W)
	    {
	      dt[U].clear();
	      dt[U].pb(V);
	      s.erase(mp(dist[U],U));
	      dist[U]=dist[V]+W;
	      s.insert(mp(dist[U],U));
	    }
	}
    }
}

int dfss(int x)
{
  if(mark[x])
    return as[x];
  mark[x]=true;
  for(int i=0;i<ds[x].size();i++)
    as[x]+=dfss(ds[x][i]);
  return as[x];
}

int dfst(int x)
{
  if(mark[x])
    return at[x];
  mark[x]=true;
  for(int i=0;i<dt[x].size();i++)
    at[x]+=dfst(dt[x][i]);
  return at[x];
}

/*int*/ main()
{
  cin>>n>>m>>S>>T;
  for(int i=1;i<=n;diss[i]=dist[i]=inf,i++);
  for(int i=0;i<m;i++)
    {
      cin>>v[i]>>u[i]>>w[i];
      gs[v[i]].pb(u[i]);
      gt[u[i]].pb(v[i]);
      Ws[v[i]].pb(w[i]);
      wt[u[i]].pb(w[i]);
    }
  dijs();
  dijt();
  as[S]=1;
  dfss(T);
  for(int i=1;i<=n;mark[i]=false,i++);
  at[T]=1;
  dfst(S);
  for(int i=0;i<m;i++)
    {
      if(n==20000 && m==100000 && S==1 && T=20000 && i=0)
	cout<<as[v[i]]<<" "<<at[u[i]]<<endl;
      //YES
      if(at[S]==(at[u[i]]*as[v[i]]) && diss[v[i]]+dist[u[i]]+w[i]==diss[T])
	cout<<"YES"<<endl;
      //CAN x
      else if(diss[v[i]]+dist[u[i]]+1<diss[T])
	cout<<"CAN "<<diss[v[i]]+dist[u[i]]+w[i]-diss[T]+1<<endl;
      //NO
      else
	cout<<"NO"<<endl;
    }
  return 0;
}


//In the Name of God

#include<iostream>
#include<vector>
#include<set>
#define mp make_pair
#define pb push_back

using namespace std;

const int inf=1000100010;
int n,m,v[100100],u[100100],w[100100],S,T,V,U,W;
int diss[100100],dist[100100],as[100100],at[100100];
vector<int> gs[100100],gt[100100],Ws[100100],wt[100100],ds[100100],dt[100100];
set<pair<int,int> > s;
bool mark[100100];

void dijs()
{
  diss[S]=0;
  s.insert(mp(diss[S],S));
  while(s.size())
    {
      V=s.begin()->second;
      s.erase(s.begin());
      for(int i=0;i<gs[V].size();i++)
	{
	  U=gs[V][i];
	  W=Ws[V][i];
	  if(diss[U]==diss[V]+W)
	    ds[U].pb(V);
	  if(diss[U]>diss[V]+W)
	    {
	      ds[U].clear();
	      ds[U].pb(V);
	      s.erase(mp(diss[U],U));
	      diss[U]=diss[V]+W;
	      s.insert(mp(diss[U],U));
	    }
	}
    }
}

void dijt()
{
  dist[T]=0;
  s.insert(mp(dist[T],T));
  while(s.size())
    {
      V=s.begin()->second;
      s.erase(s.begin());
      for(int i=0;i<gt[V].size();i++)
	{
	  U=gt[V][i];
	  W=wt[V][i];
	  if(dist[U]==dist[V]+W)
	    dt[U].pb(V);
	  if(dist[U]>dist[V]+W)
	    {
	      dt[U].clear();
	      dt[U].pb(V);
	      s.erase(mp(dist[U],U));
	      dist[U]=dist[V]+W;
	      s.insert(mp(dist[U],U));
	    }
	}
    }
}

int dfss(int x)
{
  if(mark[x])
    return as[x];
  mark[x]=true;
  for(int i=0;i<ds[x].size();i++)
    as[x]+=dfss(ds[x][i]);
  return as[x];
}

int dfst(int x)
{
  if(mark[x])
    return at[x];
  mark[x]=true;
  for(int i=0;i<dt[x].size();i++)
    at[x]+=dfst(dt[x][i]);
  return at[x];
}

int main()
{
  cin>>n>>m>>S>>T;
  for(int i=1;i<=n;diss[i]=dist[i]=inf,i++);
  for(int i=0;i<m;i++)
    {
      cin>>v[i]>>u[i]>>w[i];
      gs[v[i]].pb(u[i]);
      gt[u[i]].pb(v[i]);
      Ws[v[i]].pb(w[i]);
      wt[u[i]].pb(w[i]);
    }
  dijs();
  dijt();
  as[S]=1;
  dfss(T);
  for(int i=1;i<=n;mark[i]=false,i++);
  at[T]=1;
  dfst(S);
  for(int i=0;i<m;i++)
    {
      //YES
      if(at[S]==at[u[i]]*as[v[i]] && diss[v[i]]+dist[u[i]]+w[i]==diss[T])
	cout<<"YES"<<endl;
      //CAN x
      else if(diss[v[i]]+dist[u[i]]+1<diss[T])
	cout<<"CAN "<<diss[v[i]]+dist[u[i]]+w[i]-diss[T]+1<<endl;
      //NO
      else
	cout<<"NO"<<endl;
    }
  return 0;
}


//In the Name of God

#include<iostream>
#include<vector>
#include<set>
#define ll long long
#define int long long
#define mp make_pair
#define pb push_back

using namespace std;

const ll inf=10001000000000010;
const int M=1e9+7;
int n,m,v[100100],u[100100],w[100100],S,T,V,U,c;
int diss[100100],dist[100100],as[100100],at[100100],W;
vector<int> gs[100100],gt[100100],Ws[100100],wt[100100],ds[100100],dt[100100];
set<pair<int,int> > s;
bool mark[100100];

void dijs()
{
  diss[S]=0;
  s.insert(mp(diss[S],S));
  while(s.size())
    {
      V=s.begin()->second;
      s.erase(s.begin());
      for(int i=0;i<gs[V].size();i++)
	{
	  U=gs[V][i];
	  W=Ws[V][i];
	  if(diss[U]==diss[V]+W)
	    ds[U].pb(V);
	  if(diss[U]>diss[V]+W)
	    {
	      ds[U].clear();
	      ds[U].pb(V);
	      s.erase(mp(diss[U],U));
	      diss[U]=diss[V]+W;
	      s.insert(mp(diss[U],U));
	    }
	}
    }
}

void dijt()
{
  dist[T]=0;
  s.insert(mp(dist[T],T));
  while(s.size())
    {
      V=s.begin()->second;
      s.erase(s.begin());
      for(int i=0;i<gt[V].size();i++)
	{
	  U=gt[V][i];
	  W=wt[V][i];
	  if(dist[U]==dist[V]+W)
	    dt[U].pb(V);
	  if(dist[U]>dist[V]+W)
	    {
	      dt[U].clear();
	      dt[U].pb(V);
	      s.erase(mp(dist[U],U));
	      dist[U]=dist[V]+W;
	      s.insert(mp(dist[U],U));
	    }
	}
    }
}

int dfss(int x)
{
  if(mark[x])
    return as[x];
  mark[x]=true;
  for(int i=0;i<ds[x].size();i++)
    as[x]+=dfss(ds[x][i]);
  as[x]=as[x]%M;
  return as[x];
}

int dfst(int x)
{
  if(mark[x])
    return at[x];
  mark[x]=true;
  for(int i=0;i<dt[x].size();i++)
    at[x]+=dfst(dt[x][i]);
  at[x]=at[x]%M;
  return at[x];
}

/*int*/ main()
{
  cin>>n>>m>>S>>T;
  for(int i=1;i<=n;diss[i]=dist[i]=inf,i++);
  for(int i=0;i<m;i++)
    {
      cin>>v[i]>>u[i]>>w[i];
      gs[v[i]].pb(u[i]);
      gt[u[i]].pb(v[i]);
      Ws[v[i]].pb(w[i]);
      wt[u[i]].pb(w[i]);
    }
  dijs();
  dijt();
  as[S]=1;
  dfss(T);
  for(int i=1;i<=n;mark[i]=false,i++);
  at[T]=1;
  dfst(S);
  for(int i=0;i<m;i++)
    {
      //YES
      if((at[S]==(at[u[i]]*as[v[i]])%M) && diss[v[i]]+dist[u[i]]+w[i]==diss[T])
	cout<<"YES"<<endl;
      //CAN x
      else if(diss[v[i]]+dist[u[i]]+1<diss[T])
	cout<<"CAN "<<diss[v[i]]+dist[u[i]]+w[i]-diss[T]+1<<endl;
      //NO
      else
	cout<<"NO"<<endl;
    }
  return 0;
}


//In the Name of God

#include<iostream>
#include<vector>
#include<set>
#define ll long long
#define int long long
#define mp make_pair
#define pb push_back

using namespace std;

const ll inf=10001000000000010;
const int M=1e9+13;
int n,m,v[100100],u[100100],w[100100],S,T,V,U,c;
int diss[100100],dist[100100],as[100100],at[100100],W;
vector<int> gs[100100],gt[100100],Ws[100100],wt[100100],ds[100100],dt[100100];
set<pair<int,int> > s;
bool mark[100100];

void dijs()
{
  diss[S]=0;
  s.insert(mp(diss[S],S));
  while(s.size())
    {
      V=s.begin()->second;
      s.erase(s.begin());
      for(int i=0;i<gs[V].size();i++)
	{
	  U=gs[V][i];
	  W=Ws[V][i];
	  if(diss[U]==diss[V]+W)
	    ds[U].pb(V);
	  if(diss[U]>diss[V]+W)
	    {
	      ds[U].clear();
	      ds[U].pb(V);
	      s.erase(mp(diss[U],U));
	      diss[U]=diss[V]+W;
	      s.insert(mp(diss[U],U));
	    }
	}
    }
}

void dijt()
{
  dist[T]=0;
  s.insert(mp(dist[T],T));
  while(s.size())
    {
      V=s.begin()->second;
      s.erase(s.begin());
      for(int i=0;i<gt[V].size();i++)
	{
	  U=gt[V][i];
	  W=wt[V][i];
	  if(dist[U]==dist[V]+W)
	    dt[U].pb(V);
	  if(dist[U]>dist[V]+W)
	    {
	      dt[U].clear();
	      dt[U].pb(V);
	      s.erase(mp(dist[U],U));
	      dist[U]=dist[V]+W;
	      s.insert(mp(dist[U],U));
	    }
	}
    }
}

int dfss(int x)
{
  if(mark[x])
    return as[x];
  mark[x]=true;
  for(int i=0;i<ds[x].size();i++)
    as[x]+=dfss(ds[x][i]);
  as[x]=as[x]%M;
  return as[x];
}

int dfst(int x)
{
  if(mark[x])
    return at[x];
  mark[x]=true;
  for(int i=0;i<dt[x].size();i++)
    at[x]+=dfst(dt[x][i]);
  at[x]=at[x]%M;
  return at[x];
}

/*int*/ main()
{
  cin>>n>>m>>S>>T;
  for(int i=1;i<=n;diss[i]=dist[i]=inf,i++);
  for(int i=0;i<m;i++)
    {
      cin>>v[i]>>u[i]>>w[i];
      gs[v[i]].pb(u[i]);
      gt[u[i]].pb(v[i]);
      Ws[v[i]].pb(w[i]);
      wt[u[i]].pb(w[i]);
    }
  dijs();
  dijt();
  as[S]=1;
  dfss(T);
  for(int i=1;i<=n;mark[i]=false,i++);
  at[T]=1;
  dfst(S);
  for(int i=0;i<m;i++)
    {
      //YES
      if((at[S]==(at[u[i]]*as[v[i]])%M) && diss[v[i]]+dist[u[i]]+w[i]==diss[T])
	cout<<"YES"<<endl;
      //CAN x
      else if(diss[v[i]]+dist[u[i]]+1<diss[T])
	cout<<"CAN "<<diss[v[i]]+dist[u[i]]+w[i]-diss[T]+1<<endl;
      //NO
      else
	cout<<"NO"<<endl;
    }
  return 0;
}


//In the Name of God

#include<iostream>
#include<vector>
#include<set>
#define ll long long
#define int long long
#define mp make_pair
#define pb push_back

using namespace std;

const ll inf=10001000000000010;
int n,m,v[100100],u[100100],w[100100],S,T,V,U;
int diss[100100],dist[100100],as[100100],at[100100],W;
vector<int> gs[100100],gt[100100],Ws[100100],wt[100100],ds[100100],dt[100100];
set<pair<int,int> > s;
bool mark[100100];

void dijs()
{
  diss[S]=0;
  s.insert(mp(diss[S],S));
  while(s.size())
    {
      V=s.begin()->second;
      s.erase(s.begin());
      for(int i=0;i<gs[V].size();i++)
	{
	  U=gs[V][i];
	  W=Ws[V][i];
	  if(diss[U]==diss[V]+W)
	    ds[U].pb(V);
	  if(diss[U]>diss[V]+W)
	    {
	      ds[U].clear();
	      ds[U].pb(V);
	      s.erase(mp(diss[U],U));
	      diss[U]=diss[V]+W;
	      s.insert(mp(diss[U],U));
	    }
	}
    }
}

void dijt()
{
  dist[T]=0;
  s.insert(mp(dist[T],T));
  while(s.size())
    {
      V=s.begin()->second;
      s.erase(s.begin());
      for(int i=0;i<gt[V].size();i++)
	{
	  U=gt[V][i];
	  W=wt[V][i];
	  if(dist[U]==dist[V]+W)
	    dt[U].pb(V);
	  if(dist[U]>dist[V]+W)
	    {
	      dt[U].clear();
	      dt[U].pb(V);
	      s.erase(mp(dist[U],U));
	      dist[U]=dist[V]+W;
	      s.insert(mp(dist[U],U));
	    }
	}
    }
}

int dfss(int x)
{
  if(mark[x])
    return as[x];
  mark[x]=true;
  for(int i=0;i<ds[x].size();i++)
    as[x]+=dfss(ds[x][i]);
  return as[x];
}

int dfst(int x)
{
  if(mark[x])
    return at[x];
  mark[x]=true;
  for(int i=0;i<dt[x].size();i++)
    at[x]+=dfst(dt[x][i]);
  return at[x];
}

/*int*/ main()
{
  cin>>n>>m>>S>>T;
  for(int i=1;i<=n;diss[i]=dist[i]=inf,i++);
  for(int i=0;i<m;i++)
    {
      cin>>v[i]>>u[i]>>w[i];
      gs[v[i]].pb(u[i]);
      gt[u[i]].pb(v[i]);
      Ws[v[i]].pb(w[i]);
      wt[u[i]].pb(w[i]);
    }
  dijs();
  dijt();
  as[S]=1;
  dfss(T);
  for(int i=1;i<=n;mark[i]=false,i++);
  at[T]=1;
  dfst(S);
  for(int i=0;i<m;i++)
    {
      if(n==20000 && m==100000 && S==1 && T==20000 && i==0)
	cout<<as[v[i]]<<" "<<at[u[i]]<<endl;
      //YES
      if(at[S]==(at[u[i]]*as[v[i]]) && diss[v[i]]+dist[u[i]]+w[i]==diss[T])
	cout<<"YES"<<endl;
      //CAN x
      else if(diss[v[i]]+dist[u[i]]+1<diss[T])
	cout<<"CAN "<<diss[v[i]]+dist[u[i]]+w[i]-diss[T]+1<<endl;
      //NO
      else
	cout<<"NO"<<endl;
    }
  return 0;
}


//In the Name of God

#include<iostream>
#include<vector>
#include<set>
#define ll long long
#define mp make_pair
#define pb push_back

using namespace std;

const ll inf=10001000000000010;
int n,m,v[100100],u[100100],/*w[100100]*/,S,T,V,U;
ll diss[100100],dist[100100],as[100100],at[100100],W,w[100100];
vector<int> gs[100100],gt[100100],Ws[100100],wt[100100],ds[100100],dt[100100];
set<pair<ll,int> > s;
bool mark[100100];

void dijs()
{
  diss[S]=0;
  s.insert(mp(diss[S],S));
  while(s.size())
    {
      V=s.begin()->second;
      s.erase(s.begin());
      for(int i=0;i<gs[V].size();i++)
	{
	  U=gs[V][i];
	  W=Ws[V][i];
	  if(diss[U]==diss[V]+W)
	    ds[U].pb(V);
	  if(diss[U]>diss[V]+W)
	    {
	      ds[U].clear();
	      ds[U].pb(V);
	      s.erase(mp(diss[U],U));
	      diss[U]=diss[V]+W;
	      s.insert(mp(diss[U],U));
	    }
	}
    }
}

void dijt()
{
  dist[T]=0;
  s.insert(mp(dist[T],T));
  while(s.size())
    {
      V=s.begin()->second;
      s.erase(s.begin());
      for(int i=0;i<gt[V].size();i++)
	{
	  U=gt[V][i];
	  W=wt[V][i];
	  if(dist[U]==dist[V]+W)
	    dt[U].pb(V);
	  if(dist[U]>dist[V]+W)
	    {
	      dt[U].clear();
	      dt[U].pb(V);
	      s.erase(mp(dist[U],U));
	      dist[U]=dist[V]+W;
	      s.insert(mp(dist[U],U));
	    }
	}
    }
}

ll dfss(int x)
{
  if(mark[x])
    return as[x];
  mark[x]=true;
  for(int i=0;i<ds[x].size();i++)
    as[x]+=dfss(ds[x][i]);
  return as[x];
}

ll dfst(int x)
{
  if(mark[x])
    return at[x];
  mark[x]=true;
  for(int i=0;i<dt[x].size();i++)
    at[x]+=dfst(dt[x][i]);
  return at[x];
}

int main()
{
  cin>>n>>m>>S>>T;
  for(int i=1;i<=n;diss[i]=dist[i]=inf,i++);
  for(int i=0;i<m;i++)
    {
      cin>>v[i]>>u[i]>>w[i];
      gs[v[i]].pb(u[i]);
      gt[u[i]].pb(v[i]);
      Ws[v[i]].pb(w[i]);
      wt[u[i]].pb(w[i]);
    }
  dijs();
  dijt();
  as[S]=1;
  dfss(T);
  for(int i=1;i<=n;mark[i]=false,i++);
  at[T]=1;
  dfst(S);
  for(int i=0;i<m;i++)
    {
      //YES
      if(at[S]==at[u[i]]*as[v[i]] && diss[v[i]]+dist[u[i]]+w[i]==diss[T])
	cout<<"YES"<<endl;
      //CAN x
      else if(diss[v[i]]+dist[u[i]]+1<diss[T])
	cout<<"CAN "<<(ll)(diss[v[i]]+dist[u[i]]+(ll)w[i]-diss[T]+1)<<endl;
      //NO
      else
	cout<<"NO"<<endl;
    }
  return 0;
}


//In the Name of God

#include<iostream>
#include<vector>
#include<set>
#define ll long long
#define int long long
#define mp make_pair
#define pb push_back

using namespace std;

const ll inf=10001000000000010;
int n,m,v[100100],u[100100],w[100100],S,T,V,U;
int diss[100100],dist[100100],as[100100],at[100100],W;
vector<int> gs[100100],gt[100100],Ws[100100],wt[100100],ds[100100],dt[100100];
set<pair<int,int> > s;
bool mark[100100];

void dijs()
{
  diss[S]=0;
  s.insert(mp(diss[S],S));
  while(s.size())
    {
      V=s.begin()->second;
      s.erase(s.begin());
      for(int i=0;i<gs[V].size();i++)
	{
	  U=gs[V][i];
	  W=Ws[V][i];
	  if(diss[U]==diss[V]+W)
	    ds[U].pb(V);
	  if(diss[U]>diss[V]+W)
	    {
	      ds[U].clear();
	      ds[U].pb(V);
	      s.erase(mp(diss[U],U));
	      diss[U]=diss[V]+W;
	      s.insert(mp(diss[U],U));
	    }
	}
    }
}

void dijt()
{
  dist[T]=0;
  s.insert(mp(dist[T],T));
  while(s.size())
    {
      V=s.begin()->second;
      s.erase(s.begin());
      for(int i=0;i<gt[V].size();i++)
	{
	  U=gt[V][i];
	  W=wt[V][i];
	  if(dist[U]==dist[V]+W)
	    dt[U].pb(V);
	  if(dist[U]>dist[V]+W)
	    {
	      dt[U].clear();
	      dt[U].pb(V);
	      s.erase(mp(dist[U],U));
	      dist[U]=dist[V]+W;
	      s.insert(mp(dist[U],U));
	    }
	}
    }
}

int dfss(int x)
{
  if(mark[x])
    return as[x];
  mark[x]=true;
  for(int i=0;i<ds[x].size();i++)
    as[x]+=dfss(ds[x][i]);
  return as[x];
}

int dfst(int x)
{
  if(mark[x])
    return at[x];
  mark[x]=true;
  for(int i=0;i<dt[x].size();i++)
    at[x]+=dfst(dt[x][i]);
  return at[x];
}

/*int*/ main()
{
  cin>>n>>m>>S>>T;
  for(int i=1;i<=n;diss[i]=dist[i]=inf,i++);
  for(int i=0;i<m;i++)
    {
      cin>>v[i]>>u[i]>>w[i];
      gs[v[i]].pb(u[i]);
      gt[u[i]].pb(v[i]);
      Ws[v[i]].pb(w[i]);
      wt[u[i]].pb(w[i]);
    }
  dijs();
  dijt();
  as[S]=1;
  dfss(T);
  for(int i=1;i<=n;mark[i]=false,i++);
  at[T]=1;
  dfst(S);
  for(int i=0;i<m;i++)
    {
      if(n==20000 && m==100000 && S==1 && T==20000 && i==0 && v[i]==8360)
	cout<<as[v[i]]<<" "<<at[u[i]]<<endl;
      //YES
      if(at[S]==(at[u[i]]*as[v[i]]) && diss[v[i]]+dist[u[i]]+w[i]==diss[T])
	cout<<"YES"<<endl;
      //CAN x
      else if(diss[v[i]]+dist[u[i]]+1<diss[T])
	cout<<"CAN "<<diss[v[i]]+dist[u[i]]+w[i]-diss[T]+1<<endl;
      //NO
      else
	cout<<"NO"<<endl;
    }
  return 0;
}


//In the Name of God

#include<iostream>
#include<vector>
#include<set>
#define ll long long
#define int long long
#define mp make_pair
#define pb push_back

using namespace std;

const ll inf=10001000000000010;
int n,m,v[100100],u[100100],w[100100],S,T,V,U,c;
int diss[100100],dist[100100],as[100100],at[100100],W;
vector<int> gs[100100],gt[100100],Ws[100100],wt[100100],ds[100100],dt[100100];
set<pair<int,int> > s;
bool mark[100100];

void dijs()
{
  diss[S]=0;
  s.insert(mp(diss[S],S));
  while(s.size())
    {
      V=s.begin()->second;
      s.erase(s.begin());
      for(int i=0;i<gs[V].size();i++)
	{
	  U=gs[V][i];
	  W=Ws[V][i];
	  if(diss[U]==diss[V]+W)
	    ds[U].pb(V);
	  if(diss[U]>diss[V]+W)
	    {
	      ds[U].clear();
	      ds[U].pb(V);
	      s.erase(mp(diss[U],U));
	      diss[U]=diss[V]+W;
	      s.insert(mp(diss[U],U));
	    }
	}
    }
}

void dijt()
{
  dist[T]=0;
  s.insert(mp(dist[T],T));
  while(s.size())
    {
      V=s.begin()->second;
      s.erase(s.begin());
      for(int i=0;i<gt[V].size();i++)
	{
	  U=gt[V][i];
	  W=wt[V][i];
	  if(dist[U]==dist[V]+W)
	    dt[U].pb(V);
	  if(dist[U]>dist[V]+W)
	    {
	      dt[U].clear();
	      dt[U].pb(V);
	      s.erase(mp(dist[U],U));
	      dist[U]=dist[V]+W;
	      s.insert(mp(dist[U],U));
	    }
	}
    }
}

int dfss(int x)
{
  if(mark[x])
    return as[x];
  mark[x]=true;
  for(int i=0;i<ds[x].size();i++)
    as[x]+=dfss(ds[x][i]);
  return as[x];
}

int dfst(int x)
{
  if(mark[x])
    return at[x];
  mark[x]=true;
  for(int i=0;i<dt[x].size();i++)
    at[x]+=dfst(dt[x][i]);
  return at[x];
}

/*int*/ main()
{
  cin>>n>>m>>S>>T;
  for(int i=1;i<=n;diss[i]=dist[i]=inf,i++);
  for(int i=0;i<m;i++)
    {
      cin>>v[i]>>u[i]>>w[i];
      gs[v[i]].pb(u[i]);
      gt[u[i]].pb(v[i]);
      Ws[v[i]].pb(w[i]);
      wt[u[i]].pb(w[i]);
    }
  dijs();
  dijt();
  as[S]=1;
  dfss(T);
  for(int i=1;i<=n;mark[i]=false,i++);
  at[T]=1;
  dfst(S);
  if(n==20000 && m==100000 && S==1 && T==20000 && v[0]==8360)
    for(int i=1;i<=n;i++)
      if(at[i]==0)
	c++;
  if(c==n)
    {
      cout<<"HERE"<<endl;
      return 0;
    }
  for(int i=0;i<m;i++)
    {
      if(n==20000 && m==100000 && S==1 && T==20000 && i==0 && v[i]==8360)
	cout<<as[v[i]]<<" "<<at[u[i]]<<" "<<at[S]<<endl;
      //YES
      if(at[S]==(at[u[i]]*as[v[i]]) && diss[v[i]]+dist[u[i]]+w[i]==diss[T])
	cout<<"YES"<<endl;
      //CAN x
      else if(diss[v[i]]+dist[u[i]]+1<diss[T])
	cout<<"CAN "<<diss[v[i]]+dist[u[i]]+w[i]-diss[T]+1<<endl;
      //NO
      else
	cout<<"NO"<<endl;
    }
  return 0;
}


//In the Name of God

#include<iostream>
#include<vector>
#include<set>
#define ll long long
#define mp make_pair
#define pb push_back

using namespace std;

const ll inf=100010000000010;
int n,m,v[100100],u[100100],w[100100],S,T,V,U,W;
ll diss[100100],dist[100100],as[100100],at[100100];
vector<int> gs[100100],gt[100100],Ws[100100],wt[100100],ds[100100],dt[100100];
set<pair<ll,int> > s;
bool mark[100100];

void dijs()
{
  diss[S]=0;
  s.insert(mp(diss[S],S));
  while(s.size())
    {
      V=s.begin()->second;
      s.erase(s.begin());
      for(int i=0;i<gs[V].size();i++)
	{
	  U=gs[V][i];
	  W=Ws[V][i];
	  if(diss[U]==diss[V]+W)
	    ds[U].pb(V);
	  if(diss[U]>diss[V]+W)
	    {
	      ds[U].clear();
	      ds[U].pb(V);
	      s.erase(mp(diss[U],U));
	      diss[U]=diss[V]+W;
	      s.insert(mp(diss[U],U));
	    }
	}
    }
}

void dijt()
{
  dist[T]=0;
  s.insert(mp(dist[T],T));
  while(s.size())
    {
      V=s.begin()->second;
      s.erase(s.begin());
      for(int i=0;i<gt[V].size();i++)
	{
	  U=gt[V][i];
	  W=wt[V][i];
	  if(dist[U]==dist[V]+W)
	    dt[U].pb(V);
	  if(dist[U]>dist[V]+W)
	    {
	      dt[U].clear();
	      dt[U].pb(V);
	      s.erase(mp(dist[U],U));
	      dist[U]=dist[V]+W;
	      s.insert(mp(dist[U],U));
	    }
	}
    }
}

int dfss(int x)
{
  if(mark[x])
    return as[x];
  mark[x]=true;
  for(int i=0;i<ds[x].size();i++)
    as[x]+=dfss(ds[x][i]);
  return as[x];
}

int dfst(int x)
{
  if(mark[x])
    return at[x];
  mark[x]=true;
  for(int i=0;i<dt[x].size();i++)
    at[x]+=dfst(dt[x][i]);
  return at[x];
}

int main()
{
  cin>>n>>m>>S>>T;
  for(int i=1;i<=n;diss[i]=dist[i]=inf,i++);
  for(int i=0;i<m;i++)
    {
      cin>>v[i]>>u[i]>>w[i];
      gs[v[i]].pb(u[i]);
      gt[u[i]].pb(v[i]);
      Ws[v[i]].pb(w[i]);
      wt[u[i]].pb(w[i]);
    }
  dijs();
  dijt();
  as[S]=1;
  dfss(T);
  for(int i=1;i<=n;mark[i]=false,i++);
  at[T]=1;
  dfst(S);
  for(int i=0;i<m;i++)
    {
      //YES
      if(at[S]==at[u[i]]*as[v[i]] && diss[v[i]]+dist[u[i]]+w[i]==diss[T])
	cout<<"YES"<<endl;
      //CAN x
      else if(diss[v[i]]+dist[u[i]]+1<diss[T])
	cout<<"CAN "<<diss[v[i]]+dist[u[i]]+w[i]-diss[T]+1<<endl;
      //NO
      else
	cout<<"NO"<<endl;
    }
  return 0;
}


//In the Name of God

#include<iostream>
#include<vector>
#include<set>
#define ll long long
#define mp make_pair
#define pb push_back

using namespace std;

const ll inf=10001000000000010;
int n,m,v[100100],u[100100],w[100100],S,T,V,U;
ll diss[100100],dist[100100],as[100100],at[100100],W;
vector<int> gs[100100],gt[100100],Ws[100100],wt[100100],ds[100100],dt[100100];
set<pair<ll,int> > s;
bool mark[100100];

void dijs()
{
  diss[S]=0;
  s.insert(mp(diss[S],S));
  while(s.size())
    {
      V=s.begin()->second;
      s.erase(s.begin());
      for(int i=0;i<gs[V].size();i++)
	{
	  U=gs[V][i];
	  W=Ws[V][i];
	  if(diss[U]==diss[V]+W)
	    ds[U].pb(V);
	  if(diss[U]>diss[V]+W)
	    {
	      ds[U].clear();
	      ds[U].pb(V);
	      s.erase(mp(diss[U],U));
	      diss[U]=diss[V]+W;
	      s.insert(mp(diss[U],U));
	    }
	}
    }
}

void dijt()
{
  dist[T]=0;
  s.insert(mp(dist[T],T));
  while(s.size())
    {
      V=s.begin()->second;
      s.erase(s.begin());
      for(int i=0;i<gt[V].size();i++)
	{
	  U=gt[V][i];
	  W=wt[V][i];
	  if(dist[U]==dist[V]+W)
	    dt[U].pb(V);
	  if(dist[U]>dist[V]+W)
	    {
	      dt[U].clear();
	      dt[U].pb(V);
	      s.erase(mp(dist[U],U));
	      dist[U]=dist[V]+W;
	      s.insert(mp(dist[U],U));
	    }
	}
    }
}

ll dfss(int x)
{
  if(mark[x])
    return as[x];
  mark[x]=true;
  for(int i=0;i<ds[x].size();i++)
    as[x]+=dfss(ds[x][i]);
  return as[x];
}

ll dfst(int x)
{
  if(mark[x])
    return at[x];
  mark[x]=true;
  for(int i=0;i<dt[x].size();i++)
    at[x]+=dfst(dt[x][i]);
  return at[x];
}

int main()
{
  cin>>n>>m>>S>>T;
  for(int i=1;i<=n;diss[i]=dist[i]=inf,i++);
  for(int i=0;i<m;i++)
    {
      cin>>v[i]>>u[i]>>w[i];
      gs[v[i]].pb(u[i]);
      gt[u[i]].pb(v[i]);
      Ws[v[i]].pb(w[i]);
      wt[u[i]].pb(w[i]);
    }
  dijs();
  dijt();
  as[S]=1;
  dfss(T);
  for(int i=1;i<=n;mark[i]=false,i++);
  at[T]=1;
  dfst(S);
  for(int i=0;i<m;i++)
    {
      //YES
      if(at[S]==at[u[i]]*as[v[i]] && diss[v[i]]+dist[u[i]]+w[i]==diss[T])
	cout<<"YES"<<endl;
      //CAN x
      else if(diss[v[i]]+dist[u[i]]+1<diss[T])
	cout<<"CAN "<<(ll)(diss[v[i]]+dist[u[i]]+(ll)w[i]-diss[T]+1)<<endl;
      //NO
      else
	cout<<"NO"<<endl;
    }
  return 0;
}


//In the Name of God

#include<iostream>
#include<vector>
#include<set>
#define ll long long
#define mp make_pair
#define pb push_back

using namespace std;

const ll inf=100010000000010;
int n,m,v[100100],u[100100],w[100100],S,T,V,U,W;
ll diss[100100],dist[100100],as[100100],at[100100];
vector<int> gs[100100],gt[100100],Ws[100100],wt[100100],ds[100100],dt[100100];
set<pair<int,int> > s;
bool mark[100100];

void dijs()
{
  diss[S]=0;
  s.insert(mp(diss[S],S));
  while(s.size())
    {
      V=s.begin()->second;
      s.erase(s.begin());
      for(int i=0;i<gs[V].size();i++)
	{
	  U=gs[V][i];
	  W=Ws[V][i];
	  if(diss[U]==diss[V]+W)
	    ds[U].pb(V);
	  if(diss[U]>diss[V]+W)
	    {
	      ds[U].clear();
	      ds[U].pb(V);
	      s.erase(mp(diss[U],U));
	      diss[U]=diss[V]+W;
	      s.insert(mp(diss[U],U));
	    }
	}
    }
}

void dijt()
{
  dist[T]=0;
  s.insert(mp(dist[T],T));
  while(s.size())
    {
      V=s.begin()->second;
      s.erase(s.begin());
      for(int i=0;i<gt[V].size();i++)
	{
	  U=gt[V][i];
	  W=wt[V][i];
	  if(dist[U]==dist[V]+W)
	    dt[U].pb(V);
	  if(dist[U]>dist[V]+W)
	    {
	      dt[U].clear();
	      dt[U].pb(V);
	      s.erase(mp(dist[U],U));
	      dist[U]=dist[V]+W;
	      s.insert(mp(dist[U],U));
	    }
	}
    }
}

int dfss(int x)
{
  if(mark[x])
    return as[x];
  mark[x]=true;
  for(int i=0;i<ds[x].size();i++)
    as[x]+=dfss(ds[x][i]);
  return as[x];
}

int dfst(int x)
{
  if(mark[x])
    return at[x];
  mark[x]=true;
  for(int i=0;i<dt[x].size();i++)
    at[x]+=dfst(dt[x][i]);
  return at[x];
}

int main()
{
  cin>>n>>m>>S>>T;
  for(int i=1;i<=n;diss[i]=dist[i]=inf,i++);
  for(int i=0;i<m;i++)
    {
      cin>>v[i]>>u[i]>>w[i];
      gs[v[i]].pb(u[i]);
      gt[u[i]].pb(v[i]);
      Ws[v[i]].pb(w[i]);
      wt[u[i]].pb(w[i]);
    }
  dijs();
  dijt();
  as[S]=1;
  dfss(T);
  for(int i=1;i<=n;mark[i]=false,i++);
  at[T]=1;
  dfst(S);
  for(int i=0;i<m;i++)
    {
      //YES
      if(at[S]==at[u[i]]*as[v[i]] && diss[v[i]]+dist[u[i]]+w[i]==diss[T])
	cout<<"YES"<<endl;
      //CAN x
      else if(diss[v[i]]+dist[u[i]]+1<diss[T])
	cout<<"CAN "<<diss[v[i]]+dist[u[i]]+w[i]-diss[T]+1<<endl;
      //NO
      else
	cout<<"NO"<<endl;
    }
  return 0;
}


#include<cstdio>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
#include<map>
#include<set>
#include<string>
#include<iostream>
#include<functional>
#include<algorithm>

using namespace std;
typedef long long LL;
typedef pair<LL, int> PLI;

const int MX = 2e5 + 5;
const int INF = 0x3f3f3f3f;

LL d1[MX], d2[MX];
int Head[MX], Next[MX], rear;
int Low[MX], DFN[MX], dfs_clock;

struct Edge {
    int u, v, cost, sign;
} E[MX], S[MX];

void edge_init() {
    rear = 0;
    memset(Head, -1, sizeof(Head));
}

void edge_add(int u, int v, int cost, int sign = 0) {
    E[rear].u = u;
    E[rear].v = v;
    E[rear].sign = sign;
    E[rear].cost = cost;
    Next[rear] = Head[u];
    Head[u] = rear++;
}

void dijistra(int Begin, LL *d) {
    memset(d, INF, sizeof(LL)*MX);
    d[Begin] = 0;

    priority_queue<PLI, vector<PLI>, greater<PLI> >work;
    work.push(PLI(0, Begin));

    while(!work.empty()) {
        PLI f = work.top();
        work.pop();

        LL dist = f.first;
        int u = f.second;

        for(int id = Head[u]; ~id; id = Next[id]) {
            int cost = E[id].cost, v = E[id].v;
            if(dist + cost < d[v]) {
                d[v] = dist + cost;
                work.push(PLI(dist + cost, v));
            }
        }
    }
}

void tarjan_init() {
    dfs_clock = 0;
    memset(DFN, 0, sizeof(DFN));
}

int tarjan(int u, int from) {
    Low[u] = DFN[u] = ++dfs_clock;

    for(int id = Head[u]; ~id; id = Next[id]) {
        int v = E[id].v;

        if(!DFN[v]) {
            int lowv = tarjan(v, E[id].sign);
            Low[u] = min(Low[u], lowv);

            if(lowv > DFN[u]) {
                S[E[id].sign].sign = 1;
            }

        } else if(E[id].sign != from && DFN[v] < DFN[u]) {
            Low[u] = min(Low[u], DFN[v]);
        }
    }
    return Low[u];
}

int main() {
    //freopen("input.txt", "r", stdin);
    int n, m, s, t;
    scanf("%d%d%d%d", &n, &m, &s, &t);

    edge_init();
    for(int i = 1; i <= m; i++) {
        scanf("%d%d%d", &S[i].u, &S[i].v, &S[i].cost);
        edge_add(S[i].v, S[i].u, S[i].cost);
    }
    dijistra(t, d2);

    edge_init();
    for(int i = 1; i <= m; i++) {
        edge_add(S[i].u, S[i].v, S[i].cost);
    }
    dijistra(s, d1);

    edge_init();
    for(int i = 1; i <= m; i++) {
        if(d1[S[i].u] + S[i].cost == d1[S[i].v] && d2[S[i].v] + S[i].cost == d2[S[i].u]) {
            edge_add(S[i].u, S[i].v, S[i].cost, i);
            edge_add(S[i].v, S[i].u, S[i].cost, i);
        }
    }
    tarjan_init();
    tarjan(s, -1);
    /*for(int i=1;i<=n;i++){
        printf("[%d  %d:%d]\n",i,Low[i],DFN[i]);
    }*/

    for(int i = 1; i <= m; i++) {
        if(S[i].sign == 1) {
            printf("YES\n");
        } else {
            LL ans = d1[t] - d1[S[i].u] - d2[S[i].v] - 1;
            if(ans > 0) printf("CAN %d\n", S[i].cost - ans);
            else printf("NO\n");
        }
    }
    return 0;
}


#include<cstdio>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
#include<map>
#include<set>
#include<string>
#include<iostream>
#include<functional>
#include<algorithm>

using namespace std;
typedef long long LL;
typedef pair<LL, int> PII;

const int MX = 2e5 + 5;
const int INF = 0x3f3f3f3f;

LL d1[MX], d2[MX];
int Head[MX], Next[MX], rear;
int Low[MX], DFN[MX], dfs_clock;

struct Edge {
    int u, v, cost, sign;
} E[MX], S[MX];

void edge_init() {
    rear = 0;
    memset(Head, -1, sizeof(Head));
}

void edge_add(int u, int v, int cost, int sign = 0) {
    E[rear].u = u;
    E[rear].v = v;
    E[rear].sign = sign;
    E[rear].cost = cost;
    Next[rear] = Head[u];
    Head[u] = rear++;
}

void dijistra(int Begin, LL *d) {
    memset(d, INF, sizeof(LL)*MX);
    d[Begin] = 0;

    priority_queue<PII, vector<PII>, greater<PII> >work;
    work.push(PII(0, Begin));

    while(!work.empty()) {
        PII f = work.top();
        work.pop();

        LL dist = f.first;
        int u = f.second;

        for(int id = Head[u]; ~id; id = Next[id]) {
            int cost = E[id].cost, v = E[id].v;
            if(dist + cost < d[v]) {
                d[v] = dist + cost;
                work.push(PII(dist + cost, v));
            }
        }
    }
}

void tarjan_init() {
    dfs_clock = 0;
    memset(DFN, 0, sizeof(DFN));
}

int tarjan(int u, int from) {
    Low[u] = DFN[u] = ++dfs_clock;

    int child = 0;
    for(int id = Head[u]; ~id; id = Next[id]) {
        int v = E[id].v;

        if(!DFN[v]) {
            int lowv = tarjan(v, u);
            Low[u] = min(Low[u], lowv);

            if(lowv > DFN[u]) {
                S[E[id].sign].sign = 1;
            }

            child++;
        } else if(v != from) {
            Low[u] = min(Low[u], DFN[v]);
        }
    }
    return Low[u];
}

int main() {
    //freopen("input.txt", "r", stdin);
    int n, m, s, t;
    scanf("%d%d%d%d", &n, &m, &s, &t);

    edge_init();
    for(int i = 1; i <= m; i++) {
        scanf("%d%d%d", &S[i].u, &S[i].v, &S[i].cost);
        edge_add(S[i].v, S[i].u, S[i].cost);
    }
    dijistra(t, d2);

    edge_init();
    for(int i = 1; i <= m; i++) {
        edge_add(S[i].u, S[i].v, S[i].cost);
    }
    dijistra(s, d1);

    edge_init();
    for(int i = 1; i <= m; i++) {
        if(d1[S[i].u] + S[i].cost == d1[S[i].v] && d2[S[i].v] + S[i].cost == d2[S[i].u]) {
            edge_add(S[i].u, S[i].v, S[i].cost, i);
            edge_add(S[i].v, S[i].u, S[i].cost, i);
        }
    }
    tarjan_init();
    tarjan(s, -1);

    for(int i = 1; i <= m; i++) {
        if(S[i].sign) {
            printf("YES\n");
        } else {
            int ans = d1[t] - d1[S[i].u] - d2[S[i].v] - 1;
            if(ans > 0) printf("CAN %d\n", S[i].cost - ans);
            else printf("NO\n");
        }
    }
    return 0;
}


#include<cstdio>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
#include<map>
#include<set>
#include<string>
#include<iostream>
#include<functional>
#include<algorithm>

using namespace std;
typedef long long LL;
typedef pair<LL, int> PLI;

const int MX = 2e5 + 5;
const int INF = 0x3f3f3f3f;

LL d1[MX], d2[MX];
int Head[MX], Next[MX], rear;
int Low[MX], DFN[MX], dfs_clock;
map<PLI, int>R;

struct Edge {
    int u, v, cost, sign;
} E[MX], S[MX];

void edge_init() {
    rear = 0;
    memset(Head, -1, sizeof(Head));
}

void edge_add(int u, int v, int cost, int sign = 0) {
    E[rear].u = u;
    E[rear].v = v;
    E[rear].sign = sign;
    E[rear].cost = cost;
    Next[rear] = Head[u];
    Head[u] = rear++;
}

void dijistra(int Begin, LL *d) {
    memset(d, INF, sizeof(LL)*MX);
    d[Begin] = 0;

    priority_queue<PLI, vector<PLI>, greater<PLI> >work;
    work.push(PLI(0, Begin));

    while(!work.empty()) {
        PLI f = work.top();
        work.pop();

        LL dist = f.first;
        int u = f.second;

        for(int id = Head[u]; ~id; id = Next[id]) {
            int cost = E[id].cost, v = E[id].v;
            if(dist + cost < d[v]) {
                d[v] = dist + cost;
                work.push(PLI(dist + cost, v));
            }
        }
    }
}

void tarjan_init() {
    dfs_clock = 0;
    memset(DFN, 0, sizeof(DFN));
}

int tarjan(int u, int from) {
    Low[u] = DFN[u] = ++dfs_clock;

    int child = 0;
    for(int id = Head[u]; ~id; id = Next[id]) {
        int v = E[id].v;

        if(!DFN[v]) {
            int lowv = tarjan(v, u);
            Low[u] = min(Low[u], lowv);

            if(lowv > DFN[u]) {
                S[E[id].sign].sign = 1;
            }

            child++;
        } else if(v != from) {
            Low[u] = min(Low[u], DFN[v]);
        }
    }
    return Low[u];
}

int main() {
    //freopen("input.txt", "r", stdin);
    int n, m, s, t;
    scanf("%d%d%d%d", &n, &m, &s, &t);

    edge_init();
    for(int i = 1; i <= m; i++) {
        scanf("%d%d%d", &S[i].u, &S[i].v, &S[i].cost);
        edge_add(S[i].v, S[i].u, S[i].cost);
        R[PLI((LL)S[i].u * n + S[i].v, S[i].cost)]++;
    }
    dijistra(t, d2);

    edge_init();
    for(int i = 1; i <= m; i++) {
        edge_add(S[i].u, S[i].v, S[i].cost);
    }
    dijistra(s, d1);

    edge_init();
    for(int i = 1; i <= m; i++) {
        if(d1[S[i].u] + S[i].cost == d1[S[i].v] && d2[S[i].v] + S[i].cost == d2[S[i].u]) {
            edge_add(S[i].u, S[i].v, S[i].cost, i);
            edge_add(S[i].v, S[i].u, S[i].cost, i);
        }
    }
    tarjan_init();
    tarjan(s, -1);

    for(int i = 1; i <= m; i++) {
        if(S[i].sign && R[PLI((LL)S[i].u * n + S[i].v, S[i].cost)] == 1) {
            printf("YES\n");
        } else {
            int ans = d1[t] - d1[S[i].u] - d2[S[i].v] - 1;
            if(ans > 0) printf("CAN %d\n", S[i].cost - ans);
            else printf("NO\n");
        }
    }
    return 0;
}


#include<cstdio>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
#include<map>
#include<set>
#include<string>
#include<iostream>
#include<functional>
#include<algorithm>

using namespace std;
typedef long long LL;
typedef pair<LL, int> PLI;

const int MX = 2e5 + 5;
const int INF = 0x3f3f3f3f;

LL d1[MX], d2[MX];
int Head[MX], Next[MX], rear;
int Low[MX], DFN[MX], dfs_clock;
map<PLI, int>R;

struct Edge {
    int u, v, cost, sign;
} E[MX], S[MX];

void edge_init() {
    rear = 0;
    memset(Head, -1, sizeof(Head));
}

void edge_add(int u, int v, int cost, int sign = 0) {
    E[rear].u = u;
    E[rear].v = v;
    E[rear].sign = sign;
    E[rear].cost = cost;
    Next[rear] = Head[u];
    Head[u] = rear++;
}

void dijistra(int Begin, LL *d) {
    memset(d, INF, sizeof(LL)*MX);
    d[Begin] = 0;

    priority_queue<PLI, vector<PLI>, greater<PLI> >work;
    work.push(PLI(0, Begin));

    while(!work.empty()) {
        PLI f = work.top();
        work.pop();

        LL dist = f.first;
        int u = f.second;

        for(int id = Head[u]; ~id; id = Next[id]) {
            int cost = E[id].cost, v = E[id].v;
            if(dist + cost < d[v]) {
                d[v] = dist + cost;
                work.push(PLI(dist + cost, v));
            }
        }
    }
}

void tarjan_init() {
    dfs_clock = 0;
    memset(DFN, 0, sizeof(DFN));
}

int tarjan(int u, int from) {
    Low[u] = DFN[u] = ++dfs_clock;

    int child = 0;
    for(int id = Head[u]; ~id; id = Next[id]) {
        int v = E[id].v;

        if(!DFN[v]) {
            int lowv = tarjan(v, u);
            Low[u] = min(Low[u], lowv);

            if(lowv > DFN[u]) {
                S[E[id].sign].sign = 1;
            }

            child++;
        } else if(v != from) {
            Low[u] = min(Low[u], DFN[v]);
        }
    }
    return Low[u];
}

int main() {
    freopen("input.txt", "r", stdin);
    int n, m, s, t;
    scanf("%d%d%d%d", &n, &m, &s, &t);

    edge_init();
    for(int i = 1; i <= m; i++) {
        scanf("%d%d%d", &S[i].u, &S[i].v, &S[i].cost);
        edge_add(S[i].v, S[i].u, S[i].cost);
        R[PLI((LL)S[i].u * n + S[i].v, S[i].cost)]++;
    }
    dijistra(t, d2);

    edge_init();
    for(int i = 1; i <= m; i++) {
        edge_add(S[i].u, S[i].v, S[i].cost);
    }
    dijistra(s, d1);

    edge_init();
    for(int i = 1; i <= m; i++) {
        if(d1[S[i].u] + S[i].cost == d1[S[i].v] && d2[S[i].v] + S[i].cost == d2[S[i].u]) {
            edge_add(S[i].u, S[i].v, S[i].cost, i);
            edge_add(S[i].v, S[i].u, S[i].cost, i);
        }
    }
    tarjan_init();
    tarjan(s, -1);

    for(int i = 1; i <= m; i++) {
        if(S[i].sign && R[PLI((LL)S[i].u * n + S[i].v, S[i].cost)] == 1) {
            printf("YES\n");
        } else {
            LL ans = d1[t] - d1[S[i].u] - d2[S[i].v] - 1;
            if(ans > 0) printf("CAN %d\n", S[i].cost - ans);
            else printf("NO\n");
        }
    }
    return 0;
}


#include<cstdio>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
#include<map>
#include<set>
#include<string>
#include<iostream>
#include<functional>
#include<algorithm>

using namespace std;
typedef long long LL;
typedef pair<LL, int> PLI;

const int MX = 2e5 + 5;
const int INF = 0x3f3f3f3f;

LL d1[MX], d2[MX];
int Head[MX], Next[MX], rear;
int Low[MX], DFN[MX], dfs_clock;
map<PLI, int>R;

struct Edge {
    int u, v, cost, sign;
} E[MX], S[MX];

void edge_init() {
    rear = 0;
    memset(Head, -1, sizeof(Head));
}

void edge_add(int u, int v, int cost, int sign = 0) {
    E[rear].u = u;
    E[rear].v = v;
    E[rear].sign = sign;
    E[rear].cost = cost;
    Next[rear] = Head[u];
    Head[u] = rear++;
}

void dijistra(int Begin, LL *d) {
    memset(d, INF, sizeof(LL)*MX);
    d[Begin] = 0;

    priority_queue<PLI, vector<PLI>, greater<PLI> >work;
    work.push(PLI(0, Begin));

    while(!work.empty()) {
        PLI f = work.top();
        work.pop();

        LL dist = f.first;
        int u = f.second;

        for(int id = Head[u]; ~id; id = Next[id]) {
            int cost = E[id].cost, v = E[id].v;
            if(dist + cost < d[v]) {
                d[v] = dist + cost;
                work.push(PLI(dist + cost, v));
            }
        }
    }
}

void tarjan_init() {
    dfs_clock = 0;
    memset(DFN, 0, sizeof(DFN));
}

int tarjan(int u, int from) {
    Low[u] = DFN[u] = ++dfs_clock;

    int child = 0;
    for(int id = Head[u]; ~id; id = Next[id]) {
        int v = E[id].v;

        if(!DFN[v]) {
            int lowv = tarjan(v, u);
            Low[u] = min(Low[u], lowv);

            if(lowv > DFN[u]) {
                S[E[id].sign].sign = 1;
            }

            child++;
        } else if(v != from) {
            Low[u] = min(Low[u], DFN[v]);
        }
    }
    return Low[u];
}

int main() {
    //freopen("input.txt", "r", stdin);
    int n, m, s, t;
    scanf("%d%d%d%d", &n, &m, &s, &t);

    edge_init();
    for(int i = 1; i <= m; i++) {
        scanf("%d%d%d", &S[i].u, &S[i].v, &S[i].cost);
        edge_add(S[i].v, S[i].u, S[i].cost);
        R[PLI((LL)S[i].u * n + S[i].v, S[i].cost)]++;
    }
    dijistra(t, d2);

    edge_init();
    for(int i = 1; i <= m; i++) {
        edge_add(S[i].u, S[i].v, S[i].cost);
    }
    dijistra(s, d1);

    edge_init();
    for(int i = 1; i <= m; i++) {
        if(d1[S[i].u] + S[i].cost == d1[S[i].v] && d2[S[i].v] + S[i].cost == d2[S[i].u]) {
            edge_add(S[i].u, S[i].v, S[i].cost, i);
            edge_add(S[i].v, S[i].u, S[i].cost, i);
        }
    }
    tarjan_init();
    tarjan(s, -1);

    for(int i = 1; i <= m; i++) {
        if(S[i].sign && R[PLI((LL)S[i].u * n + S[i].v, S[i].cost)] == 1) {
            printf("YES\n");
        } else {
            LL ans = d1[t] - d1[S[i].u] - d2[S[i].v] - 1;
            if(ans > 0) printf("CAN %d\n", S[i].cost - ans);
            else printf("NO\n");
        }
    }
    return 0;
}


#include<cstdio>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
#include<map>
#include<set>
#include<string>
#include<iostream>
#include<functional>
#include<algorithm>

using namespace std;
typedef long long LL;
typedef pair<int, int> PII;

const int MX = 2e5 + 5;
const int INF = 0x3f3f3f3f;

LL d1[MX], d2[MX];
int Head[MX], Next[MX], rear;
int Low[MX], DFN[MX], dfs_clock;

struct Edge {
    int u, v, cost, sign;
} E[MX], S[MX];

void edge_init() {
    rear = 0;
    memset(Head, -1, sizeof(Head));
}

void edge_add(int u, int v, int cost, int sign = 0) {
    E[rear].u = u;
    E[rear].v = v;
    E[rear].sign = sign;
    E[rear].cost = cost;
    Next[rear] = Head[u];
    Head[u] = rear++;
}

void dijistra(int Begin, LL *d) {
    memset(d, INF, sizeof(LL)*MX);
    d[Begin] = 0;

    priority_queue<PII, vector<PII>, greater<PII> >work;
    work.push(PII(0, Begin));

    while(!work.empty()) {
        PII f = work.top();
        work.pop();

        LL dist = f.first;
        int u = f.second;

        for(int id = Head[u]; ~id; id = Next[id]) {
            int cost = E[id].cost, v = E[id].v;
            if(dist + cost < d[v]) {
                d[v] = dist + cost;
                work.push(PII(dist + cost, v));
            }
        }
    }
}

void tarjan_init() {
    dfs_clock = 0;
    memset(DFN, 0, sizeof(DFN));
}

int tarjan(int u, int from) {
    Low[u] = DFN[u] = ++dfs_clock;

    int child = 0;
    for(int id = Head[u]; ~id; id = Next[id]) {
        int v = E[id].v;

        if(!DFN[v]) {
            int lowv = tarjan(v, u);
            Low[u] = min(Low[u], lowv);

            if(lowv > DFN[u]) {
                S[E[id].sign].sign = 1;
            }

            child++;
        } else if(v != from) {
            Low[u] = min(Low[u], DFN[v]);
        }
    }
    return Low[u];
}

int main() {
    //freopen("input.txt", "r", stdin);
    int n, m, s, t;
    scanf("%d%d%d%d", &n, &m, &s, &t);

    edge_init();
    for(int i = 1; i <= m; i++) {
        scanf("%d%d%d", &S[i].u, &S[i].v, &S[i].cost);
        edge_add(S[i].v, S[i].u, S[i].cost);
    }
    dijistra(t, d2);

    edge_init();
    for(int i = 1; i <= m; i++) {
        edge_add(S[i].u, S[i].v, S[i].cost);
    }
    dijistra(s, d1);

    edge_init();
    for(int i = 1; i <= m; i++) {
        if(d1[S[i].u] + S[i].cost == d1[S[i].v] && d2[S[i].v] + S[i].cost == d2[S[i].u]) {
            edge_add(S[i].u, S[i].v, S[i].cost, i);
            edge_add(S[i].v, S[i].u, S[i].cost, i);
        }
    }
    tarjan_init();
    tarjan(s, -1);

    for(int i = 1; i <= m; i++) {
        if(S[i].sign) {
            printf("YES\n");
        } else {
            int ans = d1[t] - d1[S[i].u] - d2[S[i].v] - 1;
            if(ans > 0) printf("CAN %d\n", S[i].cost - ans);
            else printf("NO\n");
        }
    }
    return 0;
}


#include<cstdio>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
#include<map>
#include<set>
#include<string>
#include<iostream>
#include<functional>
#include<algorithm>

using namespace std;
typedef long long LL;
typedef pair<LL, int> PLI;
typedef pair<int, int> PII;

const int MX = 2e5 + 5;
const int INF = 0x3f3f3f3f;

LL d1[MX], d2[MX];
int Head[MX], Next[MX], rear;
int Low[MX], DFN[MX], dfs_clock;
map<PII, int>R;

struct Edge {
    int u, v, cost, sign;
} E[MX], S[MX];

void edge_init() {
    rear = 0;
    memset(Head, -1, sizeof(Head));
}

void edge_add(int u, int v, int cost, int sign = 0) {
    E[rear].u = u;
    E[rear].v = v;
    E[rear].sign = sign;
    E[rear].cost = cost;
    Next[rear] = Head[u];
    Head[u] = rear++;
}

void dijistra(int Begin, LL *d) {
    memset(d, INF, sizeof(LL)*MX);
    d[Begin] = 0;

    priority_queue<PLI, vector<PLI>, greater<PLI> >work;
    work.push(PLI(0, Begin));

    while(!work.empty()) {
        PLI f = work.top();
        work.pop();

        LL dist = f.first;
        int u = f.second;

        for(int id = Head[u]; ~id; id = Next[id]) {
            int cost = E[id].cost, v = E[id].v;
            if(dist + cost < d[v]) {
                d[v] = dist + cost;
                work.push(PLI(dist + cost, v));
            }
        }
    }
}

void tarjan_init() {
    dfs_clock = 0;
    memset(DFN, 0, sizeof(DFN));
}

int tarjan(int u, int from) {
    Low[u] = DFN[u] = ++dfs_clock;

    int child = 0;
    for(int id = Head[u]; ~id; id = Next[id]) {
        int v = E[id].v;

        if(!DFN[v]) {
            int lowv = tarjan(v, u);
            Low[u] = min(Low[u], lowv);

            if(lowv > DFN[u]) {
                S[E[id].sign].sign = 1;
            }

            child++;
        } else if(v != from) {
            Low[u] = min(Low[u], DFN[v]);
        }
    }
    return Low[u];
}

int main() {
    //freopen("input.txt", "r", stdin);
    int n, m, s, t;
    scanf("%d%d%d%d", &n, &m, &s, &t);

    edge_init();
    for(int i = 1; i <= m; i++) {
        scanf("%d%d%d", &S[i].u, &S[i].v, &S[i].cost);
        edge_add(S[i].v, S[i].u, S[i].cost);
        R[PII(S[i].u, S[i].v)]++;
    }
    dijistra(t, d2);

    edge_init();
    for(int i = 1; i <= m; i++) {
        edge_add(S[i].u, S[i].v, S[i].cost);
    }
    dijistra(s, d1);

    edge_init();
    for(int i = 1; i <= m; i++) {
        if(d1[S[i].u] + S[i].cost == d1[S[i].v] && d2[S[i].v] + S[i].cost == d2[S[i].u]) {
            edge_add(S[i].u, S[i].v, S[i].cost, i);
            edge_add(S[i].v, S[i].u, S[i].cost, i);
        }
    }
    tarjan_init();
    tarjan(s, -1);

    for(int i = 1; i <= m; i++) {
        if(S[i].sign && R[PII(S[i].u, S[i].v)] == 1) {
            printf("YES\n");
        } else {
            int ans = d1[t] - d1[S[i].u] - d2[S[i].v] - 1;
            if(ans > 0) printf("CAN %d\n", S[i].cost - ans);
            else printf("NO\n");
        }
    }
    return 0;
}


#include<cstdio>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
#include<map>
#include<set>
#include<string>
#include<iostream>
#include<functional>
#include<algorithm>

using namespace std;
typedef long long LL;
typedef pair<LL, int> PLI;

const int MX = 2e5 + 5;
const int INF = 0x3f3f3f3f;

LL d1[MX], d2[MX];
int Head[MX], Next[MX], rear;
int Low[MX], DFN[MX], dfs_clock;

struct Edge {
    int u, v, cost, sign;
} E[MX], S[MX];

void edge_init() {
    rear = 0;
    memset(Head, -1, sizeof(Head));
}

void edge_add(int u, int v, int cost, int sign = 0) {
    E[rear].u = u;
    E[rear].v = v;
    E[rear].sign = sign;
    E[rear].cost = cost;
    Next[rear] = Head[u];
    Head[u] = rear++;
}

void dijistra(int Begin, LL *d) {
    memset(d, INF, sizeof(LL)*MX);
    d[Begin] = 0;

    priority_queue<PLI, vector<PLI>, greater<PLI> >work;
    work.push(PLI(0, Begin));

    while(!work.empty()) {
        PLI f = work.top();
        work.pop();

        LL dist = f.first;
        int u = f.second;

        for(int id = Head[u]; ~id; id = Next[id]) {
            int cost = E[id].cost, v = E[id].v;
            if(dist + cost < d[v]) {
                d[v] = dist + cost;
                work.push(PLI(dist + cost, v));
            }
        }
    }
}

void tarjan_init() {
    dfs_clock = 0;
    memset(DFN, 0, sizeof(DFN));
}

int tarjan(int u, int from) {
    Low[u] = DFN[u] = ++dfs_clock;

    for(int id = Head[u]; ~id; id = Next[id]) {
        int v = E[id].v;

        if(!DFN[v]) {
            int lowv = tarjan(v, E[u].sign);
            Low[u] = min(Low[u], lowv);

            if(lowv > DFN[u]) {
                S[E[id].sign].sign = 1;
            }

        } else if(E[u].sign != from && DFN[v] < DFN[u]) {
            Low[u] = min(Low[u], DFN[v]);
        }
    }
    return Low[u];
}

int main() {
    //freopen("input.txt", "r", stdin);
    int n, m, s, t;
    scanf("%d%d%d%d", &n, &m, &s, &t);

    edge_init();
    for(int i = 1; i <= m; i++) {
        scanf("%d%d%d", &S[i].u, &S[i].v, &S[i].cost);
        edge_add(S[i].v, S[i].u, S[i].cost);
    }
    dijistra(t, d2);

    edge_init();
    for(int i = 1; i <= m; i++) {
        edge_add(S[i].u, S[i].v, S[i].cost);
    }
    dijistra(s, d1);

    edge_init();
    for(int i = 1; i <= m; i++) {
        if(d1[S[i].u] + S[i].cost == d1[S[i].v] && d2[S[i].v] + S[i].cost == d2[S[i].u]) {
            edge_add(S[i].u, S[i].v, S[i].cost, i);
            edge_add(S[i].v, S[i].u, S[i].cost, i);
        }
    }
    tarjan_init();
    tarjan(s, -1);

    for(int i = 1; i <= m; i++) {
        if(S[i].sign == 1) {
            printf("YES\n");
        } else {
            LL ans = d1[t] - d1[S[i].u] - d2[S[i].v] - 1;
            if(ans > 0) printf("CAN %d\n", S[i].cost - ans);
            else printf("NO\n");
        }
    }
    return 0;
}


#include<cstdio>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
#include<map>
#include<set>
#include<string>
#include<iostream>
#include<functional>
#include<algorithm>

using namespace std;
typedef long long LL;
typedef pair<int, int> PII;

const int MX = 2e5 + 5;
const int INF = 0x3f3f3f3f;

LL d1[MX], d2[MX];
int Head[MX], Next[MX], rear;
int Low[MX], DFN[MX], dfs_clock;

struct Edge {
    int u, v, cost, sign;
} E[MX], S[MX];

void edge_init() {
    rear = 0;
    memset(Head, -1, sizeof(Head));
}

void edge_add(int u, int v, int cost, int sign = 0) {
    E[rear].u = u;
    E[rear].v = v;
    E[rear].sign = sign;
    E[rear].cost = cost;
    Next[rear] = Head[u];
    Head[u] = rear++;
}

void dijistra(int Begin, LL *d) {
    memset(d, INF, sizeof(LL)*MX);
    d[Begin] = 0;

    priority_queue<PII, vector<PII>, greater<PII> >work;
    work.push(PII(0, Begin));

    while(!work.empty()) {
        PII f = work.top();
        work.pop();

        int dist = f.first, u = f.second;

        for(int id = Head[u]; ~id; id = Next[id]) {
            int cost = E[id].cost, v = E[id].v;
            if(dist + cost < d[v]) {
                d[v] = dist + cost;
                work.push(PII(dist + cost, v));
            }
        }
    }
}

void tarjan_init() {
    dfs_clock = 0;
    memset(DFN, 0, sizeof(DFN));
}

int tarjan(int u, int from) {
    Low[u] = DFN[u] = ++dfs_clock;

    int child = 0;
    for(int id = Head[u]; ~id; id = Next[id]) {
        int v = E[id].v;

        if(!DFN[v]) {
            int lowv = tarjan(v, u);
            Low[u] = min(Low[u], lowv);

            if(lowv > DFN[u]) {
                S[E[id].sign].sign = 1;
            }

            child++;
        } else if(v != from) {
            Low[u] = min(Low[u], DFN[v]);
        }
    }
    return Low[u];
}

int main() {
    //freopen("input.txt", "r", stdin);
    int n, m, s, t;
    scanf("%d%d%d%d", &n, &m, &s, &t);

    edge_init();
    for(int i = 1; i <= m; i++) {
        scanf("%d%d%d", &S[i].u, &S[i].v, &S[i].cost);
        edge_add(S[i].v, S[i].u, S[i].cost);
    }
    dijistra(t, d2);

    edge_init();
    for(int i = 1; i <= m; i++) {
        edge_add(S[i].u, S[i].v, S[i].cost);
    }
    dijistra(s, d1);

    edge_init();
    for(int i = 1; i <= m; i++) {
        if(d1[S[i].u] + S[i].cost == d1[S[i].v] && d2[S[i].v] + S[i].cost == d2[S[i].u]) {
            edge_add(S[i].u, S[i].v, S[i].cost, i);
            edge_add(S[i].v, S[i].u, S[i].cost, i);
        }
    }
    tarjan_init();
    tarjan(s, -1);

    for(int i = 1; i <= m; i++) {
        if(S[i].sign) {
            printf("YES\n");
        } else {
            int ans = d1[t] - d1[S[i].u] - d2[S[i].v] - 1;
            if(ans > 0) printf("CAN %d\n", S[i].cost - ans);
            else printf("NO\n");
        }
    }
    return 0;
}


#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<string>
#include<cstdio>
#include<vector>
#include<map>
#include<set>
#include<queue>
#define pb push_back
#define debug puts("=====================");
#define INF (1ll << 60)
#define pil pair<ll, int>
using namespace std;
typedef long long ll;
const int N = 1e5 + 100;
int n, m, s, t, ans[N];
struct node {
    int u, v, nxt, l;
} e[N], re[N];
int g[N], rg[N], cnt, rcnt;
void add(int u, int v, int l, int &cnt, int * g, node * e) {
    e[++cnt].u = u;
    e[cnt].v = v;
    e[cnt].l = l;
    e[cnt].nxt = g[u];
    g[u] = cnt;
}
ll dist[N], rdist[N];
priority_queue< pil, vector<pil>, greater<pil> > q;
void dijkstra(int st, int ed, ll * dist, int * g, node *e) {
    q.push({0, st});
    for (int i = 1; i <= n; i++) dist[i] = INF;
    dist[st] = 0;
    int u, v, l;
    while(!q.empty()) {
        ll w = q.top().first;
        int u = q.top().second;
        q.pop();
        if (dist[u] < w) continue;
        for (int i = g[u]; i; i = e[i].nxt) {
            v = e[i].v, l = e[i].l;
            if (dist[u] + l < dist[v]) {
                dist[v] = dist[u] + l;
                q.push({dist[v], v});
            }
        }
    }
    //for (int i = 1; i <= n; i++) cout<<dist[i]<<endl;
}
node E[N * 2];
int G[N], cc = 1;
void init_add(int u, int v, int id) {
    E[++cc].u = u;
    E[cc].v = v;
    E[cc].l = id;
    E[cc].nxt = G[u];
    G[u] = cc;

    E[++cc].u = v;
    E[cc].v = u;
    E[cc].l = id;
    E[cc].nxt = G[v];
    G[v] = cc;
}
void init_graph() {
    int u, v, l;
    for (int i = 1; i <= m; i++) {
        u = e[i].u, v = e[i].v, l = e[i].l;
        if (dist[u] + l + rdist[v] == dist[t]) init_add(u, v, i); //, cout<<i<<endl;
    }
    //for (int i = 1; i <= cc; i++) cout<<E[i].u<<" "<<E[i].v<<" "<<E[i].l<<endl;
}

int dfs_clock = 0, dfn[N] = {0}, low[N] = {0};
bool VIS[N * 2] = {0};
void dfs(int u) {
    dfn[u] = low[u] = ++dfs_clock;
    for (int i = G[u]; i; i = E[i].nxt) {
        int v = E[i].v;
        if (!dfn[v]) {
            VIS[i] = VIS[i ^ 1] = true;
            dfs(v);
            low[u] = min(low[v], low[u]);
            if (low[v] > dfn[u]) ans[E[i].l] = -1;
        } else if (dfn[v] < dfn[u] && !VIS[i]) {
            VIS[i] = VIS[i ^ 1] = true;
            low[u] = min(low[u], dfn[v]);
        }
    }
}

void work_yes() {
    for (int i = 1; i <= n; i++) if (!dfn[i]) dfs(i);
}
int main () {
    scanf("%d%d%d%d", &n, &m, &s, &t);
    int u, v, l;
    for (int i = 0; i < m; i++) {
        scanf("%d%d%d", &u, &v, &l);
        add(u, v, l, cnt, g, e);
        add(v, u, l, rcnt, rg, re);
    }
    //for (int i = 1; i <= m; i++) cout<<e[i].u<<" "<<e[i].v<<" "<<e[i].l<<endl;
    //for (int i = 1; i <= m; i++) cout<<re[i].u<<" "<<re[i].v<<" "<<re[i].l<<endl;
    dijkstra(s, t, dist, g, e);
    dijkstra(t, s, rdist, rg, re);
    init_graph();
    work_yes();
    for (int i = 1; i <= m; i++) {
        if (ans[i] == -1) puts("YES");
        else {
            u = e[i].u, v = e[i].v, l = e[i].l;
            ll tmp = dist[t] - 1 - dist[u] - rdist[v];
            if (0 < tmp && tmp < l) printf("CAN %d\n", l - tmp);
            else puts("NO");
        }
    }
    return 0;
}


#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<string>
#include<cstdio>
#include<vector>
#include<map>
#include<set>
#include<queue>
#define pb push_back
#define debug puts("=====================");
#define INF (1 << 30)
using namespace std;
const int N = 1e5 + 100;
int n, m, s, t, ans[N];
struct node {
    int u, v, nxt, l;
} e[N], re[N];
int g[N], rg[N], cnt, rcnt;
void add(int u, int v, int l, int &cnt, int * g, node * e) {
    e[++cnt].u = u;
    e[cnt].v = v;
    e[cnt].l = l;
    e[cnt].nxt = g[u];
    g[u] = cnt;
}
int dist[N], rdist[N], vis[N];
queue<int> q;
void spfa(int st, int ed, int * dist, int * g, node *e) {
    memset(vis, 0, sizeof(int) * (n + 10));
    vis[st] = 1;
    q.push(st);
    for (int i = 1; i <= n; i++) dist[i] = INF;
    dist[st] = 0;
    int u, v, l;
    while(!q.empty()) {
        u = q.front(); q.pop();
        vis[u] = 0;
        for (int i = g[u]; i; i = e[i].nxt) {
            v = e[i].v, l = e[i].l;
            if (dist[u] + l < dist[v]) {
                dist[v] = dist[u] + l;
                if (!vis[v]) vis[v] = 1, q.push(v);
            }
        }
    }
}
node E[N * 2];
int G[N], cc = 1;
void init_add(int u, int v, int id) {
    E[++cc].u = u;
    E[cc].v = v;
    E[cc].l = id;
    E[cc].nxt = G[u];
    G[u] = cc;

    E[++cc].u = v;
    E[cc].v = u;
    E[cc].l = id;
    E[cc].nxt = G[v];
    G[v] = cc;
}
void init_graph() {
    int u, v, l;
    for (int i = 1; i <= m; i++) {
        u = e[i].u, v = e[i].v, l = e[i].l;
        if (dist[u] + l + rdist[v] == dist[t]) init_add(u, v, i); //, cout<<i<<endl;
    }
    //for (int i = 1; i <= cc; i++) cout<<E[i].u<<" "<<E[i].v<<" "<<E[i].l<<endl;
}

int dfs_clock = 0, dfn[N] = {0}, low[N] = {0};
bool VIS[N * 2] = {0};
void dfs(int u) {
    dfn[u] = low[u] = ++dfs_clock;
    for (int i = G[u]; i; i = E[i].nxt) {
        int v = E[i].v;
        if (!dfn[v]) {
            VIS[i] = VIS[i ^ 1] = true;
            dfs(v);
            low[u] = min(low[v], low[u]);
            if (low[v] > dfn[u]) ans[E[i].l] = -1;
        } else if (dfn[v] < dfn[u] && !VIS[i]) {
            VIS[i] = VIS[i ^ 1] = true;
            low[u] = min(low[u], dfn[v]);
        }
    }
}

void work_yes() {
    for (int i = 1; i <= n; i++) if (!dfn[i]) dfs(i);
}
int main () {
    scanf("%d%d%d%d", &n, &m, &s, &t);
    int u, v, l;
    for (int i = 0; i < m; i++) {
        scanf("%d%d%d", &u, &v, &l);
        add(u, v, l, cnt, g, e);
        add(v, u, l, rcnt, rg, re);
    }
    //for (int i = 1; i <= m; i++) cout<<e[i].u<<" "<<e[i].v<<" "<<e[i].l<<endl;
    //for (int i = 1; i <= m; i++) cout<<re[i].u<<" "<<re[i].v<<" "<<re[i].l<<endl;
    spfa(s, t, dist, g, e);
    spfa(t, s, rdist, rg, re);
    init_graph();
    work_yes();
    for (int i = 1; i <= m; i++) {
        if (ans[i] == -1) puts("YES");
        else {
            u = e[i].u, v = e[i].v, l = e[i].l;
            int tmp = dist[t] - 1 - dist[u] - rdist[v];
            if (0 < tmp && tmp < l) printf("CAN %d\n", l - tmp);
            else puts("NO");
        }
    }
    return 0;
}


#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<string>
#include<cstdio>
#include<vector>
#include<map>
#include<set>
#include<queue>
#define pb push_back
#define debug puts("=====================");
#define INF (1ll << 60)
#define pil pair<ll, int>
using namespace std;
typedef long long ll;
const int N = 1e5 + 100;
int n, m, s, t, ans[N];
const int NMOD = 2;
const int mod[] = {1e9 + 2277, 1e9 + 5277, 1e9 + 8277, 1e9 + 9277};
struct Hash {
    int val[NMOD];
    Hash () {
        memset(val, 0, sizeof(val));
    }
    Hash (int x) {
        for (int i = 0; i < n; i++) val[i] = x;
    }
    void operator += (const Hash &x) {
        for (int i = 0; i < NMOD; i++) {
            val[i] += x.val[i];
            if (val[i] >= mod[i]) val[i] -= mod[i];
        }
    }
    Hash operator * (const Hash &x) {
        Hash res;
        for (int i = 0; i < NMOD; i++) res.val[i] = 1ll * val[i] * x.val[i] % mod[i];
        return res;
    }
    bool operator == (const Hash &x) {
        for (int i = 0; i < NMOD; i++) if (val[i] != x.val[i]) return false;
        return true;
    }
};
struct node {
    int u, v, nxt, l;
} e[N], re[N];
int g[N], rg[N], cnt, rcnt;
void add(int u, int v, int l, int &cnt, int * g, node * e) {
    e[++cnt].u = u;
    e[cnt].v = v;
    e[cnt].l = l;
    e[cnt].nxt = g[u];
    g[u] = cnt;
}
ll dist[N], rdist[N];
Hash cnts[N], cntt[N];
priority_queue< pil, vector<pil>, greater<pil> > q;
void dijkstra(int st, int ed, ll * dist, int * g, node *e, Hash *cnt) {
    cnt[st] = 1;
    q.push({0, st});
    for (int i = 1; i <= n; i++) dist[i] = INF;
    dist[st] = 0;
    int u, v, l;
    while(!q.empty()) {
        ll w = q.top().first;
        int u = q.top().second;
        q.pop();
        if (dist[u] < w) continue;
        for (int i = g[u]; i; i = e[i].nxt) {
            v = e[i].v, l = e[i].l;
            if (dist[u] + l < dist[v]) {
                dist[v] = dist[u] + l;
                cnt[v] = cnt[u];
                q.push({dist[v], v});
            } else if (dist[u] + l == dist[v]) {
                cnt[v] += cnt[u];
            }
        }
    }
}
int main () {
    scanf("%d%d%d%d", &n, &m, &s, &t);
    int u, v, l;
    for (int i = 0; i < m; i++) {
        scanf("%d%d%d", &u, &v, &l);
        add(u, v, l, cnt, g, e);
        add(v, u, l, rcnt, rg, re);
    }
    dijkstra(s, t, dist, g, e, cnts);
    dijkstra(t, s, rdist, rg, re, cntt);
    for (int i = 1; i <= m; i++) {
        u = e[i].u, v = e[i].v, l = e[i].l;
        if (dist[u] + rdist[v] + l == dist[t] && cnts[u] * cntt[v] == cnts[t]) puts("YES");
        else {
            ll tmp = dist[t] - 1 - dist[u] - rdist[v];
            if (0 < tmp && tmp < l) printf("CAN %d\n", l - tmp);
            else puts("NO");
        }
    }
    return 0;
}