#include <iostream>
#include <vector>
#include <string>
#include <memory.h>
#include <set>
#include <algorithm>
#include <map>
#include <cstdlib>
#include <cstdio>
#include <queue>
#include <climits>
#include <cmath>
#include <iomanip>

#define mp make_pair
#define pb push_back
#define all(x) (x).begin(), (x).end()
#define fi first
#define se second
#define endl '\n'
#define dbgv(arr) cout << #arr << ": "; for (int i = 0; i < (int)arr.size(); i++) cout << arr[i] << " "; cout << endl;
#define dbge(el) cout << #el << ": " << el << endl;
#define dbgvv(arr) cout << #arr << ": "; for (int i = 0; i < (int)arr.size(); i++) cout << "(" << arr[i].first << " " << arr[i].second << ") "; cout << endl;
#define sz(s) ((int)(s).size())
#define re return
#define rep(i, n) for (int i = 0; i < (n); i++)

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef pair<int, int> ii;
typedef vector< pair<int, int> > vii;

template<class T> T abs(T x) { return x > 0 ? x : -x; }

const int maxn = 100000 + 100;
int n, m, s, t;
vii e[maxn];
vii e2[maxn];
int from[maxn];
int to[maxn];
int w[maxn];
bool was[maxn];
ll cnt1[maxn];
ll cnt2[maxn];

vll dijkstra(int v, vii *e, ll *cnt) {
	vll d(n, LLONG_MAX);
	set< pair<ll, ll> > q;

	memset(was, 0, sizeof(was));

	d[v] = 0;
	q.insert(mp(0, v));
	cnt[v] = 1;

	while (!q.empty()) {
		pair<ll, ll> cur = *q.begin();
		ll dist = cur.fi;
		int idx = cur.se;
		was[idx] = true;

		q.erase(cur);

		rep(i, sz(e[idx])) {
			if (!was[e[idx][i].fi]) {
				if (d[e[idx][i].fi] > dist + e[idx][i].se) {
					auto it = q.lower_bound(mp(d[e[idx][i].fi], e[idx][i].fi));
					if (it != q.end()) q.erase(it);
					d[e[idx][i].fi] = dist + e[idx][i].se;
					q.insert(mp(d[e[idx][i].fi], e[idx][i].fi));
					cnt[e[idx][i].fi] = cnt[idx];
				} else if (d[e[idx][i].fi] == dist + e[idx][i].se) {
					cnt[e[idx][i].fi] += cnt[idx];
				}
			}
		}
	}

	re d;
}

int main()
{
	map<ii, int> minw;
	map<ii, int> kr;

	scanf("%d%d%d%d", &n, &m, &s, &t);
	s--;
	t--;
	rep(i, m) {
		int a, b, l;
		scanf("%d%d%d", &a, &b, &l);
		from[i] = a - 1;
		to[i] = b - 1;
		w[i] = l;
		e[a - 1].pb(mp(b - 1, l));
		e2[b - 1].pb(mp(a - 1, l));

		if (minw.count(mp(a - 1, b - 1)) == 0)
			minw[mp(a - 1, b - 1)] = w[i];
		else
			minw[mp(a - 1, b - 1)] = min(minw[mp(a - 1, b - 1)], w[i]);
	}

	rep(i, m) {
		if (minw[mp(from[i], to[i])] == w[i])
			kr[mp(from[i], to[i])]++;
	}

	vll ds = dijkstra(s, &e[0], cnt1);
	vll dt = dijkstra(t, &e2[0], cnt2);

	ll best = ds[t];
	ll cpaths = cnt1[t];

	//dbge(best);
	//dbge(cpaths);

	rep(i, m) {
		if (ds[from[i]] == LLONG_MAX || dt[to[i]] == LLONG_MAX) {
			cout << "NO" << endl;
			continue;
		}

		ll w1 = ds[from[i]] + w[i] + dt[to[i]] - best;

		if (w1 == 0) {
			if (cnt1[from[i]] * cnt2[to[i]] * kr[mp(from[i], to[i])] != cpaths) {
				if (w[i] > 1) {
					cout << "CAN 1" << endl;
				} else {
					cout << "NO" << endl;
				}
			} else {
				if (kr[mp(from[i], to[i])] > 1 && w[i] > 1) {
					cout << "CAN 1" << endl;
				} else {
					cout << "YES" << endl;

					if (from[i] == 8734 && to[i] == 10494) {
						dbge(i);
						dbge(best);
						dbge(cpaths);
						dbge(ds[from[i]]);
						dbge(dt[to[i]]);
						dbge(w[i]);
						dbge(w1);
						dbge(kr[mp(from[i], to[i])]);
						dbge(minw[mp(from[i], to[i])]);
					}
				}
			}
		} else if (w1 + 1 < w[i]) {
			cout << "CAN " << w1 + 1 << endl;
		} else {
			cout << "NO" << endl;
		}
	}

	return 0;
}


#include <iostream>
#include <vector>
#include <string>
#include <memory.h>
#include <set>
#include <algorithm>
#include <map>
#include <cstdlib>
#include <cstdio>
#include <queue>
#include <climits>
#include <cmath>
#include <iomanip>

#define mp make_pair
#define pb push_back
#define all(x) (x).begin(), (x).end()
#define fi first
#define se second
#define endl '\n'
#define dbgv(arr) cout << #arr << ": "; for (int i = 0; i < (int)arr.size(); i++) cout << arr[i] << " "; cout << endl;
#define dbge(el) cout << #el << ": " << el << endl;
#define dbgvv(arr) cout << #arr << ": "; for (int i = 0; i < (int)arr.size(); i++) cout << "(" << arr[i].first << " " << arr[i].second << ") "; cout << endl;
#define sz(s) ((int)(s).size())
#define re return
#define rep(i, n) for (int i = 0; i < (n); i++)

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef pair<int, int> ii;
typedef vector< pair<int, int> > vii;

template<class T> T abs(T x) { return x > 0 ? x : -x; }

const int maxn = 100000 + 100;
int n, m, s, t;
vii e[maxn];
vii e2[maxn];
int from[maxn];
int to[maxn];
int w[maxn];
bool was[maxn];
map<ii, bool> ewas;
int paths[maxn];
map<ii, int> eindex;

vll dijkstra(int v, vii *e) {
	vll d(n, LLONG_MAX);
	set< pair<ll, ll> > q;

	memset(was, 0, sizeof(was));

	d[v] = 0;
	q.insert(mp(0, v));

	while (!q.empty()) {
		pair<ll, ll> cur = *q.begin();
		ll dist = cur.fi;
		int idx = cur.se;
		was[idx] = true;

		q.erase(cur);

		rep(i, sz(e[idx])) {
			if (!was[e[idx][i].fi] && d[e[idx][i].fi] > dist + e[idx][i].se) {
				auto it = q.lower_bound(mp(d[e[idx][i].fi], e[idx][i].fi));
				if (it != q.end()) q.erase(it);
				d[e[idx][i].fi] = dist + e[idx][i].se;
				q.insert(mp(d[e[idx][i].fi], e[idx][i].fi));
			}
		}
	}

	re d;
}

int dfs(int v, vll& d) {
	if (v == t)
		re 1;

	int ans = 0;
	rep(i, sz(e[v])) {
		if (!ewas[mp(v, i)] && d[e[v][i].fi] == d[v] + e[v][i].se) {
			ewas[mp(v, i)] = true;
			int res = dfs(e[v][i].fi, d);

			if (res > 0) {
				paths[eindex[mp(v, i)]] += res;
				ans += res;
			}

			ewas[mp(v, i)] = false;
		}
	}

	re ans;
}

int main()
{
	std::ios::sync_with_stdio(false);
	cin >> n >> m >> s >> t;
	s--;
	t--;
	rep(i, m) {
		int a, b, l;
		cin >> a >> b >> l;
		from[i] = a - 1;
		to[i] = b - 1;
		w[i] = l;
		e[a - 1].pb(mp(b - 1, l));
		eindex[mp(a - 1, sz(e[a - 1]) - 1)] = i;
		e2[b - 1].pb(mp(a - 1, l));
	}

	vll ds = dijkstra(s, &e[0]);
	vll dt = dijkstra(t, &e2[0]);

	ll best = ds[t];
	int cpaths = dfs(s, ds);

	//dbge(best);
	//dbge(cpaths);

	rep(i, m) {
		if (ds[from[i]] == LLONG_MAX || dt[to[i]] == LLONG_MAX) {
			cout << "NO" << endl;
			continue;
		}

		ll w1 = ds[from[i]] + w[i] + dt[to[i]] - best;

		//dbge(i);
		//dbge(ds[from[i]]);
		//dbge(dt[to[i]]);
		//dbge(w[i]);
		//dbge(w1);

		if (w1 == 0) {
			if (paths[i] != cpaths) {
				if (w[i] > 1) {
					cout << "CAN 1" << endl;
				} else {
					cout << "NO" << endl;
				}
			}
			else
				cout << "YES" << endl;
		} else if (w1 + 1 < w[i]) {
			cout << "CAN " << w1 + 1 << endl;
		} else {
			cout << "NO" << endl;
		}
	}

	return 0;
}


#include <iostream>
#include <vector>
#include <string>
#include <memory.h>
#include <set>
#include <algorithm>
#include <map>
#include <cstdlib>
#include <cstdio>
#include <queue>
#include <climits>
#include <cmath>
#include <iomanip>

#define mp make_pair
#define pb push_back
#define all(x) (x).begin(), (x).end()
#define fi first
#define se second
#define endl '\n'
#define dbgv(arr) cout << #arr << ": "; for (int i = 0; i < (int)arr.size(); i++) cout << arr[i] << " "; cout << endl;
#define dbge(el) cout << #el << ": " << el << endl;
#define dbgvv(arr) cout << #arr << ": "; for (int i = 0; i < (int)arr.size(); i++) cout << "(" << arr[i].first << " " << arr[i].second << ") "; cout << endl;
#define sz(s) ((int)(s).size())
#define re return
#define rep(i, n) for (int i = 0; i < (n); i++)

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef pair<int, int> ii;
typedef vector< pair<int, int> > vii;

template<class T> T abs(T x) { return x > 0 ? x : -x; }

const int maxn = 100000 + 100;
int n, m, s, t;
vii e[maxn];
vii e2[maxn];
int from[maxn];
int to[maxn];
int w[maxn];
bool was[maxn];
ll cnt1[maxn];
ll cnt2[maxn];

vll dijkstra(int v, vii *e, ll *cnt) {
	vll d(n, LLONG_MAX);
	set< pair<ll, ll> > q;

	memset(was, 0, sizeof(was));

	d[v] = 0;
	q.insert(mp(0, v));
	cnt[v] = 1;

	while (!q.empty()) {
		pair<ll, ll> cur = *q.begin();
		ll dist = cur.fi;
		int idx = cur.se;
		if (was[idx]) continue;
		was[idx] = true;

		q.erase(cur);

		rep(i, sz(e[idx])) {
			if (!was[e[idx][i].fi]) {
				if (d[e[idx][i].fi] > dist + e[idx][i].se) {
					auto it = q.lower_bound(mp(d[e[idx][i].fi], e[idx][i].fi));
					if (it != q.end()) q.erase(it);
					d[e[idx][i].fi] = dist + e[idx][i].se;
					q.insert(mp(d[e[idx][i].fi], e[idx][i].fi));
					cnt[e[idx][i].fi] = cnt[idx];
				} else if (d[e[idx][i].fi] == dist + e[idx][i].se) {
					cnt[e[idx][i].fi] += cnt[idx];
				}
			}
		}
	}

	re d;
}

int main()
{
	scanf("%d%d%d%d", &n, &m, &s, &t);
	s--;
	t--;
	rep(i, m) {
		int a, b, l;
		scanf("%d%d%d", &a, &b, &l);
		from[i] = a - 1;
		to[i] = b - 1;
		w[i] = l;
		e[a - 1].pb(mp(b - 1, l));
		e2[b - 1].pb(mp(a - 1, l));
	}

	vll ds = dijkstra(s, &e[0], cnt1);
	vll dt = dijkstra(t, &e2[0], cnt2);

	ll best = ds[t];
	ll cpaths = cnt1[t];

	//dbge(best);
	//dbge(cpaths);

	rep(i, m) {
		if (ds[from[i]] == LLONG_MAX || dt[to[i]] == LLONG_MAX) {
			cout << "NO" << endl;
			continue;
		}

		ll w1 = ds[from[i]] + w[i] + dt[to[i]] - best;

		//dbge(i);
		//dbge(ds[from[i]]);
		//dbge(dt[to[i]]);
		//dbge(w[i]);
		//dbge(w1);

		if (w1 == 0) {
			if (cnt1[from[i]] * cnt2[to[i]] != cpaths) {
				if (w[i] > 1) {
					cout << "CAN 1" << endl;
				} else {
					cout << "NO" << endl;
				}
			}
			else
				cout << "YES" << endl;
		} else if (w1 + 1 < w[i]) {
			cout << "CAN " << w1 + 1 << endl;
		} else {
			cout << "NO" << endl;
		}
	}

	return 0;
}


#include <iostream>
#include <vector>
#include <string>
#include <memory.h>
#include <set>
#include <algorithm>
#include <map>
#include <cstdlib>
#include <cstdio>
#include <queue>
#include <climits>
#include <cmath>
#include <iomanip>

#define mp make_pair
#define pb push_back
#define all(x) (x).begin(), (x).end()
#define fi first
#define se second
#define endl '\n'
#define dbgv(arr) cout << #arr << ": "; for (int i = 0; i < (int)arr.size(); i++) cout << arr[i] << " "; cout << endl;
#define dbge(el) cout << #el << ": " << el << endl;
#define dbgvv(arr) cout << #arr << ": "; for (int i = 0; i < (int)arr.size(); i++) cout << "(" << arr[i].first << " " << arr[i].second << ") "; cout << endl;
#define sz(s) ((int)(s).size())
#define re return
#define rep(i, n) for (int i = 0; i < (n); i++)

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef pair<int, int> ii;
typedef vector< pair<int, int> > vii;

template<class T> T abs(T x) { return x > 0 ? x : -x; }

const int maxn = 100000 + 100;
int n, m, s, t;
vii e[maxn];
vii e2[maxn];
int from[maxn];
int to[maxn];
int w[maxn];
bool was[maxn];
ll paths[maxn];
ll cnt1[maxn];
ll cnt2[maxn];
map<ii, int> eindex;

vll dijkstra(int v, vii *e, ll *cnt) {
	vll d(n, LLONG_MAX);
	set< pair<ll, ll> > q;

	memset(was, 0, sizeof(was));

	d[v] = 0;
	q.insert(mp(0, v));
	cnt[v] = 1;

	while (!q.empty()) {
		pair<ll, ll> cur = *q.begin();
		ll dist = cur.fi;
		int idx = cur.se;
		was[idx] = true;

		q.erase(cur);

		rep(i, sz(e[idx])) {
			if (!was[e[idx][i].fi]) {
				if (d[e[idx][i].fi] > dist + e[idx][i].se) {
					auto it = q.lower_bound(mp(d[e[idx][i].fi], e[idx][i].fi));
					if (it != q.end()) q.erase(it);
					d[e[idx][i].fi] = dist + e[idx][i].se;
					q.insert(mp(d[e[idx][i].fi], e[idx][i].fi));
					cnt[e[idx][i].fi] = cnt[idx];
				} else if (d[e[idx][i].fi] == dist + e[idx][i].se) {
					cnt[e[idx][i].fi] += cnt[idx];
				}
			}
		}
	}

	re d;
}

