除了 #2,#5,#8,#11 和 #12 都错了,思路是先用 Tarjan 缩成 DAG 再用拓扑排序求范围
// Code by iamsh
#include<bits/stdc++.h>
using namespace std;
const int N = 3e5 + 5;
int n,m,A,B,x[N],y[N];
int dfn[N],tot,low[N],scc[N];
bool instk[N];
int stk[N],top;
vector<int> g[N],G[N];
int in[N],cnt;
map<int,int> mp;
pair<int,int> dp[N];
vector<int> tpn;
queue<int> q;
vector<pair<int,int>> ans;
void gmin(int &a,int b) {
a = a < b ? a : b;
}
void gmax(int &a,int b) {
a = a > b ? a : b;
}
void tarjan(int u) {
low[u] = dfn[u] = ++ tot;
stk[++ top] = u,instk[u] = 1;
for(int v : g[u]) {
if(!dfn[v]) {
tarjan(v);
gmin(low[u],low[v]);
}
if(instk[v]) {
gmin(low[u],dfn[v]);
}
}
if(dfn[u] == low[u]) {
int v;
do {
v = stk[top --];
scc[v] = u,instk[v] = 0;
} while(v != u);
}
}
void solve() {
cin >> n >> m >> A >> B;
for(int i = 1;i <= n;i ++) {
cin >> x[i] >> y[i];
if(x[i] == A) {
mp[y[i]];
}
}
for(auto &x : mp) {
x.second = ++ cnt;
}
while(m --) {
int u,v,d;
cin >> u >> v >> d;
g[u].push_back(v);
if(d != 1) {
g[v].push_back(u);
}
}
for(int i = 1;i <= n;i ++) {
if(!dfn[i]) {
tarjan(i);
}
}
for(int u = 1;u <= n;u ++) {
for(int v : g[u]) {
if(scc[u] != scc[v]) {
G[scc[u]].push_back(scc[v]);
}
}
}
for(int u = 1;u <= n;u ++) {
sort(G[u].begin(),G[u].begin());
G[u].erase(unique(G[u].begin(),G[u].end()),G[u].end());
for(int v : G[u]) {
in[v] ++;
}
}
for(int i = 1;i <= n;i ++) {
dp[i] = {B + 1,-1};
}
for(int i = 1;i <= n;i ++) {
if(x[i] == A) {
gmin(dp[scc[i]].first,y[i]);
gmax(dp[scc[i]].second,y[i]);
}
}
for(int i = 1;i <= n;i ++) {
if(scc[i] == i && !in[i]) {
q.push(i);
}
}
while(q.size()) {
int u = q.front();
q.pop();
tpn.push_back(u);
for(int v : G[u]) {
if(!(-- in[v])) {
q.push(v);
}
}
}
for(int i = tpn.size() - 1;~i;i --) {
int u = tpn[i];
for(int v : G[u]) {
gmin(dp[u].first,dp[v].first);
gmax(dp[u].second,dp[v].second);
}
}
for(int i = 1;i <= n;i ++) {
if(x[i] == 0) {
if(dp[scc[i]].second < 0) {
ans.push_back({y[i],0});
continue;
}
int l = mp[dp[scc[i]].first];
int r = mp[dp[scc[i]].second];
ans.push_back({y[i],r - l + 1});
}
}
sort(ans.begin(),ans.end(),greater<pair<int,int>>());
for(auto x : ans) {
cout << x.second << "\n";
}
}
int main() {
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cout << fixed << setprecision(12);
int t = 1;
// cin >> t;
while(t --) {
solve();
}
return 0;
}