#include <bits/stdc++.h>
using namespace std;
const long long N = 1e5 + 100, inF = 1e16,
                MODs[] = {1000 * 1000 * 1000 + 7, 1000 * 1000 * 1000 + 9};
struct edge {
  long long u, w, dex;
  edge(long long U, long long W, long long DEX) { u = U, w = W, dex = DEX; }
};
long long n, m, u, v, s, t, w, all, deg[N], ans[N], l[N], cnt[N][2][2],
    dis[2][N];
int mark[N];
vector<int> in[N], vec[N];
vector<edge> nei[N], rev[N], new_nei[N];
long long sum(long long a, long long b, int dex) {
  long long MOD = MODs[dex];
  a += b;
  if (a >= MOD) a -= MOD;
  return a;
}
long long mul(long long a, long long b, int dex) {
  long long MOD = MODs[dex];
  return (a % MOD) * (b % MOD) % MOD;
}
void dijkstra(int s, bool dex) {
  priority_queue<pair<long long, long long>, vector<pair<long long, long long>>,
                 greater<pair<long long, long long>>>
      pq;
  for (int i = 0; i < n; i++) dis[dex][i] = inF;
  pq.push(pair<long long, long long>(0, s));
  while (pq.size()) {
    pair<long long, long long> p = pq.top();
    pq.pop();
    while (pq.size() && dis[dex][p.second] != inF) {
      p = pq.top();
      pq.pop();
    }
    if (dis[dex][p.second] != inF) break;
    int v = p.second;
    dis[dex][v] = p.first;
    for (edge e : nei[v])
      pq.push(pair<long long, long long>(dis[dex][v] + e.w, e.u));
  }
}
void dfs(int v, int dex) {
  mark[v]++;
  if (dex == 0)
    for (edge e : new_nei[v]) {
      if (mark[e.u] == 0) dfs(e.u, dex);
      cnt[v][dex][0] = sum(cnt[v][dex][0], cnt[e.u][dex][0], 0);
      cnt[v][dex][1] = sum(cnt[v][dex][1], cnt[e.u][dex][1], 1);
    }
  else
    for (edge e : new_nei[v]) {
      cnt[e.u][dex][0] = sum(cnt[e.u][dex][0], cnt[v][dex][0], 0);
      cnt[e.u][dex][1] = sum(cnt[e.u][dex][1], cnt[v][dex][1], 1);
      mark[e.u]++;
      if (mark[e.u] == deg[e.u]) dfs(e.u, dex);
    }
}
void find_ans() {
  fill(ans, ans + N, inF);
  for (int v = 0; v < n; v++)
    for (edge e : nei[v])
      if (dis[0][v] + e.w + dis[1][e.u] == dis[0][t])
        new_nei[v].push_back(e), deg[e.u]++;
  cnt[t][0][0] = cnt[t][0][1] = 1;
  cnt[s][1][0] = cnt[s][1][1] = 1;
  dfs(s, 0);
  memset(mark, false, sizeof mark);
  dfs(s, 1);
  for (int v = 0; v < n; v++)
    for (edge e : new_nei[v])
      if (new_nei[v].size() == 1 &&
          mul(cnt[v][0][0], cnt[v][1][0], 0) == cnt[s][0][0] &&
          mul(cnt[v][0][1], cnt[v][1][1], 1) == cnt[s][0][1])
        ans[new_nei[v][0].dex] = 0;
  for (int v = 0; v < n; v++)
    for (edge e : nei[v])
      if (ans[e.dex] && dis[0][v] + dis[1][e.u] + 1 < dis[0][t])
        ans[e.dex] = e.w - (dis[0][t] - dis[0][v] - dis[1][e.u] - 1);
}
int main() {
  ios::sync_with_stdio(false), cin.tie(0);
  cin >> n >> m >> s >> t;
  s--, t--;
  for (int i = 0; i < m; i++) {
    cin >> u >> v >> w;
    nei[--u].push_back(edge(--v, w, i));
    rev[v].push_back(edge(u, w, i));
  }
  dijkstra(s, 0);
  for (int i = 0; i < n; i++) nei[i].swap(rev[i]);
  dijkstra(t, 1);
  for (int i = 0; i < n; i++) nei[i].swap(rev[i]);
  find_ans();
  for (int i = 0; i < m; i++)
    if (ans[i] == 0)
      cout << "YES\n";
    else if (ans[i] == inF)
      cout << "NO\n";
    else
      cout << "CAN " << ans[i] << '\n';
  return 0;
}