ll dfs(int v, ll flow, vll& d) {
	if (v == t)
		re flow;

	ll ans = 0;
	map<int, int> compression;
	map<int, ll> compression_result;

	rep(i, sz(e[v])) {
		if (!was[e[v][i].fi] && d[e[v][i].fi] == d[v] + e[v][i].se) {
			compression[e[v][i].fi]++;
		}
	}

	for (auto it = compression.begin(); it != compression.end(); ++it) {
		int target = it->fi;
		int add_flow = it->se;

		was[target] = true;
		ll res = dfs(target, flow * add_flow, d);
		ans += res;
		compression_result[target] = res;

		was[target] = false;
	}

	rep(i, sz(e[v])) {
		int target = e[v][i].fi;
		if (!was[target] && d[target] == d[v] + e[v][i].se) {
			ll res = compression_result[target];
			if (res > 0) {
				paths[eindex[mp(v, i)]] += compression_result[target] / compression[target];
			}
		}
	}

	re ans;
}

int main()
{
	scanf("%d%d%d%d", &n, &m, &s, &t);
	s--;
	t--;
	rep(i, m) {
		int a, b, l;
		scanf("%d%d%d", &a, &b, &l);
		from[i] = a - 1;
		to[i] = b - 1;
		w[i] = l;
		e[a - 1].pb(mp(b - 1, l));
		eindex[mp(a - 1, sz(e[a - 1]) - 1)] = i;
		e2[b - 1].pb(mp(a - 1, l));
	}

	vll ds = dijkstra(s, &e[0], cnt1);
	vll dt = dijkstra(t, &e2[0], cnt2);

	memset(was, 0, sizeof(was));
	ll best = ds[t];
	ll cpaths = cnt1[t];//dfs(s, 1, ds);//cnt[t];

	//dbge(best);
	//dbge(cpaths);

	rep(i, m) {
		if (ds[from[i]] == LLONG_MAX || dt[to[i]] == LLONG_MAX) {
			cout << "NO" << endl;
			continue;
		}

		ll w1 = ds[from[i]] + w[i] + dt[to[i]] - best;

		//dbge(i);
		//dbge(ds[from[i]]);
		//dbge(dt[to[i]]);
		//dbge(w[i]);
		//dbge(w1);

		if (w1 == 0) {
			if (cnt1[from[i]] * cnt2[to[i]] != cpaths) {
				if (w[i] > 1) {
					cout << "CAN 1" << endl;
				} else {
					cout << "NO" << endl;
				}
			}
			else
				cout << "YES" << endl;
		} else if (w1 + 1 < w[i]) {
			cout << "CAN " << w1 + 1 << endl;
		} else {
			cout << "NO" << endl;
		}
	}

	return 0;
}


#include <iostream>
#include <vector>
#include <string>
#include <memory.h>
#include <set>
#include <algorithm>
#include <map>
#include <cstdlib>
#include <cstdio>
#include <queue>
#include <climits>
#include <cmath>
#include <iomanip>

#define mp make_pair
#define pb push_back
#define all(x) (x).begin(), (x).end()
#define fi first
#define se second
#define endl '\n'
#define dbgv(arr) cout << #arr << ": "; for (int i = 0; i < (int)arr.size(); i++) cout << arr[i] << " "; cout << endl;
#define dbge(el) cout << #el << ": " << el << endl;
#define dbgvv(arr) cout << #arr << ": "; for (int i = 0; i < (int)arr.size(); i++) cout << "(" << arr[i].first << " " << arr[i].second << ") "; cout << endl;
#define sz(s) ((int)(s).size())
#define re return
#define rep(i, n) for (int i = 0; i < (n); i++)

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef pair<int, int> ii;
typedef vector< pair<int, int> > vii;

template<class T> T abs(T x) { return x > 0 ? x : -x; }

const ll mod = 1000000000ll + 3;
const int maxn = 100000 + 100;
int n, m, s, t;
vii e[maxn];
vii e2[maxn];
int from[maxn];
int to[maxn];
int w[maxn];
bool was[maxn];
ll cnt1[maxn];
ll cnt2[maxn];

vll dijkstra(int v, vii *e, ll *cnt) {
	vll d(n, LLONG_MAX);
	set< pair<ll, ll> > q;

	memset(was, 0, sizeof(was));

	d[v] = 0;
	q.insert(mp(0, v));
	cnt[v] = 1;

	while (!q.empty()) {
		pair<ll, ll> cur = *q.begin();
		ll dist = cur.fi;
		int idx = cur.se;
		was[idx] = true;

		q.erase(cur);

		rep(i, sz(e[idx])) {
			int target = e[idx][i].fi;
			if (!was[target]) {
				if (d[target] > dist + e[idx][i].se) {
					auto it = q.lower_bound(mp(d[target], target));
					if (it != q.end()) q.erase(it);
					d[target] = dist + e[idx][i].se;
					q.insert(mp(d[target], target));
					cnt[target] = cnt[idx];
				} else if (d[target] == dist + e[idx][i].se) {
					cnt[target] = (cnt[target] + cnt[idx]) % mod;
				}
			}
		}
	}

	re d;
}

int main()
{
	map<ii, int> minw;
	map<ii, int> kr;

	scanf("%d%d%d%d", &n, &m, &s, &t);
	s--;
	t--;
	rep(i, m) {
		int a, b, l;
		scanf("%d%d%d", &a, &b, &l);
		from[i] = a - 1;
		to[i] = b - 1;
		w[i] = l;
		e[a - 1].pb(mp(b - 1, l));
		e2[b - 1].pb(mp(a - 1, l));

		if (minw.count(mp(a - 1, b - 1)) == 0)
			minw[mp(a - 1, b - 1)] = w[i];
		else
			minw[mp(a - 1, b - 1)] = min(minw[mp(a - 1, b - 1)], w[i]);
	}

	rep(i, m) {
		if (minw[mp(from[i], to[i])] == w[i])
			kr[mp(from[i], to[i])]++;
	}

	vll ds = dijkstra(s, &e[0], cnt1);
	vll dt = dijkstra(t, &e2[0], cnt2);

	ll best = ds[t];
	ll cpaths = cnt1[t];

	rep(i, m) {
		if (ds[from[i]] == LLONG_MAX || dt[to[i]] == LLONG_MAX) {
			cout << "NO" << endl;
			continue;
		}

		ll w1 = ds[from[i]] + w[i] + dt[to[i]] - best;

		if (w1 == 0) {
			if (((cnt1[from[i]] * cnt2[to[i]] % mod) * kr[mp(from[i], to[i])]) % mod != cpaths) {
				if (w[i] > 1) {
					cout << "CAN 1" << endl;
				} else {
					cout << "NO" << endl;
				}
			} else {
				if (kr[mp(from[i], to[i])] > 1) {
					if (w[i] > 1)
						cout << "CAN 1" << endl;
					else
						cout << "NO" << endl;
				} else {
					cout << "YES" << endl;
				}
			}
		} else if (w1 + 1 < w[i]) {
			cout << "CAN " << w1 + 1 << endl;
		} else {
			cout << "NO" << endl;
		}
	}

	return 0;
}


#include <iostream>
#include <vector>
#include <string>
#include <memory.h>
#include <set>
#include <algorithm>
#include <map>
#include <cstdlib>
#include <cstdio>
#include <queue>
#include <climits>
#include <cmath>
#include <iomanip>

#define mp make_pair
#define pb push_back
#define all(x) (x).begin(), (x).end()
#define fi first
#define se second
#define endl '\n'
#define dbgv(arr) cout << #arr << ": "; for (int i = 0; i < (int)arr.size(); i++) cout << arr[i] << " "; cout << endl;
#define dbge(el) cout << #el << ": " << el << endl;
#define dbgvv(arr) cout << #arr << ": "; for (int i = 0; i < (int)arr.size(); i++) cout << "(" << arr[i].first << " " << arr[i].second << ") "; cout << endl;
#define sz(s) ((int)(s).size())
#define re return
#define rep(i, n) for (int i = 0; i < (n); i++)

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef pair<int, int> ii;
typedef vector< pair<int, int> > vii;

template<class T> T abs(T x) { return x > 0 ? x : -x; }

const int maxn = 100000 + 100;
int n, m, s, t;
vii e[maxn];
vii e2[maxn];
int from[maxn];
int to[maxn];
int w[maxn];
bool was[maxn];
map<ii, bool> ewas;
int paths[maxn];
map<ii, int> eindex;

vll dijkstra(int v, vii *e) {
	vll d(n, LLONG_MAX);
	set< pair<ll, ll> > q;

	memset(was, 0, sizeof(was));

	d[v] = 0;
	q.insert(mp(0, v));
	was[v] = true;

	while (!q.empty()) {
		ii cur = *q.begin();
		q.erase(cur);

		ll dist = cur.fi;
		int idx = cur.se;

		rep(i, sz(e[idx])) {
			if (!was[e[idx][i].fi] && d[e[idx][i].fi] >= dist + e[idx][i].se) {
				auto it = q.lower_bound(mp(d[e[idx][i].fi], e[idx][i].fi));
				if (it != q.end()) q.erase(it);
				d[e[idx][i].fi] = dist + e[idx][i].se;
				q.insert(mp(d[e[idx][i].fi], e[idx][i].fi));
			}
		}
	}

	re d;
}

int dfs(int v, vll& d) {
	if (v == t)
		re 1;

	int ans = 0;
	rep(i, sz(e[v])) {
		if (!ewas[mp(v, i)] && d[e[v][i].fi] == d[v] + e[v][i].se) {
			ewas[mp(v, i)] = true;
			int res = dfs(e[v][i].fi, d);

			if (res > 0) {
				paths[eindex[mp(v, i)]] += res;
				ans += res;
			}

			ewas[mp(v, i)] = false;
		}
	}

	re ans;
}

int main()
{
	std::ios::sync_with_stdio(false);
	cin >> n >> m >> s >> t;
	s--;
	t--;
	rep(i, m) {
		int a, b, l;
		cin >> a >> b >> l;
		from[i] = a - 1;
		to[i] = b - 1;
		w[i] = l;
		e[a - 1].pb(mp(b - 1, l));
		eindex[mp(a - 1, sz(e[a - 1]) - 1)] = i;
		e2[b - 1].pb(mp(a - 1, l));
	}

	vll ds = dijkstra(s, &e[0]);
	vll dt = dijkstra(t, &e2[0]);

	ll best = ds[t];
	int cpaths = dfs(s, ds);

	//dbge(best);
	//dbge(cpaths);

	rep(i, m) {
		if (ds[from[i]] == LLONG_MAX || dt[to[i]] == LLONG_MAX) {
			cout << "NO" << endl;
			continue;
		}

		ll w1 = ds[from[i]] + w[i] + dt[to[i]] - best;

		//dbge(i);
		//dbge(ds[from[i]]);
		//dbge(dt[to[i]]);
		//dbge(w[i]);
		//dbge(w1);

		if (w1 == 0) {
			if (paths[i] != cpaths)
				cout << "CAN 1" << endl;
			else
				cout << "YES" << endl;
		} else if (w1 + 1 < w[i]) {
			cout << "CAN " << w1 + 1 << endl;
		} else {
			cout << "NO" << endl;
		}
	}

	return 0;
}


#include <iostream>
#include <vector>
#include <string>
#include <memory.h>
#include <set>
#include <algorithm>
#include <map>
#include <cstdlib>
#include <cstdio>
#include <queue>
#include <climits>
#include <cmath>
#include <iomanip>

#define mp make_pair
#define pb push_back
#define all(x) (x).begin(), (x).end()
#define fi first
#define se second
#define endl '\n'
#define dbgv(arr) cout << #arr << ": "; for (int i = 0; i < (int)arr.size(); i++) cout << arr[i] << " "; cout << endl;
#define dbge(el) cout << #el << ": " << el << endl;
#define dbgvv(arr) cout << #arr << ": "; for (int i = 0; i < (int)arr.size(); i++) cout << "(" << arr[i].first << " " << arr[i].second << ") "; cout << endl;
#define sz(s) ((int)(s).size())
#define re return
#define rep(i, n) for (int i = 0; i < (n); i++)

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef pair<int, int> ii;
typedef vector< pair<int, int> > vii;

template<class T> T abs(T x) { return x > 0 ? x : -x; }

const int maxn = 100000 + 100;
int n, m, s, t;
vii e[maxn];
vii e2[maxn];
int from[maxn];
int to[maxn];
int w[maxn];
bool was[maxn];
int paths[maxn];
map<ii, int> eindex;

vll dijkstra(int v, vii *e) {
	vll d(n, LLONG_MAX);
	set< pair<ll, ll> > q;

	memset(was, 0, sizeof(was));

	d[v] = 0;
	q.insert(mp(0, v));

	while (!q.empty()) {
		pair<ll, ll> cur = *q.begin();
		ll dist = cur.fi;
		int idx = cur.se;
		was[idx] = true;

		q.erase(cur);

		rep(i, sz(e[idx])) {
			if (!was[e[idx][i].fi] && d[e[idx][i].fi] > dist + e[idx][i].se) {
				auto it = q.lower_bound(mp(d[e[idx][i].fi], e[idx][i].fi));
				if (it != q.end()) q.erase(it);
				d[e[idx][i].fi] = dist + e[idx][i].se;
				q.insert(mp(d[e[idx][i].fi], e[idx][i].fi));
			}
		}
	}

	re d;
}

int dfs(int v, vll& d) {
	if (v == t)
		re 1;

	int ans = 0;
	map<int, int> cache;

	rep(i, sz(e[v])) {
		if (!was[e[v][i].fi] && d[e[v][i].fi] == d[v] + e[v][i].se) {
			was[e[v][i].fi] = true;
			int res = 0;

			if (cache.count(e[v][i].fi) > 0)
				res = cache[e[v][i].fi];
			else {
				res = dfs(e[v][i].fi, d);
				cache[e[v][i].fi] = res;
			}

			if (res > 0) {
				paths[eindex[mp(v, i)]] += res;
				ans += res;
			}

			was[e[v][i].fi] = false;
		}
	}

	re ans;
}

