#include <bits/stdc++.h>
using namespace std;
const int M = 100100, N = 100010;
int n;
int m;
int s;
int t;
int head[2][N];
long long dis[2][N];
int vis[N];
int cnt;
int dfn[N], low[N];
int indx;
int fa[N];
struct Edge {
  int from;
  int to;
  int cap;
  int next;
  int id;
} edge[2 * M];
struct Road {
  int u, v, w;
  int flag;
  long long ans;
} road[M];
struct HeapNode {
  long long dis;
  int id;
  bool operator<(const HeapNode &A) const { return dis > A.dis; }
};
void init();
void addEdge(int u, int v, int w, int ii, int flag);
void Dijstra(int s, int flag, int n);
void Reduce(int m, int t);
void tarjan(int u);
void output(int m);
int main() {
  scanf("%d %d %d %d", &n, &m, &s, &t);
  init();
  for (int i = 0; i < m; i++) {
    scanf("%d %d %d", &road[i].u, &road[i].v, &road[i].w);
    addEdge(road[i].u, road[i].v, road[i].w, i, 0);
    addEdge(road[i].v, road[i].u, road[i].w, i, 1);
  }
  Dijstra(s, 0, n);
  Dijstra(t, 1, n);
  Reduce(m, t);
  memset(dfn, -1, sizeof(dfn));
  memset(low, 0, sizeof(low));
  indx = 0;
  tarjan(s);
  output(m);
  return 0;
}
void init() {
  cnt = 0;
  memset(head, -1, sizeof(head));
}
void Dijstra(int s, int flag, int n) {
  priority_queue<HeapNode> Q;
  for (int i = 1; i <= n; i++) {
    dis[flag][i] = 100000000000100;
    vis[i] = 0;
  }
  dis[flag][s] = 0;
  Q.push((HeapNode){0, s});
  while (!Q.empty()) {
    HeapNode k = Q.top();
    Q.pop();
    int u = k.id;
    if (vis[u]) continue;
    vis[u] = 1;
    for (int i = head[flag][u]; i != -1; i = edge[i].next) {
      int v = edge[i].to;
      if (dis[flag][u] + edge[i].cap < dis[flag][v]) {
        dis[flag][v] = dis[flag][u] + edge[i].cap;
        Q.push((HeapNode){dis[flag][v], v});
      }
    }
  }
}
void Reduce(int m, int t) {
  long long mincost = dis[0][t];
  cnt = 0;
  memset(head, -1, sizeof(head));
  for (int i = 0; i < m; i++) {
    int u = road[i].u, v = road[i].v;
    if (dis[0][u] == 100000000000100 || dis[1][v] == 100000000000100) {
      road[i].flag = -2;
      continue;
    }
    if (dis[0][u] + dis[1][v] + (long long)road[i].w > mincost) {
      road[i].flag = -1;
      road[i].ans =
          (long long)road[i].w + 1 - (mincost - dis[0][u] - dis[1][v]);
    } else if (dis[0][u] + dis[1][v] + (long long)road[i].w == mincost) {
      addEdge(u, v, road[i].w, i, 0);
      addEdge(v, u, road[i].w, i, 0);
    }
  }
}
void addEdge(int u, int v, int w, int ii, int flag) {
  edge[cnt].from = u;
  edge[cnt].to = v;
  edge[cnt].cap = w;
  edge[cnt].id = ii;
  edge[cnt].next = head[flag][u];
  head[flag][u] = cnt++;
}
void tarjan(int u) {
  dfn[u] = low[u] = ++indx;
  for (int i = head[0][u]; i != -1; i = edge[i].next) {
    int v = edge[i].to;
    if (dfn[v] == -1) {
      fa[v] = edge[i].id;
      tarjan(v);
      low[u] = min(low[u], low[v]);
      if (low[v] > dfn[u]) {
        road[edge[i].id].flag = 1;
      }
    } else {
      if (fa[u] != edge[i].id) {
        low[u] = min(low[u], dfn[v]);
      }
    }
  }
}
void output(int m) {
  for (int i = 0; i < m; i++) {
    if (road[i].flag == -1) {
      if (road[i].ans < road[i].w && road[i].ans > 0)
        printf("CAN %I64d\n", road[i].ans);
      else
        printf("NO\n");
    } else if (road[i].flag == 1) {
      printf("YES\n");
    } else {
      if (road[i].w > 1 && road[i].flag != -2)
        printf("CAN 1\n");
      else
        printf("NO\n");
    }
  }
}
