#include<time.h>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<stack>
#include<queue>
#include<set>
#include<map>
#include<string>
#include<math.h>
#include<cctype>
#define ll long long
#define REP(i,a,b) for(int (i)=(a);(i)<=(b);(i)++)
#define REPP(i,a,b,t) for(int (i)=(a);(i)<=(b);(i)+=(t))
#define rep(i,a,b) for(int (i)=(a);(i)>=(b);(i)--)
#define repp(i,a,b,t) for(int (i)=(a);(i)>=(b);(i)-=(t))
#define PII pair<int,int>
#define fst first
#define snd second
#define MP make_pair
#define PB push_back
#define RI(x) scanf("%d",&(x))
#define RII(x,y) scanf("%d%d",&(x),&(y))
#define RIII(x,y,z) scanf("%d%d%d",&(x),&(y),&(z))
#define DRI(x) int (x);scanf("%d",&(x))
#define DRII(x,y) int (x),(y);scanf("%d%d",&(x),&(y))
#define DRIII(x,y,z) int (x),(y),(z);scanf("%d%d%d",&(x),&(y),&(z))
#define RS(x) scanf("%s",x)
#define RSS(x,y) scanf("%s%s",x,y)
#define DRS(x) char x[maxn];scanf("%s",x)
#define DRSS(x,y) char x[maxn],y[maxn];scanf("%s%s",x,y)
#define MS0(a) memset((a),0,sizeof((a)))
#define MS1(a) memset((a),-1,sizeof((a)))
#define MS(a,b) memset((a),(b),sizeof((a)))
#define ALL(v) v.begin(),v.end()
#define SZ(v) (int)(v).size()
using namespace std;
const int MAXN=200000;
const int MAXM=200000;
__int64 INF=(1LL<<60);
struct Edge{
int u,v;
__int64 w;
int i;
}e[MAXM];
struct Node{
int v;
__int64 w;
bool operator <(const Node &r)const
{
return w>r.w;
}
};
vector<Node> g[2][MAXN];
vector<Edge> G[MAXN];
bool in[MAXM];
bool vis[MAXN];
int n,m,s,t,u,v,index;
int dfn[MAXN];
__int64 d[2][MAXN],ddd,w;
void dijkstra(int flag)
{
int a=flag?t:s;
memset(vis,0,sizeof(vis));
for(int i=0;i<=MAXN;i++)
d[flag][i]=INF;
priority_queue<Node> q;
d[flag][a]=0;
q.push({a,0});
Node temp;
while(!q.empty())
{
temp=q.top();
q.pop();
int u=temp.v;
if(vis[u])continue;
vis[u]=true;
for(int i=0;i<g[flag][u].size();i++)
{
int v=g[flag][u][i].v;
__int64 w=g[flag][u][i].w;
if(!vis[v]&&d[flag][v]>d[flag][u]+w)
{
d[flag][v]=d[flag][u]+w;
q.push({v,d[flag][v]});
}
}
}
}
int Targan(int u,int la)
{
int lowu=dfn[u]=++index;
for(int i=0;i<G[u].size();i++)
{
Edge en=G[u][i];
if(dfn[en.v]==-1)
{
int lowv=Targan(en.v,en.i);
lowu=min(lowu,lowv);
if(lowv>dfn[u])
{
in[en.i]=true;
}
}
else if(dfn[en.v]<dfn[en.u]&&en.i!=la)
lowu=min(lowu,dfn[en.v]);
}
return lowu;
}
int main()
{
//freopen("in.txt","r",stdin);
scanf("%d%d%d%d",&n,&m,&s,&t);
for(int i=0;i<m;i++)
{
scanf("%d%d%I64d",&u,&v,&w);
e[i]={u,v,w,i};
g[0][u].push_back({v,w});
g[1][v].push_back({u,w});
}
dijkstra(0);
dijkstra(1);
ddd=d[0][t];
for(int i=0;i<m;i++)
{
Edge en=e[i];
if(d[0][en.u]+en.w==d[0][en.v]&&d[1][en.v]+en.w==d[1][en.u])
{
G[en.u].push_back({en.u,en.v,en.w,i});
G[en.v].push_back({en.v,en.u,en.w,i});
}
}
for(int i=0;i<=n;i++)
dfn[i]=-1;
Targan(s,-1);
for(int i=0;i<m;i++)
{
if(ddd==INF)
{
printf("NO\n");
continue;
}
if(in[i])
printf("YES\n");
else
{
__int64 aa=d[0][e[i].u]+d[1][e[i].v]+e[i].w-ddd+1;
if(aa<e[i].w)
printf("CAN %I64d\n",aa);
else
printf("NO\n");
}
}
return 0;
}