int main()
{
	scanf("%d%d%d%d", &n, &m, &s, &t);
	s--;
	t--;
	rep(i, m) {
		int a, b, l;
		scanf("%d%d%d", &a, &b, &l);
		from[i] = a - 1;
		to[i] = b - 1;
		w[i] = l;
		e[a - 1].pb(mp(b - 1, l));
		eindex[mp(a - 1, sz(e[a - 1]) - 1)] = i;
		e2[b - 1].pb(mp(a - 1, l));
	}

	vll ds = dijkstra(s, &e[0]);
	vll dt = dijkstra(t, &e2[0]);

	memset(was, 0, sizeof(was));
	ll best = ds[t];
	int cpaths = dfs(s, ds);

	//dbge(best);
	//dbge(cpaths);

	rep(i, m) {
		if (ds[from[i]] == LLONG_MAX || dt[to[i]] == LLONG_MAX) {
			cout << "NO" << endl;
			continue;
		}

		ll w1 = ds[from[i]] + w[i] + dt[to[i]] - best;

		//dbge(i);
		//dbge(ds[from[i]]);
		//dbge(dt[to[i]]);
		//dbge(w[i]);
		//dbge(w1);

		if (w1 == 0) {
			if (paths[i] != cpaths) {
				if (w[i] > 1) {
					cout << "CAN 1" << endl;
				} else {
					cout << "NO" << endl;
				}
			}
			else
				cout << "YES" << endl;
		} else if (w1 + 1 < w[i]) {
			cout << "CAN " << w1 + 1 << endl;
		} else {
			cout << "NO" << endl;
		}
	}

	return 0;
}


#include <iostream>
#include <vector>
#include <string>
#include <memory.h>
#include <set>
#include <algorithm>
#include <map>
#include <cstdlib>
#include <cstdio>
#include <queue>
#include <climits>
#include <cmath>
#include <iomanip>

#define mp make_pair
#define pb push_back
#define all(x) (x).begin(), (x).end()
#define fi first
#define se second
#define endl '\n'
#define dbgv(arr) cout << #arr << ": "; for (int i = 0; i < (int)arr.size(); i++) cout << arr[i] << " "; cout << endl;
#define dbge(el) cout << #el << ": " << el << endl;
#define dbgvv(arr) cout << #arr << ": "; for (int i = 0; i < (int)arr.size(); i++) cout << "(" << arr[i].first << " " << arr[i].second << ") "; cout << endl;
#define sz(s) ((int)(s).size())
#define re return
#define rep(i, n) for (int i = 0; i < (n); i++)

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef pair<int, int> ii;
typedef vector< pair<int, int> > vii;

template<class T> T abs(T x) { return x > 0 ? x : -x; }

const ll mod = 1000000000ll + 7;
const int maxn = 100000 + 100;
int n, m, s, t;
vii e[maxn];
vii e2[maxn];
int from[maxn];
int to[maxn];
int w[maxn];
bool was[maxn];
ll cnt1[maxn];
ll cnt2[maxn];

vll dijkstra(int v, vii *e, ll *cnt) {
	vll d(n, LLONG_MAX);
	set< pair<ll, ll> > q;

	memset(was, 0, sizeof(was));

	d[v] = 0;
	q.insert(mp(0, v));
	cnt[v] = 1;

	while (!q.empty()) {
		pair<ll, ll> cur = *q.begin();
		ll dist = cur.fi;
		int idx = cur.se;
		was[idx] = true;

		if (cnt[idx] <= 0) {
			dbge(idx);
			dbge(cnt[idx]);
			dbge(v);
		}

		q.erase(cur);

		rep(i, sz(e[idx])) {
			int target = e[idx][i].fi;
			if (!was[target]) {
				if (d[target] > dist + e[idx][i].se) {
					auto it = q.lower_bound(mp(d[target], target));
					if (it != q.end()) q.erase(it);
					d[target] = dist + e[idx][i].se;
					q.insert(mp(d[target], target));
					cnt[target] = cnt[idx];
				} else if (d[target] == dist + e[idx][i].se) {
					cnt[target] = (cnt[target] + cnt[idx]) % mod;
				}
			}
		}
	}

	re d;
}

int main()
{
	map<ii, int> minw;
	map<ii, int> kr;

	scanf("%d%d%d%d", &n, &m, &s, &t);
	s--;
	t--;
	rep(i, m) {
		int a, b, l;
		scanf("%d%d%d", &a, &b, &l);
		from[i] = a - 1;
		to[i] = b - 1;
		w[i] = l;
		e[a - 1].pb(mp(b - 1, l));
		e2[b - 1].pb(mp(a - 1, l));

		if (minw.count(mp(a - 1, b - 1)) == 0)
			minw[mp(a - 1, b - 1)] = w[i];
		else
			minw[mp(a - 1, b - 1)] = min(minw[mp(a - 1, b - 1)], w[i]);
	}

	rep(i, m) {
		if (minw[mp(from[i], to[i])] == w[i])
			kr[mp(from[i], to[i])]++;
	}

	vll ds = dijkstra(s, &e[0], cnt1);
	vll dt = dijkstra(t, &e2[0], cnt2);

	ll best = ds[t];
	ll cpaths = cnt1[t];

	//dbge(best);
	//dbge(cpaths);

	rep(i, m) {
		if (ds[from[i]] == LLONG_MAX || dt[to[i]] == LLONG_MAX) {
			cout << "NO" << endl;
			continue;
		}

		ll w1 = ds[from[i]] + w[i] + dt[to[i]] - best;

		if (w1 == 0) {
			if (((cnt1[from[i]] * cnt2[to[i]] % mod) * kr[mp(from[i], to[i])]) % mod != cpaths) {
				if (w[i] > 1) {
					cout << "CAN 1" << endl;
				} else {
					cout << "NO" << endl;
				}
			} else {
				if (kr[mp(from[i], to[i])] > 1 && w[i] > 1) {
					cout << "CAN 1" << endl;
				} else {
					cout << "YES" << endl;
				}
			}
		} else if (w1 + 1 < w[i]) {
			cout << "CAN " << w1 + 1 << endl;
		} else {
			cout << "NO" << endl;
		}
	}

	return 0;
}


#include <iostream>
#include <vector>
#include <string>
#include <memory.h>
#include <set>
#include <algorithm>
#include <map>
#include <cstdlib>
#include <cstdio>
#include <queue>
#include <climits>
#include <cmath>
#include <iomanip>

#define mp make_pair
#define pb push_back
#define all(x) (x).begin(), (x).end()
#define fi first
#define se second
#define endl '\n'
#define dbgv(arr) cout << #arr << ": "; for (int i = 0; i < (int)arr.size(); i++) cout << arr[i] << " "; cout << endl;
#define dbge(el) cout << #el << ": " << el << endl;
#define dbgvv(arr) cout << #arr << ": "; for (int i = 0; i < (int)arr.size(); i++) cout << "(" << arr[i].first << " " << arr[i].second << ") "; cout << endl;
#define sz(s) ((int)(s).size())
#define re return
#define rep(i, n) for (int i = 0; i < (n); i++)

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef pair<int, int> ii;
typedef vector< pair<int, int> > vii;

template<class T> T abs(T x) { return x > 0 ? x : -x; }

const int maxn = 100000 + 100;
int n, m, s, t;
vii e[maxn];
vii e2[maxn];
int from[maxn];
int to[maxn];
int w[maxn];
bool was[maxn];
map<ii, bool> ewas;
int paths[maxn];
map<ii, int> eindex;

vll dijkstra(int v, vii *e) {
	vll d(n, LLONG_MAX);
	set< pair<ll, ll> > q;

	memset(was, 0, sizeof(was));

	d[v] = 0;
	q.insert(mp(0, v));

	while (!q.empty()) {
		pair<ll, ll> cur = *q.begin();
		ll dist = cur.fi;
		int idx = cur.se;
		was[idx] = true;

		q.erase(cur);

		rep(i, sz(e[idx])) {
			if (!was[e[idx][i].fi] && d[e[idx][i].fi] >= dist + e[idx][i].se) {
				auto it = q.lower_bound(mp(d[e[idx][i].fi], e[idx][i].fi));
				if (it != q.end()) q.erase(it);
				d[e[idx][i].fi] = dist + e[idx][i].se;
				q.insert(mp(d[e[idx][i].fi], e[idx][i].fi));
			}
		}
	}

	re d;
}

int dfs(int v, vll& d) {
	if (v == t)
		re 1;

	int ans = 0;
	rep(i, sz(e[v])) {
		if (!ewas[mp(v, i)] && d[e[v][i].fi] == d[v] + e[v][i].se) {
			ewas[mp(v, i)] = true;
			int res = dfs(e[v][i].fi, d);

			if (res > 0) {
				paths[eindex[mp(v, i)]] += res;
				ans += res;
			}

			ewas[mp(v, i)] = false;
		}
	}

	re ans;
}

int main()
{
	std::ios::sync_with_stdio(false);
	cin >> n >> m >> s >> t;
	s--;
	t--;
	rep(i, m) {
		int a, b, l;
		cin >> a >> b >> l;
		from[i] = a - 1;
		to[i] = b - 1;
		w[i] = l;
		e[a - 1].pb(mp(b - 1, l));
		eindex[mp(a - 1, sz(e[a - 1]) - 1)] = i;
		e2[b - 1].pb(mp(a - 1, l));
	}

	vll ds = dijkstra(s, &e[0]);
	vll dt = dijkstra(t, &e2[0]);

	ll best = ds[t];
	int cpaths = dfs(s, ds);

	//dbge(best);
	//dbge(cpaths);

	rep(i, m) {
		if (ds[from[i]] == LLONG_MAX || dt[to[i]] == LLONG_MAX) {
			cout << "NO" << endl;
			continue;
		}

		ll w1 = ds[from[i]] + w[i] + dt[to[i]] - best;

		//dbge(i);
		//dbge(ds[from[i]]);
		//dbge(dt[to[i]]);
		//dbge(w[i]);
		//dbge(w1);

		if (w1 == 0) {
			if (paths[i] != cpaths) {
				if (w[i] > 1) {
					cout << "CAN 1" << endl;
				} else {
					cout << "NO" << endl;
				}
			}
			else
				cout << "YES" << endl;
		} else if (w1 + 1 < w[i]) {
			cout << "CAN " << w1 + 1 << endl;
		} else {
			cout << "NO" << endl;
		}
	}

	return 0;
}


#include <iostream>
#include <vector>
#include <string>
#include <memory.h>
#include <set>
#include <algorithm>
#include <map>
#include <cstdlib>
#include <cstdio>
#include <queue>
#include <climits>
#include <cmath>
#include <iomanip>

#define mp make_pair
#define pb push_back
#define all(x) (x).begin(), (x).end()
#define fi first
#define se second
#define endl '\n'
#define dbgv(arr) cout << #arr << ": "; for (int i = 0; i < (int)arr.size(); i++) cout << arr[i] << " "; cout << endl;
#define dbge(el) cout << #el << ": " << el << endl;
#define dbgvv(arr) cout << #arr << ": "; for (int i = 0; i < (int)arr.size(); i++) cout << "(" << arr[i].first << " " << arr[i].second << ") "; cout << endl;
#define sz(s) ((int)(s).size())
#define re return
#define rep(i, n) for (int i = 0; i < (n); i++)

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef pair<int, int> ii;
typedef vector< pair<int, int> > vii;

template<class T> T abs(T x) { return x > 0 ? x : -x; }

const ll mod = 1000000000ll + 7;
const int maxn = 100000 + 100;
int n, m, s, t;
vii e[maxn];
vii e2[maxn];
int from[maxn];
int to[maxn];
int w[maxn];
bool was[maxn];
ll cnt1[maxn];
ll cnt2[maxn];

vll dijkstra(int v, vii *e, ll *cnt) {
	vll d(n, LLONG_MAX);
	set< pair<ll, ll> > q;

	memset(was, 0, sizeof(was));

	d[v] = 0;
	q.insert(mp(0, v));
	cnt[v] = 1;

	while (!q.empty()) {
		pair<ll, ll> cur = *q.begin();
		ll dist = cur.fi;
		int idx = cur.se;
		was[idx] = true;

		if (cnt[idx] <= 0) {
			dbge(idx);
			dbge(cnt[idx]);
			dbge(v);
		}

		q.erase(cur);

		rep(i, sz(e[idx])) {
			int target = e[idx][i].fi;
			if (!was[target]) {
				if (d[target] > dist + e[idx][i].se) {
					auto it = q.lower_bound(mp(d[target], target));
					if (it != q.end()) q.erase(it);
					d[target] = dist + e[idx][i].se;
					q.insert(mp(d[target], target));
					cnt[target] = cnt[idx];
				} else if (d[target] == dist + e[idx][i].se) {
					cnt[target] = (cnt[target] + cnt[idx]) % mod;
				}
			}
		}
	}

	re d;
}

int main()
{
	map<ii, int> minw;
	map<ii, int> kr;

	scanf("%d%d%d%d", &n, &m, &s, &t);
	s--;
	t--;
	rep(i, m) {
		int a, b, l;
		scanf("%d%d%d", &a, &b, &l);
		from[i] = a - 1;
		to[i] = b - 1;
		w[i] = l;
		e[a - 1].pb(mp(b - 1, l));
		e2[b - 1].pb(mp(a - 1, l));

		if (minw.count(mp(a - 1, b - 1)) == 0)
			minw[mp(a - 1, b - 1)] = w[i];
		else
			minw[mp(a - 1, b - 1)] = min(minw[mp(a - 1, b - 1)], w[i]);
	}

	rep(i, m) {
		if (minw[mp(from[i], to[i])] == w[i])
			kr[mp(from[i], to[i])]++;
	}

	vll ds = dijkstra(s, &e[0], cnt1);
	vll dt = dijkstra(t, &e2[0], cnt2);

	ll best = ds[t];
	ll cpaths = cnt1[t];

	//dbge(best);
	//dbge(cpaths);

	rep(i, m) {
		if (ds[from[i]] == LLONG_MAX || dt[to[i]] == LLONG_MAX) {
			cout << "NO" << endl;
			continue;
		}

		ll w1 = ds[from[i]] + w[i] + dt[to[i]] - best;

		if (w1 == 0) {
			if (cnt1[from[i]] * cnt2[to[i]] * kr[mp(from[i], to[i])] != cpaths) {
				if (w[i] > 1) {
					cout << "CAN 1" << endl;
				} else {
					cout << "NO" << endl;
				}
			} else {
				if (kr[mp(from[i], to[i])] > 1 && w[i] > 1) {
					cout << "CAN 1" << endl;
				} else {
					cout << "YES" << endl;

					if (from[i] == 8734 && to[i] == 10494) {
						dbge(i);
						dbge(best);
						dbge(cpaths);
						dbge(ds[from[i]]);
						dbge(dt[to[i]]);
						dbge(cnt1[from[i]]);
						dbge(cnt2[to[i]]);
						dbge(w[i]);
						dbge(w1);
						dbge(kr[mp(from[i], to[i])]);
						dbge(minw[mp(from[i], to[i])]);
					}
				}
			}
		} else if (w1 + 1 < w[i]) {
			cout << "CAN " << w1 + 1 << endl;
		} else {
			cout << "NO" << endl;
		}
	}

	return 0;
}


#include <iostream>
#include <vector>
#include <string>
#include <memory.h>
#include <set>
#include <algorithm>
#include <map>
#include <cstdlib>
#include <cstdio>
#include <queue>
#include <climits>
#include <cmath>
#include <iomanip>

