#include <bits/stdc++.h>
const double EPS = 1e-7, PI = acos(-1.0);
using namespace std;
template <class T>
inline T IN(T &num) {
  num = 0;
  char c = getchar(), f = 0;
  while (c != '-' && (c < '0' || c > '9')) c = getchar();
  if (c == '-') f = 1, c = getchar();
  while ('0' <= c && c <= '9') num = num * 10 + c - '0', c = getchar();
  if (f) num = -num;
  return num;
}
template <class T>
inline void U(T num) {
  if (num < 0) putchar('-'), num = -num;
  if (num > 9) U(num / 10);
  putchar(num % 10 + '0');
}
const int NUM = 100010;
const int MAXV = NUM, MAXE = NUM;
struct edge {
  int next, from, to, cost, id;
};
struct G {
  vector<edge> e;
  vector<int> head;
  void init() {
    e.clear();
    head.clear();
    head.resize(MAXV, -1);
  }
  void add_edge(int u, int v, int cost, int id) {
    e.push_back((edge){head[u], u, v, cost, id});
    head[u] = (int)e.size() - 1;
  }
} g[2];
int n, m, s, t;
long long dist[2][MAXV];
void shortest_path(int S, int T, int k) {
  priority_queue<pair<int, int>, vector<pair<int, int> >,
                 greater<pair<int, int> > >
      que;
  for (int i = 1; i <= n; i++) dist[k][i] = LONG_LONG_MAX;
  dist[k][S] = 0;
  que.push(pair<int, int>(0, S));
  while (!que.empty()) {
    pair<int, int> p = que.top();
    que.pop();
    int u = p.second;
    if (dist[k][u] < p.first) continue;
    for (int i = g[k].head[u]; i != -1; i = g[k].e[i].next) {
      int v = g[k].e[i].to;
      if (dist[k][v] > dist[k][u] + g[k].e[i].cost) {
        dist[k][v] = dist[k][u] + g[k].e[i].cost;
        que.push(pair<int, int>(dist[k][v], v));
      }
    }
  }
}
int ans[MAXE];
int dfs[MAXV], low[MAXV];
int stk[MAXV], top;
void tarjan(int u, int order, int pree) {
  dfs[u] = low[u] = order++;
  for (int i = g[1].head[u]; i != -1; i = g[1].e[i].next) {
    int v = g[1].e[i].to;
    if (!dfs[v]) {
      tarjan(v, order, i);
      if (low[v] < low[u]) low[u] = low[v];
      if (dfs[u] < low[v]) {
        ans[g[1].e[i].id] = 0;
      }
    } else if ((i ^ 1) != pree && dfs[v] < low[u])
      low[u] = dfs[v];
  }
}
int main() {
  int i, u, v, w;
  IN(n), IN(m), IN(s), IN(t);
  g[0].init(), g[1].init();
  for (i = 0; i < m; i++) {
    IN(u), IN(v), IN(w);
    g[0].add_edge(u, v, w, i);
    g[1].add_edge(v, u, w, i);
  }
  shortest_path(s, t, 0);
  shortest_path(t, s, 1);
  memset(ans, -1, sizeof(ans));
  g[1].init();
  for (int i = 0; i < m; i++) {
    u = g[0].e[i].from, v = g[0].e[i].to, w = g[0].e[i].cost;
    if (dist[0][u] + dist[1][u] == dist[0][t] &&
        dist[0][v] + dist[1][v] == dist[0][t] && dist[0][u] + w == dist[0][v]) {
      g[1].add_edge(u, v, w, i);
      g[1].add_edge(v, u, w, i);
    }
  }
  tarjan(s, 1, -1);
  for (int i = 0; i < m; i++)
    if (ans[i] == -1) {
      int u = g[0].e[i].from, v = g[0].e[i].to, w = g[0].e[i].cost;
      if (dist[0][u] < dist[0][t] && dist[1][v] < dist[0][t]) {
        int cnt = dist[0][t] - 1 - dist[0][u] - dist[1][v];
        if (cnt > 0 && cnt < w) ans[i] = w - cnt;
      }
    }
  for (int i = 0; i < m; i++)
    if (ans[i] == 0)
      puts("YES");
    else if (ans[i] == -1)
      puts("NO");
    else
      printf("CAN %d\n", ans[i]);
  return 0;
}
