#include <bits/stdc++.h>
#pragma GCC optimize("O3", "unroll-loops")
#pragma GCC target("sse4.2")
using namespace std;
mt19937 gen(chrono::high_resolution_clock::now().time_since_epoch().count());
template <class T, class U>
inline void checkmin(T &x, U y) {
  if (y < x) x = y;
}
template <class T, class U>
inline void checkmax(T &x, U y) {
  if (y > x) x = y;
}
template <class T, class U>
inline bool ifmax(T &x, U y) {
  if (y > x) return x = y, true;
  return false;
}
template <class T, class U>
inline bool ifmin(T &x, U y) {
  if (y < x) return x = y, true;
  return false;
}
template <class T>
inline void sort(T &a) {
  sort(a.begin(), a.end());
}
template <class T>
inline void rsort(T &a) {
  sort(a.rbegin(), a.rend());
}
template <class T>
inline void reverse(T &a) {
  reverse(a.begin(), a.end());
}
template <class T, class U>
inline istream &operator>>(istream &str, pair<T, U> &p) {
  return str >> p.first >> p.second;
}
template <class T>
inline istream &operator>>(istream &str, vector<T> &a) {
  for (auto &i : a) str >> i;
  return str;
}
template <class T>
inline T sorted(T a) {
  sort(a);
  return a;
}
signed main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  cout << fixed << setprecision(12);
  int n, m, second, t;
  cin >> n >> m >> second >> t;
  --second, --t;
  vector<vector<pair<int, long long>>> G(n), rev(n);
  vector<pair<pair<int, int>, long long>> edge;
  for (int i = 0; i < m; ++i) {
    int u, v;
    long long w;
    cin >> u >> v >> w;
    --u, --v;
    edge.push_back({{u, v}, w});
    G[u].push_back({v, w});
    rev[v].push_back({u, w});
  }
  auto getdist = [&](int second,
                     const vector<vector<pair<int, long long>>> &G) {
    vector<long long> dist(n, 3000000000000000007ll);
    dist[second] = 0;
    auto cmp = [&](int i, int j) { return dist[i] > dist[j]; };
    priority_queue<int, vector<int>, decltype(cmp)> que(cmp);
    que.push(second);
    while (signed(que.size())) {
      auto first = que.top();
      que.pop();
      for (auto i : G[first])
        if (ifmin(dist[i.first], dist[first] + i.second)) que.push(i.first);
    }
    return dist;
  };
  auto ds = getdist(second, G), dt = getdist(t, rev);
  vector<pair<long long, long long>> check;
  map<long long, int> cnts, cntt;
  for (auto &i : edge) {
    if (ds[i.first.first] + dt[i.first.second] + i.second == ds[t]) {
      check.push_back({ds[i.first.first], ds[i.first.first] + i.second});
      ++cnts[ds[i.first.first]];
      ++cntt[dt[i.first.second]];
    }
  }
  sort(check);
  for (int i = 1; i < signed(check.size()); ++i)
    checkmax(check[i].second, check[i - 1].second);
  for (auto &i : edge) {
    if (ds[i.first.first] + dt[i.first.second] + i.second == ds[t]) {
      pair<long long, long long> x = pair<long long, long long>(
          ds[i.first.first], ds[i.first.first] + i.second);
      auto it = lower_bound(check.begin(), check.end(), x);
      bool flag = *it == x;
      if (++it != check.end())
        if (*it == x) flag = false;
      if (flag && cnts[ds[i.first.first]] == 1 &&
          cntt[dt[i.first.second]] == 1) {
        cout << "YES\n";
      } else if (i.second > 1)
        cout << "CAN " << 1 << '\n';
      else
        cout << "NO\n";
    } else {
      long long need =
          ds[i.first.first] + dt[i.first.second] + i.second - ds[t] + 1;
      if (need < i.second)
        cout << "CAN " << need << '\n';
      else
        cout << "NO\n";
    }
  }
  return 0;
}