#define mp make_pair
#define pb push_back
#define all(x) (x).begin(), (x).end()
#define fi first
#define se second
#define endl '\n'
#define dbgv(arr) cout << #arr << ": "; for (int i = 0; i < (int)arr.size(); i++) cout << arr[i] << " "; cout << endl;
#define dbge(el) cout << #el << ": " << el << endl;
#define dbgvv(arr) cout << #arr << ": "; for (int i = 0; i < (int)arr.size(); i++) cout << "(" << arr[i].first << " " << arr[i].second << ") "; cout << endl;
#define sz(s) ((int)(s).size())
#define re return
#define rep(i, n) for (int i = 0; i < (n); i++)

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef pair<int, int> ii;
typedef vector< pair<int, int> > vii;

template<class T> T abs(T x) { return x > 0 ? x : -x; }

const ll mod = 1000000000ll + 7;
const int maxn = 100000 + 100;
int n, m, s, t;
vii e[maxn];
vii e2[maxn];
int from[maxn];
int to[maxn];
int w[maxn];
bool was[maxn];
ll cnt1[maxn];
ll cnt2[maxn];

vll dijkstra(int v, vii *e, ll *cnt) {
	vll d(n, LLONG_MAX);
	set< pair<ll, ll> > q;

	memset(was, 0, sizeof(was));

	d[v] = 0;
	q.insert(mp(0, v));
	cnt[v] = 1;

	while (!q.empty()) {
		pair<ll, ll> cur = *q.begin();
		ll dist = cur.fi;
		int idx = cur.se;
		was[idx] = true;

		q.erase(cur);

		rep(i, sz(e[idx])) {
			int target = e[idx][i].fi;
			if (!was[target]) {
				if (d[target] > dist + e[idx][i].se) {
					auto it = q.lower_bound(mp(d[target], target));
					if (it != q.end()) q.erase(it);
					d[target] = dist + e[idx][i].se;
					q.insert(mp(d[target], target));
					cnt[target] = cnt[idx];
				} else if (d[target] == dist + e[idx][i].se) {
					cnt[target] = (cnt[target] + cnt[idx]) % mod;
				}
			}
		}
	}

	re d;
}

int main()
{
	map<ii, int> minw;
	map<ii, int> kr;

	scanf("%d%d%d%d", &n, &m, &s, &t);
	s--;
	t--;
	rep(i, m) {
		int a, b, l;
		scanf("%d%d%d", &a, &b, &l);
		from[i] = a - 1;
		to[i] = b - 1;
		w[i] = l;
		e[a - 1].pb(mp(b - 1, l));
		e2[b - 1].pb(mp(a - 1, l));

		if (minw.count(mp(a - 1, b - 1)) == 0)
			minw[mp(a - 1, b - 1)] = w[i];
		else
			minw[mp(a - 1, b - 1)] = min(minw[mp(a - 1, b - 1)], w[i]);
	}

	rep(i, m) {
		if (minw[mp(from[i], to[i])] == w[i])
			kr[mp(from[i], to[i])]++;
	}

	vll ds = dijkstra(s, &e[0], cnt1);
	vll dt = dijkstra(t, &e2[0], cnt2);

	ll best = ds[t];
	ll cpaths = cnt1[t];

	rep(i, m) {
		if (ds[from[i]] == LLONG_MAX || dt[to[i]] == LLONG_MAX) {
			cout << "NO" << endl;
			continue;
		}

		ll w1 = ds[from[i]] + w[i] + dt[to[i]] - best;

		if (w1 == 0) {
			if (((cnt1[from[i]] * cnt2[to[i]] % mod) * kr[mp(from[i], to[i])]) % mod != cpaths) {
				if (w[i] > 1) {
					cout << "CAN 1" << endl;
				} else {
					cout << "NO" << endl;
				}
			} else {
				if (kr[mp(from[i], to[i])] > 1 && w[i] > 1) {
					cout << "CAN 1" << endl;
				} else {
					cout << "YES" << endl;
				}
			}
		} else if (w1 + 1 < w[i]) {
			cout << "CAN " << w1 + 1 << endl;
		} else {
			cout << "NO" << endl;
		}
	}

	return 0;
}


#include <iostream>
#include <vector>
#include <string>
#include <memory.h>
#include <set>
#include <algorithm>
#include <map>
#include <cstdlib>
#include <cstdio>
#include <queue>
#include <climits>
#include <cmath>
#include <iomanip>

#define mp make_pair
#define pb push_back
#define all(x) (x).begin(), (x).end()
#define fi first
#define se second
#define endl '\n'
#define dbgv(arr) cout << #arr << ": "; for (int i = 0; i < (int)arr.size(); i++) cout << arr[i] << " "; cout << endl;
#define dbge(el) cout << #el << ": " << el << endl;
#define dbgvv(arr) cout << #arr << ": "; for (int i = 0; i < (int)arr.size(); i++) cout << "(" << arr[i].first << " " << arr[i].second << ") "; cout << endl;
#define sz(s) ((int)(s).size())
#define re return
#define rep(i, n) for (int i = 0; i < (n); i++)

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef pair<int, int> ii;
typedef vector< pair<int, int> > vii;

template<class T> T abs(T x) { return x > 0 ? x : -x; }

const int maxn = 100000 + 100;
int n, m, s, t;
vii e[maxn];
vii e2[maxn];
int from[maxn];
int to[maxn];
int w[maxn];
bool was[maxn];
ll cnt1[maxn];
ll cnt2[maxn];

vll dijkstra(int v, vii *e, ll *cnt) {
	vll d(n, LLONG_MAX);
	set< pair<ll, ll> > q;

	memset(was, 0, sizeof(was));

	d[v] = 0;
	q.insert(mp(0, v));
	cnt[v] = 1;

	while (!q.empty()) {
		pair<ll, ll> cur = *q.begin();
		ll dist = cur.fi;
		int idx = cur.se;
		was[idx] = true;

		q.erase(cur);

		rep(i, sz(e[idx])) {
			if (!was[e[idx][i].fi]) {
				if (d[e[idx][i].fi] > dist + e[idx][i].se) {
					auto it = q.lower_bound(mp(d[e[idx][i].fi], e[idx][i].fi));
					if (it != q.end()) q.erase(it);
					d[e[idx][i].fi] = dist + e[idx][i].se;
					q.insert(mp(d[e[idx][i].fi], e[idx][i].fi));
					cnt[e[idx][i].fi] = cnt[idx];
				} else if (d[e[idx][i].fi] == dist + e[idx][i].se) {
					cnt[e[idx][i].fi] += cnt[idx];
				}
			}
		}
	}

	re d;
}

int main()
{
	map<ii, int> minw;
	map<ii, int> kr;

	scanf("%d%d%d%d", &n, &m, &s, &t);
	s--;
	t--;
	rep(i, m) {
		int a, b, l;
		scanf("%d%d%d", &a, &b, &l);
		from[i] = a - 1;
		to[i] = b - 1;
		w[i] = l;
		e[a - 1].pb(mp(b - 1, l));
		e2[b - 1].pb(mp(a - 1, l));

		if (minw.count(mp(a - 1, b - 1)) == 0)
			minw[mp(a - 1, b - 1)] = w[i];
		else
			minw[mp(a - 1, b - 1)] = min(minw[mp(a - 1, b - 1)], w[i]);
	}

	rep(i, m) {
		if (minw[mp(from[i], to[i])] == w[i])
			kr[mp(from[i], to[i])]++;
	}

	vll ds = dijkstra(s, &e[0], cnt1);
	vll dt = dijkstra(t, &e2[0], cnt2);

	ll best = ds[t];
	ll cpaths = cnt1[t];

	//dbge(best);
	//dbge(cpaths);

	rep(i, m) {
		if (ds[from[i]] == LLONG_MAX || dt[to[i]] == LLONG_MAX) {
			cout << "NO" << endl;
			continue;
		}

		ll w1 = ds[from[i]] + w[i] + dt[to[i]] - best;

		//dbge(i);
		//dbge(ds[from[i]]);
		//dbge(dt[to[i]]);
		//dbge(w[i]);
		//dbge(w1);

		if (w1 == 0) {
			if (cnt1[from[i]] * cnt2[to[i]] * kr[mp(from[i], to[i])] != cpaths) {
				if (w[i] > 1) {
					cout << "CAN 1" << endl;
				} else {
					cout << "NO" << endl;
				}
			} else {
				if (kr[mp(from[i], to[i])] > 1) {
					cout << "CAN 1" << endl;
				} else {
					cout << "YES" << endl;
				}
			}
		} else if (w1 + 1 < w[i]) {
			cout << "CAN " << w1 + 1 << endl;
		} else {
			cout << "NO" << endl;
		}
	}

	return 0;
}


#include <iostream>
#include <vector>
#include <string>
#include <memory.h>
#include <set>
#include <algorithm>
#include <map>
#include <cstdlib>
#include <cstdio>
#include <queue>
#include <climits>
#include <cmath>
#include <iomanip>

#define mp make_pair
#define pb push_back
#define all(x) (x).begin(), (x).end()
#define fi first
#define se second
#define endl '\n'
#define dbgv(arr) cout << #arr << ": "; for (int i = 0; i < (int)arr.size(); i++) cout << arr[i] << " "; cout << endl;
#define dbge(el) cout << #el << ": " << el << endl;
#define dbgvv(arr) cout << #arr << ": "; for (int i = 0; i < (int)arr.size(); i++) cout << "(" << arr[i].first << " " << arr[i].second << ") "; cout << endl;
#define sz(s) ((int)(s).size())
#define re return
#define rep(i, n) for (int i = 0; i < (n); i++)

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef pair<int, int> ii;
typedef vector< pair<int, int> > vii;

template<class T> T abs(T x) { return x > 0 ? x : -x; }

const int maxn = 100000 + 100;
int n, m, s, t;
vii e[maxn];
vii e2[maxn];
int from[maxn];
int to[maxn];
int w[maxn];
bool was[maxn];
map<ii, bool> ewas;
int paths[maxn];
map<ii, int> eindex;

vll dijkstra(int v, vii *e) {
	vll d(n, LLONG_MAX);
	set< pair<ll, ll> > q;

	memset(was, 0, sizeof(was));

	d[v] = 0;
	q.insert(mp(0, v));
	was[v] = true;

	while (!q.empty()) {
		ii cur = *q.begin();
		q.erase(cur);

		ll dist = cur.fi;
		int idx = cur.se;

		rep(i, sz(e[idx])) {
			if (!was[e[idx][i].fi] && d[e[idx][i].fi] >= dist + e[idx][i].se) {
				auto it = q.lower_bound(mp(d[e[idx][i].fi], e[idx][i].fi));
				if (it != q.end()) q.erase(it);
				d[e[idx][i].fi] = dist + e[idx][i].se;
				q.insert(mp(d[e[idx][i].fi], e[idx][i].fi));
			}
		}
	}

	re d;
}

int dfs(int v, vll& d) {
	if (v == t)
		re 1;

	int ans = 0;
	rep(i, sz(e[v])) {
		if (!ewas[mp(v, i)] && d[e[v][i].fi] == d[v] + e[v][i].se) {
			ewas[mp(v, i)] = true;
			int res = dfs(e[v][i].fi, d);

			if (res > 0) {
				paths[eindex[mp(v, i)]] += res;
				ans += res;
			}

			ewas[mp(v, i)] = false;
		}
	}

	re ans;
}

int main()
{
	std::ios::sync_with_stdio(false);
	cin >> n >> m >> s >> t;
	s--;
	t--;
	rep(i, m) {
		int a, b, l;
		cin >> a >> b >> l;
		from[i] = a - 1;
		to[i] = b - 1;
		w[i] = l;
		e[a - 1].pb(mp(b - 1, l));
		eindex[mp(a - 1, sz(e[a - 1]) - 1)] = i;
		e2[b - 1].pb(mp(a - 1, l));
	}

	vll ds = dijkstra(s, &e[0]);
	vll dt = dijkstra(t, &e2[0]);

	ll best = ds[t];
	int cpaths = dfs(s, ds);

	//dbge(best);
	//dbge(cpaths);

	rep(i, m) {
		if (ds[from[i]] == LLONG_MAX || dt[to[i]] == LLONG_MAX) {
			cout << "NO" << endl;
			continue;
		}

		ll w1 = ds[from[i]] + w[i] + dt[to[i]] - best;

		//dbge(i);
		//dbge(ds[from[i]]);
		//dbge(dt[to[i]]);
		//dbge(w[i]);
		//dbge(w1);

		if (w1 == 0) {
			if (paths[i] != cpaths) {
				if (w[i] > 1) {
					cout << "CAN 1" << endl;
				} else {
					cout << "NO" << endl;
				}
			}
			else
				cout << "YES" << endl;
		} else if (w1 + 1 < w[i]) {
			cout << "CAN " << w1 + 1 << endl;
		} else {
			cout << "NO" << endl;
		}
	}

	return 0;
}


#include <iostream>
#include <vector>
#include <string>
#include <memory.h>
#include <set>
#include <algorithm>
#include <map>
#include <cstdlib>
#include <cstdio>
#include <queue>
#include <climits>
#include <cmath>
#include <iomanip>

#define mp make_pair
#define pb push_back
#define all(x) (x).begin(), (x).end()
#define fi first
#define se second
#define endl '\n'
#define dbgv(arr) cout << #arr << ": "; for (int i = 0; i < (int)arr.size(); i++) cout << arr[i] << " "; cout << endl;
#define dbge(el) cout << #el << ": " << el << endl;
#define dbgvv(arr) cout << #arr << ": "; for (int i = 0; i < (int)arr.size(); i++) cout << "(" << arr[i].first << " " << arr[i].second << ") "; cout << endl;
#define sz(s) ((int)(s).size())
#define re return
#define rep(i, n) for (int i = 0; i < (n); i++)

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef pair<int, int> ii;
typedef vector< pair<int, int> > vii;

template<class T> T abs(T x) { return x > 0 ? x : -x; }

const int maxn = 100000 + 100;
int n, m, s, t;
vii e[maxn];
vii e2[maxn];
int from[maxn];
int to[maxn];
int w[maxn];
bool was[maxn];
ll cnt1[maxn];
ll cnt2[maxn];

vll dijkstra(int v, vii *e, ll *cnt) {
	vll d(n, LLONG_MAX);
	set< pair<ll, ll> > q;

	memset(was, 0, sizeof(was));

	d[v] = 0;
	q.insert(mp(0, v));
	cnt[v] = 1;

	while (!q.empty()) {
		pair<ll, ll> cur = *q.begin();
		ll dist = cur.fi;
		int idx = cur.se;
		was[idx] = true;

		if (cnt[idx] <= 0) {
			dbge(idx);
			dbge(cnt[idx]);
			dbge(v);
		}

		q.erase(cur);

		rep(i, sz(e[idx])) {
			int target = e[idx][i].fi;
			if (!was[target]) {
				if (d[target] > dist + e[idx][i].se) {
					auto it = q.lower_bound(mp(d[target], target));
					if (it != q.end()) q.erase(it);
					d[target] = dist + e[idx][i].se;
					q.insert(mp(d[target], target));
					cnt[target] = cnt[idx];
				} else if (d[target] == dist + e[idx][i].se) {
					cnt[target] += cnt[idx];
				}
			}
		}
	}

	re d;
}

