#include <bits/stdc++.h>
using namespace std;
struct Edge {
  long long u, v, w;
  bool operator<(const Edge E) const {
    if (u == E.u) {
      if (v == E.v) {
        return w != E.w;
      }
      return v != E.v;
    }
    return u != E.u;
  }
};
struct Path {
  long long nodo, peso;
  Path() {}
  Path(long long n, long long p) {
    nodo = n;
    peso = p;
  }
  bool operator<(const Path &P) const {
    if (peso == P.peso) {
      return nodo < P.nodo;
    }
    return peso > P.peso;
  }
};
vector<long long> adjD[100100];
vector<long long> adjI[100100];
vector<long long> pesoD[100100];
vector<long long> pesoI[100100];
bool vis[100100];
long long d[100100];
long long dInv[100100];
void dijkstraD(long long root) {
  for (int i = 0; i < 100100; i++) d[i] = 1e18;
  ;
  for (int i = 0; i < 100100; i++) vis[i] = false;
  ;
  priority_queue<Path> q;
  Path inicio;
  inicio.nodo = root;
  inicio.peso = 0;
  d[root] = 0;
  q.push(inicio);
  while (!q.empty()) {
    Path p = q.top();
    q.pop();
    int u = p.nodo;
    if (vis[u]) {
      continue;
    }
    if (p.peso != d[u]) {
      continue;
    }
    vis[u] = true;
    for (int i = 0; i < adjD[u].size(); i++) {
      int v = adjD[u][i];
      if (vis[v]) {
        continue;
      }
      if (d[u] + pesoD[u][i] < d[v]) {
        d[v] = d[u] + pesoD[u][i];
        Path nuevoPath(v, d[v]);
        q.push(nuevoPath);
      }
    }
  }
}
void dijsktraI(long long root) {
  for (int i = 0; i < 100100; i++) dInv[i] = 1e18;
  ;
  for (int i = 0; i < 100100; i++) vis[i] = false;
  ;
  priority_queue<Path> q;
  Path inicio;
  inicio.nodo = root;
  inicio.peso = 0;
  dInv[root] = 0;
  q.push(inicio);
  while (!q.empty()) {
    Path p = q.top();
    q.pop();
    int u = p.nodo;
    if (vis[u]) {
      continue;
    }
    if (p.peso != dInv[u]) {
      continue;
    }
    vis[u] = true;
    for (int i = 0; i < adjI[u].size(); i++) {
      int v = adjI[u][i];
      if (vis[v]) {
        continue;
      }
      if (dInv[u] + pesoI[u][i] < dInv[v]) {
        dInv[v] = dInv[u] + pesoI[u][i];
        Path nuevoPath(v, dInv[v]);
        q.push(nuevoPath);
      }
    }
  }
}
long long contCaminos = 1;
map<pair<long long, long long>, bool> esencial;
void dijkstraPath(long long root, long long fin) {
  priority_queue<Path> q;
  Path inicio;
  inicio.nodo = root;
  inicio.peso = 0;
  q.push(inicio);
  while (!q.empty()) {
    Path p = q.top();
    if (p.peso != d[p.nodo]) {
      system("pause");
      continue;
    }
    bool puedeSer = false;
    long long contEntrantes = 0;
    long long fijoU = p.nodo;
    long long fijoW = p.peso;
    long long u, w;
    u = fijoU;
    w = fijoW;
    while (!q.empty() && u == fijoU && w == fijoW) {
      q.pop();
      contEntrantes++;
      u = q.top().nodo;
      w = q.top().peso;
    }
    u = fijoU;
    w = fijoW;
    if (contEntrantes == contCaminos) puedeSer = true;
    contCaminos -= contEntrantes;
    long long contSalientes = 0;
    long long auxV = -1;
    for (int i = 0; i < adjD[u].size(); i++) {
      int v = adjD[u][i];
      if (d[u] + pesoD[u][i] != d[v]) {
        continue;
      }
      if (d[u] + pesoD[u][i] + dInv[v] != d[fin]) {
        continue;
      }
      Path nuevoPath(v, d[v]);
      contCaminos++;
      contSalientes++;
      auxV = v;
      q.push(nuevoPath);
    }
    if (contSalientes == 1 && puedeSer) {
      esencial[make_pair(u, auxV)] = true;
    }
  }
}
Edge E[100100];
map<Edge, long long> multiEdge;
int main() {
  long long n, m;
  scanf("%lld", &n);
  ;
  scanf("%lld", &m);
  ;
  long long s, t;
  scanf("%lld", &s);
  ;
  scanf("%lld", &t);
  ;
  s--;
  t--;
  for (int i = 0; i < m; i++) {
    long long u;
    scanf("%lld", &u);
    ;
    u--;
    long long v;
    scanf("%lld", &v);
    ;
    v--;
    long long w;
    scanf("%lld", &w);
    ;
    adjD[u].push_back(v);
    pesoD[u].push_back(w);
    adjI[v].push_back(u);
    pesoI[v].push_back(w);
    E[i].u = u;
    E[i].v = v;
    E[i].w = w;
    multiEdge[E[i]]++;
  }
  dijkstraD(s);
  dijsktraI(t);
  dijkstraPath(s, t);
  for (int i = 0; i < m; i++) {
    long long path = d[E[i].u] + E[i].w + dInv[E[i].v];
    if (path > d[t]) {
      long long mejora = path - d[t] + 1;
      if (E[i].w - mejora >= 1 && path < 1e18) {
        printf("CAN %lld\n", mejora);
      } else {
        printf("NO\n");
      }
    } else if (path < d[t]) {
      printf("BUG\n");
    } else {
      if (multiEdge[E[i]] > 1) {
        if (E[i].w > 1) {
          printf("CAN 1\n");
        } else {
          printf("NO\n");
        }
      } else {
        if (esencial[make_pair(E[i].u, E[i].v)]) {
          printf("YES\n");
        } else if (E[i].w > 1) {
          printf("CAN 1\n");
        } else {
          printf("NO\n");
        }
      }
    }
  }
  return 0;
}
