#include <bits/stdc++.h>
using namespace std;
const int N = 1e5;
struct NODE {
  int to, len, id;
  NODE *nxt;
  NODE() {}
  NODE(int _t, int _l, int _i, NODE *_n) : id(_i), len(_l), to(_t), nxt(_n) {}
};
struct GRAPH {
  NODE pol[N * 2 + 3], *head[N + 3], *ncnt;
  GRAPH() { ncnt = pol; }
  void AddEdge(int u, int v, int len, int id) {
    NODE *p = ++ncnt;
    *p = NODE(v, len, id, head[u]);
    head[u] = p;
  }
  NODE *&operator[](int id) { return head[id]; }
} G, G_, F;
int n, m, s, t, ndfn, nblk;
long long dis[N + 3], fdis[N + 3], ans[N + 3];
bool vis[N + 3];
int dfn[N + 3], low[N + 3], blk[N + 3];
stack<int> stk;
void Dijkstra() {
  priority_queue<pair<long long, int> > que;
  memset(dis, 0x3f, sizeof dis);
  que.push(make_pair(dis[s] = 0, s));
  while (!que.empty()) {
    int u = que.top().second;
    que.pop();
    if (vis[u]) continue;
    vis[u] = true;
    for (auto it = G[u]; it; it = it->nxt) {
      int v = it->to;
      if (!vis[v] && dis[v] > dis[u] + it->len) {
        dis[v] = dis[u] + it->len;
        que.push(make_pair(-dis[v], v));
      }
    }
  }
  memset(fdis, 0x3f, sizeof fdis);
  memset(vis, false, sizeof vis);
  que.push(make_pair(fdis[t] = 0, t));
  while (!que.empty()) {
    int u = que.top().second;
    que.pop();
    if (vis[u]) continue;
    vis[u] = true;
    for (auto it = G_[u]; it; it = it->nxt) {
      int v = it->to;
      if (!vis[v] && fdis[v] > fdis[u] + it->len) {
        fdis[v] = fdis[u] + it->len;
        que.push(make_pair(-fdis[v], v));
      }
    }
  }
}
void Tarjan(int u, int las) {
  dfn[u] = low[u] = ++ndfn;
  stk.push(u);
  for (auto it = F[u]; it; it = it->nxt) {
    int v = it->to;
    if (it->id == las) continue;
    if (!dfn[v]) {
      Tarjan(v, it->id);
      low[u] = min(low[u], low[v]);
    } else
      low[u] = min(low[u], dfn[v]);
  }
  if (dfn[u] == low[u]) {
    ++nblk;
    int tmp;
    do {
      tmp = stk.top();
      stk.pop();
      blk[tmp] = nblk;
    } while (tmp != u);
  }
}
int main() {
  scanf("%d%d%d%d", &n, &m, &s, &t);
  for (int i = 1, u, v, len; i <= m; i++) {
    scanf("%d%d%d", &u, &v, &len);
    G.AddEdge(u, v, len, i);
    G_.AddEdge(v, u, len, i);
  }
  Dijkstra();
  memset(ans, 0x3f, sizeof ans);
  for (int i = 1; i <= n; i++)
    for (auto it = G[i]; it; it = it->nxt)
      if (dis[i] + it->len == dis[it->to] &&
          fdis[it->to] == dis[t] - dis[i] - it->len) {
        if (it->len != 1) ans[it->id] = 1;
        F.AddEdge(i, it->to, 1, it->id);
        F.AddEdge(it->to, i, 1, it->id);
      }
  Tarjan(s, -1);
  for (int i = 1; i <= n; i++)
    for (auto it = F[i]; it; it = it->nxt)
      if (blk[i] != blk[it->to]) ans[it->id] = 0;
  int resdis = dis[t];
  for (int i = 1; i <= n; i++)
    for (auto it = G[i]; it; it = it->nxt) {
      if (ans[it->id] <= 1) continue;
      if (resdis - dis[i] - fdis[it->to] - 1 >= 1)
        ans[it->id] =
            min(ans[it->id], it->len + 1 - (resdis - dis[i] - fdis[it->to]));
      else
        ans[it->id] = -1;
    }
  for (int i = 1; i <= m; i++)
    if (ans[i] == 0)
      printf("YES\n");
    else if (ans[i] == -1)
      printf("NO\n");
    else
      printf("CAN %lld\n", ans[i]);
  return 0;
}