int main()
{
	map<ii, int> minw;
	map<ii, int> kr;

	scanf("%d%d%d%d", &n, &m, &s, &t);
	s--;
	t--;
	rep(i, m) {
		int a, b, l;
		scanf("%d%d%d", &a, &b, &l);
		from[i] = a - 1;
		to[i] = b - 1;
		w[i] = l;
		e[a - 1].pb(mp(b - 1, l));
		e2[b - 1].pb(mp(a - 1, l));

		if (minw.count(mp(a - 1, b - 1)) == 0)
			minw[mp(a - 1, b - 1)] = w[i];
		else
			minw[mp(a - 1, b - 1)] = min(minw[mp(a - 1, b - 1)], w[i]);
	}

	rep(i, m) {
		if (minw[mp(from[i], to[i])] == w[i])
			kr[mp(from[i], to[i])]++;
	}

	vll ds = dijkstra(s, &e[0], cnt1);
	vll dt = dijkstra(t, &e2[0], cnt2);

	ll best = ds[t];
	ll cpaths = cnt1[t];

	//dbge(best);
	//dbge(cpaths);

	rep(i, m) {
		if (ds[from[i]] == LLONG_MAX || dt[to[i]] == LLONG_MAX) {
			cout << "NO" << endl;
			continue;
		}

		ll w1 = ds[from[i]] + w[i] + dt[to[i]] - best;

		if (w1 == 0) {
			if (cnt1[from[i]] * cnt2[to[i]] * kr[mp(from[i], to[i])] != cpaths) {
				if (w[i] > 1) {
					cout << "CAN 1" << endl;
				} else {
					cout << "NO" << endl;
				}
			} else {
				if (kr[mp(from[i], to[i])] > 1 && w[i] > 1) {
					cout << "CAN 1" << endl;
				} else {
					cout << "YES" << endl;

					if (0 && from[i] == 8734 && to[i] == 10494) {
						dbge(i);
						dbge(best);
						dbge(cpaths);
						dbge(ds[from[i]]);
						dbge(dt[to[i]]);
						dbge(cnt1[from[i]]);
						dbge(cnt2[to[i]]);
						dbge(w[i]);
						dbge(w1);
						dbge(kr[mp(from[i], to[i])]);
						dbge(minw[mp(from[i], to[i])]);
					}
				}
			}
		} else if (w1 + 1 < w[i]) {
			cout << "CAN " << w1 + 1 << endl;
		} else {
			cout << "NO" << endl;
		}
	}

	return 0;
}


#include <iostream>
#include <vector>
#include <string>
#include <memory.h>
#include <set>
#include <algorithm>
#include <map>
#include <cstdlib>
#include <cstdio>
#include <queue>
#include <climits>
#include <cmath>
#include <iomanip>

#define mp make_pair
#define pb push_back
#define all(x) (x).begin(), (x).end()
#define fi first
#define se second
#define endl '\n'
#define dbgv(arr) cout << #arr << ": "; for (int i = 0; i < (int)arr.size(); i++) cout << arr[i] << " "; cout << endl;
#define dbge(el) cout << #el << ": " << el << endl;
#define dbgvv(arr) cout << #arr << ": "; for (int i = 0; i < (int)arr.size(); i++) cout << "(" << arr[i].first << " " << arr[i].second << ") "; cout << endl;
#define sz(s) ((int)(s).size())
#define re return
#define rep(i, n) for (int i = 0; i < (n); i++)

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef pair<int, int> ii;
typedef vector< pair<int, int> > vii;

template<class T> T abs(T x) { return x > 0 ? x : -x; }

const int maxn = 100000 + 100;
int n, m, s, t;
vii e[maxn];
vii e2[maxn];
int from[maxn];
int to[maxn];
int w[maxn];
bool was[maxn];
int paths[maxn];
map<ii, int> eindex;

vll dijkstra(int v, vii *e) {
	vll d(n, LLONG_MAX);
	set< pair<ll, ll> > q;

	memset(was, 0, sizeof(was));

	d[v] = 0;
	q.insert(mp(0, v));

	while (!q.empty()) {
		pair<ll, ll> cur = *q.begin();
		ll dist = cur.fi;
		int idx = cur.se;
		was[idx] = true;

		q.erase(cur);

		rep(i, sz(e[idx])) {
			if (!was[e[idx][i].fi] && d[e[idx][i].fi] > dist + e[idx][i].se) {
				auto it = q.lower_bound(mp(d[e[idx][i].fi], e[idx][i].fi));
				if (it != q.end()) q.erase(it);
				d[e[idx][i].fi] = dist + e[idx][i].se;
				q.insert(mp(d[e[idx][i].fi], e[idx][i].fi));
			}
		}
	}

	re d;
}

int dfs(int v, vll& d) {
	if (v == t)
		re 1;

	int ans = 0;
	rep(i, sz(e[v])) {
		if (!was[e[v][i].fi] && d[e[v][i].fi] == d[v] + e[v][i].se) {
			was[e[v][i].fi] = true;
			int res = dfs(e[v][i].fi, d);

			if (res > 0) {
				paths[eindex[mp(v, i)]] += res;
				ans += res;
			}

			was[e[v][i].fi] = false;
		}
	}

	re ans;
}

int main()
{
	scanf("%d%d%d%d", &n, &m, &s, &t);
	s--;
	t--;
	rep(i, m) {
		int a, b, l;
		scanf("%d%d%d", &a, &b, &l);
		from[i] = a - 1;
		to[i] = b - 1;
		w[i] = l;
		e[a - 1].pb(mp(b - 1, l));
		eindex[mp(a - 1, sz(e[a - 1]) - 1)] = i;
		e2[b - 1].pb(mp(a - 1, l));
	}

	vll ds = dijkstra(s, &e[0]);
	vll dt = dijkstra(t, &e2[0]);

	memset(was, 0, sizeof(was));
	ll best = ds[t];
	int cpaths = dfs(s, ds);

	//dbge(best);
	//dbge(cpaths);

	rep(i, m) {
		if (ds[from[i]] == LLONG_MAX || dt[to[i]] == LLONG_MAX) {
			cout << "NO" << endl;
			continue;
		}

		ll w1 = ds[from[i]] + w[i] + dt[to[i]] - best;

		//dbge(i);
		//dbge(ds[from[i]]);
		//dbge(dt[to[i]]);
		//dbge(w[i]);
		//dbge(w1);

		if (w1 == 0) {
			if (paths[i] != cpaths) {
				if (w[i] > 1) {
					cout << "CAN 1" << endl;
				} else {
					cout << "NO" << endl;
				}
			}
			else
				cout << "YES" << endl;
		} else if (w1 + 1 < w[i]) {
			cout << "CAN " << w1 + 1 << endl;
		} else {
			cout << "NO" << endl;
		}
	}

	return 0;
}


#include <iostream>
#include <vector>
#include <string>
#include <memory.h>
#include <set>
#include <algorithm>
#include <map>
#include <cstdlib>
#include <cstdio>
#include <queue>
#include <climits>
#include <cmath>
#include <iomanip>

#define mp make_pair
#define pb push_back
#define all(x) (x).begin(), (x).end()
#define fi first
#define se second
#define endl '\n'
#define dbgv(arr) cout << #arr << ": "; for (int i = 0; i < (int)arr.size(); i++) cout << arr[i] << " "; cout << endl;
#define dbge(el) cout << #el << ": " << el << endl;
#define dbgvv(arr) cout << #arr << ": "; for (int i = 0; i < (int)arr.size(); i++) cout << "(" << arr[i].first << " " << arr[i].second << ") "; cout << endl;
#define sz(s) ((int)(s).size())
#define re return
#define rep(i, n) for (int i = 0; i < (n); i++)

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef pair<int, int> ii;
typedef vector< pair<int, int> > vii;

template<class T> T abs(T x) { return x > 0 ? x : -x; }

const int maxn = 100000 + 100;
int n, m, s, t;
vii e[maxn];
vii e2[maxn];
int from[maxn];
int to[maxn];
int w[maxn];
bool was[maxn];
ll cnt1[maxn];
ll cnt2[maxn];

vll dijkstra(int v, vii *e, ll *cnt) {
	vll d(n, LLONG_MAX);
	set< pair<ll, ll> > q;

	memset(was, 0, sizeof(was));

	d[v] = 0;
	q.insert(mp(0, v));
	cnt[v] = 1;

	while (!q.empty()) {
		pair<ll, ll> cur = *q.begin();
		ll dist = cur.fi;
		int idx = cur.se;
		was[idx] = true;

		q.erase(cur);

		rep(i, sz(e[idx])) {
			if (!was[e[idx][i].fi]) {
				if (d[e[idx][i].fi] > dist + e[idx][i].se) {
					auto it = q.lower_bound(mp(d[e[idx][i].fi], e[idx][i].fi));
					if (it != q.end()) q.erase(it);
					d[e[idx][i].fi] = dist + e[idx][i].se;
					q.insert(mp(d[e[idx][i].fi], e[idx][i].fi));
					cnt[e[idx][i].fi] = cnt[idx];
				} else if (d[e[idx][i].fi] == dist + e[idx][i].se) {
					cnt[e[idx][i].fi] += cnt[idx];
				}
			}
		}
	}

	re d;
}

int main()
{
	map<ii, int> minw;
	map<ii, int> kr;

	scanf("%d%d%d%d", &n, &m, &s, &t);
	s--;
	t--;
	rep(i, m) {
		int a, b, l;
		scanf("%d%d%d", &a, &b, &l);
		from[i] = a - 1;
		to[i] = b - 1;
		w[i] = l;
		e[a - 1].pb(mp(b - 1, l));
		e2[b - 1].pb(mp(a - 1, l));

		if (minw.count(mp(a - 1, b - 1)) == 0)
			minw[mp(a - 1, b - 1)] = w[i];
		else
			minw[mp(a - 1, b - 1)] = min(minw[mp(a - 1, b - 1)], w[i]);
	}

	rep(i, m) {
		if (minw[mp(from[i], to[i])] == w[i])
			kr[mp(from[i], to[i])]++;
	}

	vll ds = dijkstra(s, &e[0], cnt1);
	vll dt = dijkstra(t, &e2[0], cnt2);

	ll best = ds[t];
	ll cpaths = cnt1[t];

	//dbge(best);
	//dbge(cpaths);

	rep(i, m) {
		if (ds[from[i]] == LLONG_MAX || dt[to[i]] == LLONG_MAX) {
			cout << "NO" << endl;
			continue;
		}

		ll w1 = ds[from[i]] + w[i] + dt[to[i]] - best;

		//dbge(i);
		//dbge(ds[from[i]]);
		//dbge(dt[to[i]]);
		//dbge(w[i]);
		//dbge(w1);

		if (w1 == 0) {
			if (cnt1[from[i]] * cnt2[to[i]] * kr[mp(from[i], to[i])] != cpaths) {
				if (w[i] > 1) {
					cout << "CAN 1" << endl;
				} else {
					cout << "NO" << endl;
				}
			}
			else
				cout << "YES" << endl;
		} else if (w1 + 1 < w[i]) {
			cout << "CAN " << w1 + 1 << endl;
		} else {
			cout << "NO" << endl;
		}
	}

	return 0;
}


#include <iostream>
#include <vector>
#include <string>
#include <memory.h>
#include <set>
#include <algorithm>
#include <map>
#include <cstdlib>
#include <cstdio>
#include <queue>
#include <climits>
#include <cmath>
#include <iomanip>

#define mp make_pair
#define pb push_back
#define all(x) (x).begin(), (x).end()
#define fi first
#define se second
#define endl '\n'
#define dbgv(arr) cout << #arr << ": "; for (int i = 0; i < (int)arr.size(); i++) cout << arr[i] << " "; cout << endl;
#define dbge(el) cout << #el << ": " << el << endl;
#define dbgvv(arr) cout << #arr << ": "; for (int i = 0; i < (int)arr.size(); i++) cout << "(" << arr[i].first << " " << arr[i].second << ") "; cout << endl;
#define sz(s) ((int)(s).size())
#define re return
#define rep(i, n) for (int i = 0; i < (n); i++)

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef pair<int, int> ii;
typedef vector< pair<int, int> > vii;

template<class T> T abs(T x) { return x > 0 ? x : -x; }

const int maxn = 100000 + 100;
int n, m, s, t;
vii e[maxn];
vii e2[maxn];
int from[maxn];
int to[maxn];
int w[maxn];
bool was[maxn];
map<ii, bool> ewas;
int paths[maxn];
map<ii, int> eindex;

vll dijkstra(int v, vii *e) {
	vll d(n, LLONG_MAX);
	set< pair<ll, ll> > q;

	memset(was, 0, sizeof(was));

	d[v] = 0;
	q.insert(mp(0, v));

	while (!q.empty()) {
		pair<ll, ll> cur = *q.begin();
		ll dist = cur.fi;
		int idx = cur.se;
		was[idx] = true;

		q.erase(cur);

		rep(i, sz(e[idx])) {
			if (!was[e[idx][i].fi] && d[e[idx][i].fi] > dist + e[idx][i].se) {
				auto it = q.lower_bound(mp(d[e[idx][i].fi], e[idx][i].fi));
				if (it != q.end()) q.erase(it);
				d[e[idx][i].fi] = dist + e[idx][i].se;
				q.insert(mp(d[e[idx][i].fi], e[idx][i].fi));
			}
		}
	}

	re d;
}

int dfs(int v, vll& d) {
	if (v == t)
		re 1;

	int ans = 0;
	rep(i, sz(e[v])) {
		if (!ewas[mp(v, i)] && d[e[v][i].fi] == d[v] + e[v][i].se) {
			ewas[mp(v, i)] = true;
			int res = dfs(e[v][i].fi, d);

			if (res > 0) {
				paths[eindex[mp(v, i)]] += res;
				ans += res;
			}

			ewas[mp(v, i)] = false;
		}
	}

	re ans;
}

int main()
{
	scanf("%d%d%d%d", &n, &m, &s, &t);
	s--;
	t--;
	rep(i, m) {
		int a, b, l;
		scanf("%d%d%d", &a, &b, &l);
		from[i] = a - 1;
		to[i] = b - 1;
		w[i] = l;
		e[a - 1].pb(mp(b - 1, l));
		eindex[mp(a - 1, sz(e[a - 1]) - 1)] = i;
		e2[b - 1].pb(mp(a - 1, l));
	}

	vll ds = dijkstra(s, &e[0]);
	vll dt = dijkstra(t, &e2[0]);

	ll best = ds[t];
	int cpaths = dfs(s, ds);

	//dbge(best);
	//dbge(cpaths);

	rep(i, m) {
		if (ds[from[i]] == LLONG_MAX || dt[to[i]] == LLONG_MAX) {
			cout << "NO" << endl;
			continue;
		}

		ll w1 = ds[from[i]] + w[i] + dt[to[i]] - best;

		//dbge(i);
		//dbge(ds[from[i]]);
		//dbge(dt[to[i]]);
		//dbge(w[i]);
		//dbge(w1);

		if (w1 == 0) {
			if (paths[i] != cpaths) {
				if (w[i] > 1) {
					cout << "CAN 1" << endl;
				} else {
					cout << "NO" << endl;
				}
			}
			else
				cout << "YES" << endl;
		} else if (w1 + 1 < w[i]) {
			cout << "CAN " << w1 + 1 << endl;
		} else {
			cout << "NO" << endl;
		}
	}

	return 0;
}


