#include <bits/stdc++.h>
using namespace std;
const long long int LINF = 0x3f3f3f3f3f3f3f3fll;
const long double pi = acos(-1);
const int MOD = 1e9 + 7;
vector<vector<pair<long long int, long long int> > > graphC;
vector<pair<long long int, pair<long long int, long long int> > > edges;
vector<long long int> level;
vector<long long int> minLevel;
vector<long long int> res;
void Dijkstra(vector<vector<pair<long long int, long long int> > >& graph,
              long long int start, long long int end,
              vector<long long int>& pesos) {
  priority_queue<pair<long long int, long long int>,
                 vector<pair<long long int, long long int> >,
                 greater<pair<long long int, long long int> > >
      nodes;
  pesos[start] = 0;
  nodes.push(make_pair(0, start));
  pair<long long int, long long int> atual;
  while (!nodes.empty()) {
    atual = nodes.top();
    nodes.pop();
    for (vector<pair<long long int, long long int> >::iterator it =
             graph[atual.second].begin();
         it != graph[atual.second].end(); ++it) {
      if (pesos[it->second] == -1 ||
          pesos[it->second] > it->first + pesos[atual.second]) {
        pesos[it->second] = it->first + pesos[atual.second];
        nodes.push(make_pair(pesos[it->second], it->second));
      }
    }
  }
}
long long int dfs(long long int start, long long int nivel,
                  long long int edgeDad) {
  if (level[start] != -1) {
    if (minLevel[start] == LINF)
      return level[start];
    else
      return minLevel[start];
  }
  level[start] = nivel;
  long long int retorno, minimo = nivel;
  for (long long int i = 0; i < graphC[start].size(); i++) {
    if (graphC[start][i].second != edgeDad) {
      retorno = dfs(graphC[start][i].first, nivel + 1, graphC[start][i].second);
      if (retorno > nivel) {
        res[graphC[start][i].second] = 0;
      }
      minimo = min(minimo, retorno);
    }
  }
  minLevel[start] = minimo;
  return minimo;
}
int main() {
  long long int n, m, s, t, i, a, b, c, result;
  cin >> n >> m >> s >> t;
  s--;
  t--;
  vector<vector<pair<long long int, long long int> > > graphA(n);
  vector<vector<pair<long long int, long long int> > > graphB(n);
  graphC.resize(n);
  edges.resize(m);
  vector<long long int> pesosA(n, LINF);
  vector<long long int> pesosB(n, LINF);
  level.resize(n, -1);
  minLevel.resize(n, LINF);
  res.resize(m, -1);
  for (i = 0; i < m; i++) {
    cin >> edges[i].first >> edges[i].second.first >> edges[i].second.second;
    edges[i].first--;
    edges[i].second.first--;
    graphA[edges[i].first].push_back(
        make_pair(edges[i].second.second, edges[i].second.first));
    graphB[edges[i].second.first].push_back(
        make_pair(edges[i].second.second, edges[i].first));
  }
  Dijkstra(graphA, s, t, pesosA);
  Dijkstra(graphB, t, s, pesosB);
  for (i = 0; i < m; i++) {
    if (pesosA[edges[i].first] != LINF and
        pesosB[edges[i].second.first] != LINF and
        edges[i].second.second + pesosA[edges[i].first] +
                pesosB[edges[i].second.first] ==
            pesosA[t]) {
      graphC[edges[i].first].push_back(make_pair(edges[i].second.first, i));
      graphC[edges[i].second.first].push_back(make_pair(edges[i].first, i));
    }
  }
  dfs(s, 0, -1);
  for (i = 0; i < m; i++) {
    if (res[i] == 0)
      cout << "YES\n";
    else {
      a = pesosA[edges[i].first];
      b = pesosB[edges[i].second.first];
      c = pesosA[t];
      result = ((edges[i].second.second + a + b) - c) + 1;
      if (result >= edges[i].second.second)
        cout << "NO\n";
      else
        cout << "CAN " << result << endl;
    }
  }
  return 0;
}
