#include <bits/stdc++.h>
#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;
const int MAXN = 101000;
const int MAXM = 500000;
const long long INF = 1e17;
struct shortestpath {
  int cnt;
  int head[MAXN], vis[MAXN];
  long long dis[MAXN];
  struct edge {
    int to, nxt, w;
  } e[MAXM];
  void init() {
    cnt = 0;
    memset(head, -1, sizeof(head));
  }
  void addedge(int u, int v, int w) {
    e[cnt].w = w;
    e[cnt].to = v;
    e[cnt].nxt = head[u];
    head[u] = cnt++;
  }
  void dijkstra(int s, int n) {
    memset(vis, 0, sizeof(vis));
    for (int i = 0; i <= n; i++) dis[i] = INF;
    priority_queue<pair<long long, int>, vector<pair<long long, int> >,
                   greater<pair<long long, int> > >
        que;
    dis[s] = 0;
    vis[s] = 1;
    que.push(pair<long long, int>(0, s));
    while (!que.empty()) {
      pair<long long, int> p = que.top();
      que.pop();
      int u = p.second;
      if (dis[u] < p.first) continue;
      for (int i = head[u]; ~i; i = e[i].nxt) {
        if (dis[e[i].to] > dis[u] + e[i].w) {
          dis[e[i].to] = dis[u] + e[i].w;
          que.push(pair<long long, int>(dis[e[i].to], e[i].to));
        }
      }
    }
  }
} Dij1, Dij2;
struct Tarjan {
  int head[MAXN], cnt;
  int low[MAXN], dfn[MAXN], sta[MAXN], bel[MAXN];
  bool iscut[MAXN];
  int top, idx, block, bri;
  struct edge {
    int from, to, nxt;
    bool cut;
  } e[MAXM];
  void init() {
    cnt = 0;
    memset(head, -1, sizeof(head));
  }
  void addedge(int u, int v) {
    e[cnt].from = u;
    e[cnt].to = v;
    e[cnt].nxt = head[u];
    e[cnt].cut = false;
    head[u] = cnt++;
  }
  void tarjan(int u, int pre) {
    int v;
    low[u] = dfn[u] = ++idx;
    sta[++top] = u;
    int child = 0, flag = 1;
    for (int i = head[u]; ~i; i = e[i].nxt) {
      v = e[i].to;
      if (flag && v == pre) {
        flag = 0;
        continue;
      }
      if (!dfn[v]) {
        child++;
        tarjan(v, u);
        low[u] = min(low[u], low[v]);
        if (low[v] >= dfn[u]) {
          iscut[u] = true;
          if (low[v] > dfn[u]) {
            e[i].cut = true;
            e[i ^ 1].cut = true;
          }
        }
      } else
        low[u] = min(low[u], dfn[v]);
    }
    if (child == 1 && pre < 0) iscut[u] = false;
    if (low[u] == dfn[u]) {
      block++;
      do {
        bel[sta[top]] = block;
      } while (sta[top--] != u);
    }
  }
  void solve(int N) {
    idx = top = block = 0;
    memset(dfn, 0, sizeof(dfn));
    memset(iscut, 0, sizeof(iscut));
    memset(bel, -1, sizeof(bel));
    for (int i = 1; i <= N; i++) {
      if (!dfn[i]) tarjan(i, -1);
    }
  }
} Tar;
int vis[MAXM];
struct Edge {
  int u, v, w;
} e[MAXN];
int main() {
  int n, m, s, t;
  while (~scanf("%d%d%d%d", &n, &m, &s, &t)) {
    Dij1.init(), Dij2.init();
    for (int i = 0; i < m; i++) {
      int u, v, w;
      scanf("%d%d%d", &u, &v, &w);
      e[i].u = u, e[i].v = v, e[i].w = w;
      Dij1.addedge(u, v, w);
      Dij2.addedge(v, u, w);
    }
    Dij1.dijkstra(s, n);
    Dij2.dijkstra(t, n);
    Tar.init();
    memset(vis, false, sizeof(vis));
    for (int i = 0; i < m; i++) {
      int u = e[i].u, v = e[i].v, w = e[i].w;
      if (Dij1.dis[u] + w + Dij2.dis[v] == Dij1.dis[t]) {
        Tar.addedge(u, v);
        Tar.addedge(v, u);
        vis[i] = Tar.cnt - 1;
      }
    }
    Tar.solve(n);
    for (int i = 0; i < m; i++) {
      if (vis[i] && Tar.e[vis[i]].cut == true) {
        puts("YES");
        continue;
      }
      int u = e[i].u, v = e[i].v;
      long long w = Dij1.dis[t] - Dij1.dis[u] - Dij2.dis[v] - 1;
      if (w <= 0)
        puts("NO");
      else
        printf("CAN %I64d\n", e[i].w - w);
    }
  }
  return 0;
}