#include <iostream>
#include <vector>
#include <string>
#include <memory.h>
#include <set>
#include <algorithm>
#include <map>
#include <cstdlib>
#include <cstdio>
#include <queue>
#include <climits>
#include <cmath>
#include <iomanip>

#define mp make_pair
#define pb push_back
#define all(x) (x).begin(), (x).end()
#define fi first
#define se second
#define endl '\n'
#define dbgv(arr) cout << #arr << ": "; for (int i = 0; i < (int)arr.size(); i++) cout << arr[i] << " "; cout << endl;
#define dbge(el) cout << #el << ": " << el << endl;
#define dbgvv(arr) cout << #arr << ": "; for (int i = 0; i < (int)arr.size(); i++) cout << "(" << arr[i].first << " " << arr[i].second << ") "; cout << endl;
#define sz(s) ((int)(s).size())
#define re return
#define rep(i, n) for (int i = 0; i < (n); i++)

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef pair<int, int> ii;
typedef vector< pair<int, int> > vii;

template<class T> T abs(T x) { return x > 0 ? x : -x; }

const int maxn = 100000 + 100;
int n, m, s, t;
vii e[maxn];
vii e2[maxn];
int from[maxn];
int to[maxn];
int w[maxn];
bool was[maxn];
map<ii, bool> ewas;
int paths[maxn];
map<ii, int> eindex;

vll dijkstra(int v, vii *e) {
	vll d(n, LLONG_MAX);
	set< pair<ll, ll> > q;

	memset(was, 0, sizeof(was));

	d[v] = 0;
	q.insert(mp(0, v));
	was[v] = true;

	while (!q.empty()) {
		pair<ll, ll> cur = *q.begin();
		q.erase(cur);

		ll dist = cur.fi;
		int idx = cur.se;

		rep(i, sz(e[idx])) {
			if (!was[e[idx][i].fi] && d[e[idx][i].fi] >= dist + e[idx][i].se) {
				auto it = q.lower_bound(mp(d[e[idx][i].fi], e[idx][i].fi));
				if (it != q.end()) q.erase(it);
				d[e[idx][i].fi] = dist + e[idx][i].se;
				q.insert(mp(d[e[idx][i].fi], e[idx][i].fi));
				was[e[idx][i].fi] = true;
			}
		}
	}

	re d;
}

int dfs(int v, vll& d) {
	if (v == t)
		re 1;

	int ans = 0;
	rep(i, sz(e[v])) {
		if (!ewas[mp(v, i)] && d[e[v][i].fi] == d[v] + e[v][i].se) {
			ewas[mp(v, i)] = true;
			int res = dfs(e[v][i].fi, d);

			if (res > 0) {
				paths[eindex[mp(v, i)]] += res;
				ans += res;
			}

			ewas[mp(v, i)] = false;
		}
	}

	re ans;
}

int main()
{
	std::ios::sync_with_stdio(false);
	cin >> n >> m >> s >> t;
	s--;
	t--;
	rep(i, m) {
		int a, b, l;
		cin >> a >> b >> l;
		from[i] = a - 1;
		to[i] = b - 1;
		w[i] = l;
		e[a - 1].pb(mp(b - 1, l));
		eindex[mp(a - 1, sz(e[a - 1]) - 1)] = i;
		e2[b - 1].pb(mp(a - 1, l));
	}

	vll ds = dijkstra(s, &e[0]);
	vll dt = dijkstra(t, &e2[0]);

	ll best = ds[t];
	int cpaths = dfs(s, ds);

	//dbge(best);
	//dbge(cpaths);

	rep(i, m) {
		if (ds[from[i]] == LLONG_MAX || dt[to[i]] == LLONG_MAX) {
			cout << "NO" << endl;
			continue;
		}

		ll w1 = ds[from[i]] + w[i] + dt[to[i]] - best;

		//dbge(i);
		//dbge(ds[from[i]]);
		//dbge(dt[to[i]]);
		//dbge(w[i]);
		//dbge(w1);

		if (w1 == 0) {
			if (paths[i] != cpaths) {
				if (w[i] > 1) {
					cout << "CAN 1" << endl;
				} else {
					cout << "NO" << endl;
				}
			}
			else
				cout << "YES" << endl;
		} else if (w1 + 1 < w[i]) {
			cout << "CAN " << w1 + 1 << endl;
		} else {
			cout << "NO" << endl;
		}
	}

	return 0;
}


#include <iostream>
#include <vector>
#include <string>
#include <memory.h>
#include <set>
#include <algorithm>
#include <map>
#include <cstdlib>
#include <cstdio>
#include <queue>
#include <climits>
#include <cmath>
#include <iomanip>

#define mp make_pair
#define pb push_back
#define all(x) (x).begin(), (x).end()
#define fi first
#define se second
#define endl '\n'
#define dbgv(arr) cout << #arr << ": "; for (int i = 0; i < (int)arr.size(); i++) cout << arr[i] << " "; cout << endl;
#define dbge(el) cout << #el << ": " << el << endl;
#define dbgvv(arr) cout << #arr << ": "; for (int i = 0; i < (int)arr.size(); i++) cout << "(" << arr[i].first << " " << arr[i].second << ") "; cout << endl;
#define sz(s) ((int)(s).size())
#define re return
#define rep(i, n) for (int i = 0; i < (n); i++)

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef pair<int, int> ii;
typedef vector< pair<int, int> > vii;

template<class T> T abs(T x) { return x > 0 ? x : -x; }

const int maxn = 100000 + 100;
int n, m, s, t;
vii e[maxn];
vii e2[maxn];
int from[maxn];
int to[maxn];
int w[maxn];
bool was[maxn];
ll cnt1[maxn];
ll cnt2[maxn];

vll dijkstra(int v, vii *e, ll *cnt) {
	vll d(n, LLONG_MAX);
	set< pair<ll, ll> > q;

	memset(was, 0, sizeof(was));

	d[v] = 0;
	q.insert(mp(0, v));
	cnt[v] = 1;

	while (!q.empty()) {
		pair<ll, ll> cur = *q.begin();
		ll dist = cur.fi;
		int idx = cur.se;
		was[idx] = true;

		q.erase(cur);

		rep(i, sz(e[idx])) {
			int target = e[idx][i].fi;
			if (!was[target]) {
				if (d[target] > dist + e[idx][i].se) {
					auto it = q.lower_bound(mp(d[target], target));
					if (it != q.end()) q.erase(it);
					d[target] = dist + e[idx][i].se;
					q.insert(mp(d[target], target));
					cnt[target] = cnt[idx];
				} else if (d[target] == dist + e[idx][i].se) {
					cnt[target] += cnt[idx];
				}
			}
		}
	}

	re d;
}

int main()
{
	map<ii, int> minw;
	map<ii, int> kr;

	scanf("%d%d%d%d", &n, &m, &s, &t);
	s--;
	t--;
	rep(i, m) {
		int a, b, l;
		scanf("%d%d%d", &a, &b, &l);
		from[i] = a - 1;
		to[i] = b - 1;
		w[i] = l;
		e[a - 1].pb(mp(b - 1, l));
		e2[b - 1].pb(mp(a - 1, l));

		if (minw.count(mp(a - 1, b - 1)) == 0)
			minw[mp(a - 1, b - 1)] = w[i];
		else
			minw[mp(a - 1, b - 1)] = min(minw[mp(a - 1, b - 1)], w[i]);
	}

	rep(i, m) {
		if (minw[mp(from[i], to[i])] == w[i])
			kr[mp(from[i], to[i])]++;
	}

	vll ds = dijkstra(s, &e[0], cnt1);
	vll dt = dijkstra(t, &e2[0], cnt2);

	ll best = ds[t];
	ll cpaths = cnt1[t];

	//dbge(best);
	//dbge(cpaths);

	rep(i, m) {
		if (ds[from[i]] == LLONG_MAX || dt[to[i]] == LLONG_MAX) {
			cout << "NO" << endl;
			continue;
		}

		ll w1 = ds[from[i]] + w[i] + dt[to[i]] - best;

		if (w1 == 0) {
			if (cnt1[from[i]] * cnt2[to[i]] * kr[mp(from[i], to[i])] != cpaths) {
				if (w[i] > 1) {
					cout << "CAN 1" << endl;
				} else {
					cout << "NO" << endl;
				}
			} else {
				if (kr[mp(from[i], to[i])] > 1 && w[i] > 1) {
					cout << "CAN 1" << endl;
				} else {
					cout << "YES" << endl;

					if (0 && from[i] == 8734 && to[i] == 10494) {
						dbge(i);
						dbge(best);
						dbge(cpaths);
						dbge(ds[from[i]]);
						dbge(dt[to[i]]);
						dbge(cnt1[from[i]]);
						dbge(cnt2[to[i]]);
						dbge(w[i]);
						dbge(w1);
						dbge(kr[mp(from[i], to[i])]);
						dbge(minw[mp(from[i], to[i])]);
					}
				}
			}
		} else if (w1 + 1 < w[i]) {
			cout << "CAN " << w1 + 1 << endl;
		} else {
			cout << "NO" << endl;
		}
	}

	return 0;
}


#include <iostream>
#include <vector>
#include <string>
#include <memory.h>
#include <set>
#include <algorithm>
#include <map>
#include <cstdlib>
#include <cstdio>
#include <queue>
#include <climits>
#include <cmath>
#include <iomanip>

#define mp make_pair
#define pb push_back
#define all(x) (x).begin(), (x).end()
#define fi first
#define se second
#define endl '\n'
#define dbgv(arr) cout << #arr << ": "; for (int i = 0; i < (int)arr.size(); i++) cout << arr[i] << " "; cout << endl;
#define dbge(el) cout << #el << ": " << el << endl;
#define dbgvv(arr) cout << #arr << ": "; for (int i = 0; i < (int)arr.size(); i++) cout << "(" << arr[i].first << " " << arr[i].second << ") "; cout << endl;
#define sz(s) ((int)(s).size())
#define re return
#define rep(i, n) for (int i = 0; i < (n); i++)

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef pair<int, int> ii;
typedef vector< pair<int, int> > vii;

template<class T> T abs(T x) { return x > 0 ? x : -x; }

const int maxn = 100000 + 100;
int n, m, s, t;
vii e[maxn];
vii e2[maxn];
int from[maxn];
int to[maxn];
int w[maxn];
bool was[maxn];
ll cnt1[maxn];
ll cnt2[maxn];

vll dijkstra(int v, vii *e, ll *cnt) {
	vll d(n, LLONG_MAX);
	set< pair<ll, ll> > q;

	memset(was, 0, sizeof(was));

	d[v] = 0;
	q.insert(mp(0, v));
	cnt[v] = 1;

	while (!q.empty()) {
		pair<ll, ll> cur = *q.begin();
		ll dist = cur.fi;
		int idx = cur.se;
		was[idx] = true;

		q.erase(cur);

		rep(i, sz(e[idx])) {
			if (!was[e[idx][i].fi]) {
				if (d[e[idx][i].fi] > dist + e[idx][i].se) {
					auto it = q.lower_bound(mp(d[e[idx][i].fi], e[idx][i].fi));
					if (it != q.end()) q.erase(it);
					d[e[idx][i].fi] = dist + e[idx][i].se;
					q.insert(mp(d[e[idx][i].fi], e[idx][i].fi));
					cnt[e[idx][i].fi] = cnt[idx];
				} else if (d[e[idx][i].fi] == dist + e[idx][i].se) {
					cnt[e[idx][i].fi] += cnt[idx];
				}
			}
		}
	}

	re d;
}

int main()
{
	map<ii, int> minw;
	map<ii, int> kr;

	scanf("%d%d%d%d", &n, &m, &s, &t);
	s--;
	t--;
	rep(i, m) {
		int a, b, l;
		scanf("%d%d%d", &a, &b, &l);
		from[i] = a - 1;
		to[i] = b - 1;
		w[i] = l;
		e[a - 1].pb(mp(b - 1, l));
		e2[b - 1].pb(mp(a - 1, l));

		if (minw.count(mp(a - 1, b - 1)) == 0)
			minw[mp(a - 1, b - 1)] = w[i];
		else
			minw[mp(a - 1, b - 1)] = min(minw[mp(a - 1, b - 1)], w[i]);
	}

	rep(i, m) {
		if (minw[mp(from[i], to[i])] == w[i])
			kr[mp(from[i], to[i])]++;
	}

	vll ds = dijkstra(s, &e[0], cnt1);
	vll dt = dijkstra(t, &e2[0], cnt2);

	ll best = ds[t];
	ll cpaths = cnt1[t];

	//dbge(best);
	//dbge(cpaths);

	rep(i, m) {
		if (ds[from[i]] == LLONG_MAX || dt[to[i]] == LLONG_MAX) {
			cout << "NO" << endl;
			continue;
		}

		ll w1 = ds[from[i]] + w[i] + dt[to[i]] - best;

		if (w1 == 0) {
			if (cnt1[from[i]] * cnt2[to[i]] * kr[mp(from[i], to[i])] != cpaths) {
				if (w[i] > 1) {
					cout << "CAN 1" << endl;
				} else {
					cout << "NO" << endl;
				}
			} else {
				if (kr[mp(from[i], to[i])] > 1 && w[i] > 1) {
					cout << "CAN 1" << endl;
				} else {
					cout << "YES" << endl;

					if (from[i] == 8735 && to[i] == 10495) {
						dbge(i);
						dbge(best);
						dbge(cpaths);
						dbge(ds[from[i]]);
						dbge(dt[to[i]]);
						dbge(w[i]);
						dbge(w1);
						dbge(kr[mp(from[i], to[i])]);
						dbge(minw[mp(from[i], to[i])]);
					}
				}
			}
		} else if (w1 + 1 < w[i]) {
			cout << "CAN " << w1 + 1 << endl;
		} else {
			cout << "NO" << endl;
		}
	}

	return 0;
}


#include <iostream>
#include <vector>
#include <string>
#include <memory.h>
#include <set>
#include <algorithm>
#include <map>
#include <cstdlib>
#include <cstdio>
#include <queue>
#include <climits>
#include <cmath>
#include <iomanip>

#define mp make_pair
#define pb push_back
#define all(x) (x).begin(), (x).end()
#define fi first
#define se second
#define endl '\n'
#define dbgv(arr) cout << #arr << ": "; for (int i = 0; i < (int)arr.size(); i++) cout << arr[i] << " "; cout << endl;
#define dbge(el) cout << #el << ": " << el << endl;
#define dbgvv(arr) cout << #arr << ": "; for (int i = 0; i < (int)arr.size(); i++) cout << "(" << arr[i].first << " " << arr[i].second << ") "; cout << endl;
#define sz(s) ((int)(s).size())
#define re return
#define rep(i, n) for (int i = 0; i < (n); i++)

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef pair<int, int> ii;
typedef vector< pair<int, int> > vii;

template<class T> T abs(T x) { return x > 0 ? x : -x; }

const int maxn = 100000 + 100;
int n, m, s, t;
vii e[maxn];
vii e2[maxn];
int from[maxn];
int to[maxn];
int w[maxn];
bool was[maxn];
ll cnt1[maxn];
ll cnt2[maxn];

vll dijkstra(int v, vii *e, ll *cnt) {
	vll d(n, LLONG_MAX);
	set< pair<ll, ll> > q;

	memset(was, 0, sizeof(was));

	d[v] = 0;
	q.insert(mp(0, v));
	cnt[v] = 1;

	while (!q.empty()) {
		pair<ll, ll> cur = *q.begin();
		ll dist = cur.fi;
		int idx = cur.se;
		was[idx] = true;

		q.erase(cur);

		rep(i, sz(e[idx])) {
			if (!was[e[idx][i].fi]) {
				if (d[e[idx][i].fi] > dist + e[idx][i].se) {
					auto it = q.lower_bound(mp(d[e[idx][i].fi], e[idx][i].fi));
					if (it != q.end()) q.erase(it);
					d[e[idx][i].fi] = dist + e[idx][i].se;
					q.insert(mp(d[e[idx][i].fi], e[idx][i].fi));
					cnt[e[idx][i].fi] = cnt[idx];
				} else if (d[e[idx][i].fi] == dist + e[idx][i].se) {
					cnt[e[idx][i].fi] += cnt[idx];
				}
			}
		}
	}

	re d;
}

int main()
{
	map<ii, int> minw;
	map<ii, int> kr;

	scanf("%d%d%d%d", &n, &m, &s, &t);
	s--;
	t--;
	rep(i, m) {
		int a, b, l;
		scanf("%d%d%d", &a, &b, &l);
		from[i] = a - 1;
		to[i] = b - 1;
		w[i] = l;
		e[a - 1].pb(mp(b - 1, l));
		e2[b - 1].pb(mp(a - 1, l));

		if (minw.count(mp(a - 1, b - 1)) == 0)
			minw[mp(a - 1, b - 1)] = w[i];
		else
			minw[mp(a - 1, b - 1)] = min(minw[mp(a - 1, b - 1)], w[i]);
	}

	rep(i, m) {
		if (minw[mp(from[i], to[i])] == w[i])
			kr[mp(from[i], to[i])]++;
	}

	vll ds = dijkstra(s, &e[0], cnt1);
	vll dt = dijkstra(t, &e2[0], cnt2);

	ll best = ds[t];
	ll cpaths = cnt1[t];

	//dbge(best);
	//dbge(cpaths);

	rep(i, m) {
		if (ds[from[i]] == LLONG_MAX || dt[to[i]] == LLONG_MAX) {
			cout << "NO" << endl;
			continue;
		}

		ll w1 = ds[from[i]] + w[i] + dt[to[i]] - best;

		if (w1 == 0) {
			if (cnt1[from[i]] * cnt2[to[i]] * kr[mp(from[i], to[i])] != cpaths) {
				if (w[i] > 1) {
					cout << "CAN 1" << endl;
				} else {
					cout << "NO" << endl;
				}
			} else {
				if (kr[mp(from[i], to[i])] > 1 && w[i] > 1) {
					cout << "CAN 1" << endl;
				} else {
					cout << "YES" << endl;

					if (i == 22 && from[i] == 8735 && to[i] == 10495) {
						dbge(i);
						dbge(best);
						dbge(cpaths);
						dbge(ds[from[i]]);
						dbge(dt[to[i]]);
						dbge(w[i]);
						dbge(w1);
						dbge(kr[mp(from[i], to[i])]);
						dbge(minw[mp(from[i], to[i])]);
					}
				}
			}
		} else if (w1 + 1 < w[i]) {
			cout << "CAN " << w1 + 1 << endl;
		} else {
			cout << "NO" << endl;
		}
	}

	return 0;
}


#include <iostream>
#include <vector>
#include <string>
#include <memory.h>
#include <set>
#include <algorithm>
#include <map>
#include <cstdlib>
#include <cstdio>
#include <queue>
#include <climits>
#include <cmath>
#include <iomanip>

#define mp make_pair
#define pb push_back
#define all(x) (x).begin(), (x).end()
#define fi first
#define se second
#define endl '\n'
#define dbgv(arr) cout << #arr << ": "; for (int i = 0; i < (int)arr.size(); i++) cout << arr[i] << " "; cout << endl;
#define dbge(el) cout << #el << ": " << el << endl;
#define dbgvv(arr) cout << #arr << ": "; for (int i = 0; i < (int)arr.size(); i++) cout << "(" << arr[i].first << " " << arr[i].second << ") "; cout << endl;
#define sz(s) ((int)(s).size())
#define re return
#define rep(i, n) for (int i = 0; i < (n); i++)

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef pair<int, int> ii;
typedef vector< pair<int, int> > vii;

template<class T> T abs(T x) { return x > 0 ? x : -x; }

const int maxn = 100000 + 100;
int n, m, s, t;
vii e[maxn];
vii e2[maxn];
int from[maxn];
int to[maxn];
int w[maxn];
bool was[maxn];
ll cnt1[maxn];
ll cnt2[maxn];

vll dijkstra(int v, vii *e, ll *cnt) {
	vll d(n, LLONG_MAX);
	set< pair<ll, ll> > q;

	memset(was, 0, sizeof(was));

	d[v] = 0;
	q.insert(mp(0, v));
	cnt[v] = 1;

	while (!q.empty()) {
		pair<ll, ll> cur = *q.begin();
		ll dist = cur.fi;
		int idx = cur.se;
		was[idx] = true;

		q.erase(cur);

		rep(i, sz(e[idx])) {
			int target = e[idx][i].fi;
			if (!was[target]) {
				if (d[target] > dist + e[idx][i].se) {
					auto it = q.lower_bound(mp(d[target], target));
					if (it != q.end()) q.erase(it);
					d[target] = dist + e[idx][i].se;
					q.insert(mp(d[target], target));
					cnt[target] = cnt[idx];
				} else if (d[target] == dist + e[idx][i].se) {
					cnt[target] += cnt[idx];
				}
			}
		}
	}

	re d;
}

int main()
{
	map<ii, int> minw;
	map<ii, int> kr;

	scanf("%d%d%d%d", &n, &m, &s, &t);
	s--;
	t--;
	rep(i, m) {
		int a, b, l;
		scanf("%d%d%d", &a, &b, &l);
		from[i] = a - 1;
		to[i] = b - 1;
		w[i] = l;
		e[a - 1].pb(mp(b - 1, l));
		e2[b - 1].pb(mp(a - 1, l));

		if (minw.count(mp(a - 1, b - 1)) == 0)
			minw[mp(a - 1, b - 1)] = w[i];
		else
			minw[mp(a - 1, b - 1)] = min(minw[mp(a - 1, b - 1)], w[i]);
	}

	rep(i, m) {
		if (minw[mp(from[i], to[i])] == w[i])
			kr[mp(from[i], to[i])]++;
	}

	vll ds = dijkstra(s, &e[0], cnt1);
	vll dt = dijkstra(t, &e2[0], cnt2);

	ll best = ds[t];
	ll cpaths = cnt1[t];

	//dbge(best);
	//dbge(cpaths);

	rep(i, m) {
		if (ds[from[i]] == LLONG_MAX || dt[to[i]] == LLONG_MAX) {
			cout << "NO" << endl;
			continue;
		}

		ll w1 = ds[from[i]] + w[i] + dt[to[i]] - best;

		if (w1 == 0) {
			if (cnt1[from[i]] * cnt2[to[i]] * kr[mp(from[i], to[i])] != cpaths) {
				if (w[i] > 1) {
					cout << "CAN 1" << endl;
				} else {
					cout << "NO" << endl;
				}
			} else {
				if (kr[mp(from[i], to[i])] > 1 && w[i] > 1) {
					cout << "CAN 1" << endl;
				} else {
					cout << "YES" << endl;

					if (from[i] == 8734 && to[i] == 10494) {
						dbge(i);
						dbge(best);
						dbge(cpaths);
						dbge(ds[from[i]]);
						dbge(dt[to[i]]);
						dbge(cnt1[from[i]]);
						dbge(cnt2[to[i]]);
						dbge(w[i]);
						dbge(w1);
						dbge(kr[mp(from[i], to[i])]);
						dbge(minw[mp(from[i], to[i])]);
					}
				}
			}
		} else if (w1 + 1 < w[i]) {
			cout << "CAN " << w1 + 1 << endl;
		} else {
			cout << "NO" << endl;
		}
	}

	return 0;
}


#include <iostream>
#include <vector>
#include <string>
#include <memory.h>
#include <set>
#include <algorithm>
#include <map>
#include <cstdlib>
#include <cstdio>
#include <queue>
#include <climits>
#include <cmath>
#include <iomanip>

#define mp make_pair
#define pb push_back
#define all(x) (x).begin(), (x).end()
#define fi first
#define se second
#define endl '\n'
#define dbgv(arr) cout << #arr << ": "; for (int i = 0; i < (int)arr.size(); i++) cout << arr[i] << " "; cout << endl;
#define dbge(el) cout << #el << ": " << el << endl;
#define dbgvv(arr) cout << #arr << ": "; for (int i = 0; i < (int)arr.size(); i++) cout << "(" << arr[i].first << " " << arr[i].second << ") "; cout << endl;
#define sz(s) ((int)(s).size())
#define re return
#define rep(i, n) for (int i = 0; i < (n); i++)

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef vector<int> vi;
typedef pair<int, int> ii;
typedef vector< pair<int, int> > vii;

template<class T> T abs(T x) { return x > 0 ? x : -x; }

const int maxn = 100000 + 100;
int n, m, s, t;
vii e[maxn];
vii e2[maxn];
int from[maxn];
int to[maxn];
int w[maxn];
bool was[maxn];
map<ii, bool> ewas;
map<ii, int> paths;

vi dijkstra(int v, vii *e) {
	vi d(n, INT_MAX);
	set<ii> q;

	memset(was, 0, sizeof(was));

	d[v] = 0;
	q.insert(mp(0, v));
	was[v] = true;

	while (!q.empty()) {
		ii cur = *q.begin();
		q.erase(cur);

		int dist = cur.fi;
		int idx = cur.se;

		rep(i, sz(e[idx])) {
			if (!was[e[idx][i].fi] && d[e[idx][i].fi] >= dist + e[idx][i].se) {
				auto it = q.lower_bound(mp(d[e[idx][i].fi], e[idx][i].fi));
				if (it != q.end()) q.erase(it);
				d[e[idx][i].fi] = dist + e[idx][i].se;
				q.insert(mp(d[e[idx][i].fi], e[idx][i].fi));
			}
		}
	}

	re d;
}

int dfs(int v, vi& d) {
	if (v == t)
		re 1;

	int ans = 0;
	rep(i, sz(e[v])) {
		if (!ewas[mp(v, i)] && d[e[v][i].fi] == d[v] + e[v][i].se) {
			ewas[mp(v, i)] = true;
			int res = dfs(e[v][i].fi, d);

			if (res > 0) {
				paths[mp(v, e[v][i].fi)] += res;
				ans += res;
			}

			ewas[mp(v, i)] = false;
		}
	}

	re ans;
}

int main()
{
	std::ios::sync_with_stdio(false);
	cin >> n >> m >> s >> t;
	s--;
	t--;
	rep(i, m) {
		int a, b, l;
		cin >> a >> b >> l;
		from[i] = a - 1;
		to[i] = b - 1;
		w[i] = l;
		e[a - 1].pb(mp(b - 1, l));
		e2[b - 1].pb(mp(a - 1, l));
	}

	vi ds = dijkstra(s, &e[0]);
	vi dt = dijkstra(t, &e2[0]);

	int best = ds[t];
	int cpaths = dfs(s, ds);

	rep(i, m) {
		if (ds[from[i]] == INT_MAX || dt[to[i]] == INT_MAX) {
			cout << "NO" << endl;
			continue;
		}

		int w1 = ds[from[i]] + w[i] + dt[to[i]] - best;
		if (w1 == 0) {
			if (paths[mp(from[i], to[i])] != cpaths)
				cout << "CAN 1" << endl;
			else
				cout << "YES" << endl;
		} else if (w1 + 1 < w[i]) {
			cout << "CAN " << w1 + 1 << endl;
		} else {
			cout << "NO" << endl;
		}
	}

	return 0;
}


#include <iostream>
#include <vector>
#include <string>
#include <memory.h>
#include <set>
#include <algorithm>
#include <map>
#include <cstdlib>
#include <cstdio>
#include <queue>
#include <climits>
#include <cmath>
#include <iomanip>

#define mp make_pair
#define pb push_back
#define all(x) (x).begin(), (x).end()
#define fi first
#define se second
#define endl '\n'
#define dbgv(arr) cout << #arr << ": "; for (int i = 0; i < (int)arr.size(); i++) cout << arr[i] << " "; cout << endl;
#define dbge(el) cout << #el << ": " << el << endl;
#define dbgvv(arr) cout << #arr << ": "; for (int i = 0; i < (int)arr.size(); i++) cout << "(" << arr[i].first << " " << arr[i].second << ") "; cout << endl;
#define sz(s) ((int)(s).size())
#define re return
#define rep(i, n) for (int i = 0; i < (n); i++)

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef pair<int, int> ii;
typedef vector< pair<int, int> > vii;

template<class T> T abs(T x) { return x > 0 ? x : -x; }

const int maxn = 100000 + 100;
int n, m, s, t;
vii e[maxn];
vii e2[maxn];
int from[maxn];
int to[maxn];
int w[maxn];
bool was[maxn];
ll paths[maxn];
ll cnt1[maxn];
ll cnt2[maxn];
map<ii, int> eindex;

vll dijkstra(int v, vii *e, ll *cnt) {
	vll d(n, LLONG_MAX);
	set< pair<ll, ll> > q;

	memset(was, 0, sizeof(was));

	d[v] = 0;
	q.insert(mp(0, v));
	cnt[v] = 1;

	while (!q.empty()) {
		pair<ll, ll> cur = *q.begin();
		ll dist = cur.fi;
		int idx = cur.se;
		was[idx] = true;

		q.erase(cur);

		rep(i, sz(e[idx])) {
			if (!was[e[idx][i].fi]) {
				if (d[e[idx][i].fi] > dist + e[idx][i].se) {
					auto it = q.lower_bound(mp(d[e[idx][i].fi], e[idx][i].fi));
					if (it != q.end()) q.erase(it);
					d[e[idx][i].fi] = dist + e[idx][i].se;
					q.insert(mp(d[e[idx][i].fi], e[idx][i].fi));
					cnt[e[idx][i].fi] = cnt[idx];
				} else if (d[e[idx][i].fi] == dist + e[idx][i].se) {
					cnt[e[idx][i].fi] += cnt[idx];
				}
			}
		}
	}

	re d;
}

ll dfs(int v, ll flow, vll& d) {
	if (v == t)
		re flow;

	ll ans = 0;
	map<int, int> compression;
	map<int, ll> compression_result;

	rep(i, sz(e[v])) {
		if (!was[e[v][i].fi] && d[e[v][i].fi] == d[v] + e[v][i].se) {
			compression[e[v][i].fi]++;
		}
	}

	for (auto it = compression.begin(); it != compression.end(); ++it) {
		int target = it->fi;
		int add_flow = it->se;

		was[target] = true;
		ll res = dfs(target, flow * add_flow, d);
		ans += res;
		compression_result[target] = res;

		was[target] = false;
	}

	rep(i, sz(e[v])) {
		int target = e[v][i].fi;
		if (!was[target] && d[target] == d[v] + e[v][i].se) {
			ll res = compression_result[target];
			if (res > 0) {
				paths[eindex[mp(v, i)]] += compression_result[target] / compression[target];
			}
		}
	}

	re ans;
}

int main()
{
	scanf("%d%d%d%d", &n, &m, &s, &t);
	s--;
	t--;
	rep(i, m) {
		int a, b, l;
		scanf("%d%d%d", &a, &b, &l);
		from[i] = a - 1;
		to[i] = b - 1;
		w[i] = l;
		e[a - 1].pb(mp(b - 1, l));
		eindex[mp(a - 1, sz(e[a - 1]) - 1)] = i;
		e2[b - 1].pb(mp(a - 1, l));
	}

	vll ds = dijkstra(s, &e[0], cnt1);
	vll dt = dijkstra(t, &e2[0], cnt2);

	memset(was, 0, sizeof(was));
	ll best = ds[t];
	ll cpaths = cnt1[t];//dfs(s, 1, ds);//cnt[t];

	//dbge(best);
	//dbge(cpaths);

	rep(i, m) {
		if (ds[from[i]] == LLONG_MAX || dt[to[i]] == LLONG_MAX) {
			cout << "NO" << endl;
			continue;
		}

		ll w1 = ds[from[i]] + w[i] + dt[to[i]] - best;

		//dbge(i);
		//dbge(ds[from[i]]);
		//dbge(dt[to[i]]);
		//dbge(w[i]);
		//dbge(w1);

		if (w1 == 0) {
			if (cnt2[to[i]] != cpaths) {
				if (w[i] > 1) {
					cout << "CAN 1" << endl;
				} else {
					cout << "NO" << endl;
				}
			}
			else
				cout << "YES" << endl;
		} else if (w1 + 1 < w[i]) {
			cout << "CAN " << w1 + 1 << endl;
		} else {
			cout << "NO" << endl;
		}
	}

	return 0;
}


#include <iostream>
#include <vector>
#include <string>
#include <memory.h>
#include <set>
#include <algorithm>
#include <map>
#include <cstdlib>
#include <cstdio>
#include <queue>
#include <climits>
#include <cmath>
#include <iomanip>

#define mp make_pair
#define pb push_back
#define all(x) (x).begin(), (x).end()
#define fi first
#define se second
#define endl '\n'
#define dbgv(arr) cout << #arr << ": "; for (int i = 0; i < (int)arr.size(); i++) cout << arr[i] << " "; cout << endl;
#define dbge(el) cout << #el << ": " << el << endl;
#define dbgvv(arr) cout << #arr << ": "; for (int i = 0; i < (int)arr.size(); i++) cout << "(" << arr[i].first << " " << arr[i].second << ") "; cout << endl;
#define sz(s) ((int)(s).size())
#define re return
#define rep(i, n) for (int i = 0; i < (n); i++)

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef pair<int, int> ii;
typedef vector< pair<int, int> > vii;

template<class T> T abs(T x) { return x > 0 ? x : -x; }

const int maxn = 100000 + 100;
int n, m, s, t;
vii e[maxn];
vii e2[maxn];
int from[maxn];
int to[maxn];
int w[maxn];
bool was[maxn];
map<ii, bool> ewas;
int paths[maxn];
map<ii, int> eindex;

vll dijkstra(int v, vii *e) {
	vll d(n, LLONG_MAX);
	set< pair<ll, ll> > q;

	memset(was, 0, sizeof(was));

	d[v] = 0;
	q.insert(mp(0, v));
	was[v] = true;

	while (!q.empty()) {
		pair<ll, ll> cur = *q.begin();
		q.erase(cur);

		ll dist = cur.fi;
		int idx = cur.se;

		rep(i, sz(e[idx])) {
			if (!was[e[idx][i].fi] && d[e[idx][i].fi] >= dist + e[idx][i].se) {
				auto it = q.lower_bound(mp(d[e[idx][i].fi], e[idx][i].fi));
				if (it != q.end()) q.erase(it);
				d[e[idx][i].fi] = dist + e[idx][i].se;
				q.insert(mp(d[e[idx][i].fi], e[idx][i].fi));
			}
		}
	}

	re d;
}

int dfs(int v, vll& d) {
	if (v == t)
		re 1;

	int ans = 0;
	rep(i, sz(e[v])) {
		if (!ewas[mp(v, i)] && d[e[v][i].fi] == d[v] + e[v][i].se) {
			ewas[mp(v, i)] = true;
			int res = dfs(e[v][i].fi, d);

			if (res > 0) {
				paths[eindex[mp(v, i)]] += res;
				ans += res;
			}

			ewas[mp(v, i)] = false;
		}
	}

	re ans;
}

int main()
{
	std::ios::sync_with_stdio(false);
	cin >> n >> m >> s >> t;
	s--;
	t--;
	rep(i, m) {
		int a, b, l;
		cin >> a >> b >> l;
		from[i] = a - 1;
		to[i] = b - 1;
		w[i] = l;
		e[a - 1].pb(mp(b - 1, l));
		eindex[mp(a - 1, sz(e[a - 1]) - 1)] = i;
		e2[b - 1].pb(mp(a - 1, l));
	}

	vll ds = dijkstra(s, &e[0]);
	vll dt = dijkstra(t, &e2[0]);

	ll best = ds[t];
	int cpaths = dfs(s, ds);

	//dbge(best);
	//dbge(cpaths);

	rep(i, m) {
		if (ds[from[i]] == LLONG_MAX || dt[to[i]] == LLONG_MAX) {
			cout << "NO" << endl;
			continue;
		}

		ll w1 = ds[from[i]] + w[i] + dt[to[i]] - best;

		//dbge(i);
		//dbge(ds[from[i]]);
		//dbge(dt[to[i]]);
		//dbge(w[i]);
		//dbge(w1);

		if (w1 == 0) {
			if (paths[i] != cpaths) {
				if (w[i] > 1) {
					cout << "CAN 1" << endl;
				} else {
					cout << "NO" << endl;
				}
			}
			else
				cout << "YES" << endl;
		} else if (w1 + 1 < w[i]) {
			cout << "CAN " << w1 + 1 << endl;
		} else {
			cout << "NO" << endl;
		}
	}

	return 0;
}


#include <iostream>
#include <vector>
#include <string>
#include <memory.h>
#include <set>
#include <algorithm>
#include <map>
#include <cstdlib>
#include <cstdio>
#include <queue>
#include <climits>
#include <cmath>
#include <iomanip>

#define mp make_pair
#define pb push_back
#define all(x) (x).begin(), (x).end()
#define fi first
#define se second
#define endl '\n'
#define dbgv(arr) cout << #arr << ": "; for (int i = 0; i < (int)arr.size(); i++) cout << arr[i] << " "; cout << endl;
#define dbge(el) cout << #el << ": " << el << endl;
#define dbgvv(arr) cout << #arr << ": "; for (int i = 0; i < (int)arr.size(); i++) cout << "(" << arr[i].first << " " << arr[i].second << ") "; cout << endl;
#define sz(s) ((int)(s).size())
#define re return
#define rep(i, n) for (int i = 0; i < (n); i++)

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef pair<int, int> ii;
typedef vector< pair<int, int> > vii;

template<class T> T abs(T x) { return x > 0 ? x : -x; }

const ll mod = 1000000000ll + 7;
const int maxn = 100000 + 100;
int n, m, s, t;
vii e[maxn];
vii e2[maxn];
int from[maxn];
int to[maxn];
int w[maxn];
bool was[maxn];
ll cnt1[maxn];
ll cnt2[maxn];

vll dijkstra(int v, vii *e, ll *cnt) {
	vll d(n, LLONG_MAX);
	set< pair<ll, ll> > q;

	memset(was, 0, sizeof(was));

	d[v] = 0;
	q.insert(mp(0, v));
	cnt[v] = 1;

	while (!q.empty()) {
		pair<ll, ll> cur = *q.begin();
		ll dist = cur.fi;
		int idx = cur.se;
		was[idx] = true;

		if (cnt[idx] <= 0) {
			dbge(idx);
			dbge(cnt[idx]);
			dbge(v);
		}

		q.erase(cur);

		rep(i, sz(e[idx])) {
			int target = e[idx][i].fi;
			if (!was[target]) {
				if (d[target] > dist + e[idx][i].se) {
					auto it = q.lower_bound(mp(d[target], target));
					if (it != q.end()) q.erase(it);
					d[target] = dist + e[idx][i].se;
					q.insert(mp(d[target], target));
					cnt[target] = cnt[idx];
				} else if (d[target] == dist + e[idx][i].se) {
					cnt[target] = (cnt[target] + cnt[idx]) % mod;
				}
			}
		}
	}

	re d;
}

int main()
{
	map<ii, int> minw;
	map<ii, int> kr;

	scanf("%d%d%d%d", &n, &m, &s, &t);
	s--;
	t--;
	rep(i, m) {
		int a, b, l;
		scanf("%d%d%d", &a, &b, &l);
		from[i] = a - 1;
		to[i] = b - 1;
		w[i] = l;
		e[a - 1].pb(mp(b - 1, l));
		e2[b - 1].pb(mp(a - 1, l));

		if (minw.count(mp(a - 1, b - 1)) == 0)
			minw[mp(a - 1, b - 1)] = w[i];
		else
			minw[mp(a - 1, b - 1)] = min(minw[mp(a - 1, b - 1)], w[i]);
	}

	rep(i, m) {
		if (minw[mp(from[i], to[i])] == w[i])
			kr[mp(from[i], to[i])]++;
	}

	vll ds = dijkstra(s, &e[0], cnt1);
	vll dt = dijkstra(t, &e2[0], cnt2);

	ll best = ds[t];
	ll cpaths = cnt1[t];

	//dbge(best);
	//dbge(cpaths);

	rep(i, m) {
		if (ds[from[i]] == LLONG_MAX || dt[to[i]] == LLONG_MAX) {
			cout << "NO" << endl;
			continue;
		}

		ll w1 = ds[from[i]] + w[i] + dt[to[i]] - best;

		if (w1 == 0) {
			if (cnt1[from[i]] * cnt2[to[i]] * kr[mp(from[i], to[i])] != cpaths) {
				if (w[i] > 1) {
					cout << "CAN 1" << endl;
				} else {
					cout << "NO" << endl;
				}
			} else {
				if (kr[mp(from[i], to[i])] > 1 && w[i] > 1) {
					cout << "CAN 1" << endl;
				} else {
					cout << "YES" << endl;

					if (0 && from[i] == 8734 && to[i] == 10494) {
						dbge(i);
						dbge(best);
						dbge(cpaths);
						dbge(ds[from[i]]);
						dbge(dt[to[i]]);
						dbge(cnt1[from[i]]);
						dbge(cnt2[to[i]]);
						dbge(w[i]);
						dbge(w1);
						dbge(kr[mp(from[i], to[i])]);
						dbge(minw[mp(from[i], to[i])]);
					}
				}
			}
		} else if (w1 + 1 < w[i]) {
			cout << "CAN " << w1 + 1 << endl;
		} else {
			cout << "NO" << endl;
		}
	}

	return 0;
}


#include <iostream>
#include <vector>
#include <string>
#include <memory.h>
#include <set>
#include <algorithm>
#include <map>
#include <cstdlib>
#include <cstdio>
#include <queue>
#include <climits>
#include <cmath>
#include <iomanip>

#define mp make_pair
#define pb push_back
#define all(x) (x).begin(), (x).end()
#define fi first
#define se second
#define endl '\n'
#define dbgv(arr) cout << #arr << ": "; for (int i = 0; i < (int)arr.size(); i++) cout << arr[i] << " "; cout << endl;
#define dbge(el) cout << #el << ": " << el << endl;
#define dbgvv(arr) cout << #arr << ": "; for (int i = 0; i < (int)arr.size(); i++) cout << "(" << arr[i].first << " " << arr[i].second << ") "; cout << endl;
#define sz(s) ((int)(s).size())
#define re return
#define rep(i, n) for (int i = 0; i < (n); i++)

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef vector<int> vi;
typedef pair<int, int> ii;
typedef vector< pair<int, int> > vii;

template<class T> T abs(T x) { return x > 0 ? x : -x; }

const int maxn = 100000 + 100;
int n, m, s, t;
vii e[maxn];
vii e2[maxn];
int from[maxn];
int to[maxn];
int w[maxn];
bool was[maxn];
map<ii, bool> ewas;
map<ii, int> paths;

vi dijkstra(int v, vii *e) {
	vi d(n, INT_MAX);
	set<ii> q;

	memset(was, 0, sizeof(was));

	d[v] = 0;
	q.insert(mp(0, v));
	was[v] = true;

	while (!q.empty()) {
		ii cur = *q.begin();
		q.erase(cur);

		int dist = cur.fi;
		int idx = cur.se;

		rep(i, sz(e[idx])) {
			if (!was[e[idx][i].fi] && d[e[idx][i].fi] >= dist + e[idx][i].se) {
				auto it = q.lower_bound(mp(d[e[idx][i].fi], e[idx][i].fi));
				if (it != q.end()) q.erase(it);
				d[e[idx][i].fi] = dist + e[idx][i].se;
				q.insert(mp(d[e[idx][i].fi], e[idx][i].fi));
			}
		}
	}

	re d;
}

int dfs(int v, vi& d) {
	if (v == t)
		re 1;

	int ans = 0;
	rep(i, sz(e[v])) {
		if (!ewas[mp(v, i)] && d[e[v][i].fi] == d[v] + e[v][i].se) {
			ewas[mp(v, i)] = true;
			int res = dfs(e[v][i].fi, d);

			if (res > 0) {
				paths[mp(v, e[v][i].fi)] += res;
				ans += res;
			}

			ewas[mp(v, i)] = false;
		}
	}

	re ans;
}

int main()
{
	std::ios::sync_with_stdio(false);
	cin >> n >> m >> s >> t;
	s--;
	t--;
	rep(i, m) {
		int a, b, l;
		cin >> a >> b >> l;
		from[i] = a - 1;
		to[i] = b - 1;
		w[i] = l;
		e[a - 1].pb(mp(b - 1, l));
		e2[b - 1].pb(mp(a - 1, l));
	}

	vi ds = dijkstra(s, &e[0]);
	vi dt = dijkstra(t, &e2[0]);

	int best = ds[t];
	int cpaths = dfs(s, ds);

	rep(i, m) {
		int w1 = ds[from[i]] + w[i] + dt[to[i]] - best;
		if (w1 == 0) {
			if (paths[mp(from[i], to[i])] != cpaths)
				cout << "CAN 1" << endl;
			else
				cout << "YES" << endl;
		} else if (w1 + 1 < w[i]) {
			cout << "CAN " << w1 + 1 << endl;
		} else {
			cout << "NO" << endl;
		}
	}

	return 0;
}