/* OBS1: using binary lifting find lowest ancestor invited to a party, he will be the new owner. OBS2: now all the party a user is invited to, is from a ancestor OBS3: we can do a DFS and mantain a BIT with how many active parties per age. O(N + MlogN + Mlog(MaxAge)) */ #include using namespace std; const int MAXN = 100010; const int MAXK = 20; const int MAX = 100000; int idade[MAXN], pai[MAXN], party[MAXN][3], dp[MAXK][MAXN]; vector grafo[MAXN], myParties[MAXN], myNewParties[MAXN]; int bit[MAXN], resp[MAXN]; bool inside(int a, int l, int r) { return (a >= l) && (a <= r); } void dfs(int v) { //binary lifting dp[0][v] = pai[v]; for(int i = 1; i < MAXK; i++) dp[i][v] = dp[i-1][dp[i-1][v]]; for(int i = 0; i < (int) myParties[v].size(); i++) { int j = myParties[v][i]; int l = party[j][1]; int r = party[j][2]; int newOwner = v; for(int k = MAXK - 1; k >= 0; k--) if(inside(idade[dp[k][newOwner]], l, r)) newOwner = dp[k][newOwner]; myNewParties[newOwner].push_back(j); } for(int i = 0; i < (int) grafo[v].size(); i++) { int filho = grafo[v][i]; dfs(filho); } } int query(int v) { int resp = 0; while(v > 0) { resp += bit[v]; v -= v&-v; } return resp; } void update(int v, int val) { while(v < MAXN) { bit[v] += val; v += v&-v; } } void dfs2(int v) { for(int i = 0; i < (int) myNewParties[v].size(); i++) { int j = myNewParties[v][i]; int l = party[j][1]; int r = party[j][2]; update(l, 1); update(r + 1, -1); } resp[v] = query(idade[v]); for(int i = 0; i < (int) grafo[v].size(); i++) { int filho = grafo[v][i]; dfs2(filho); } for(int i = 0; i < (int) myNewParties[v].size(); i++) { int j = myNewParties[v][i]; int l = party[j][1]; int r = party[j][2]; update(l, -1); update(r + 1, 1); } } int main() { int n, m; scanf("%d %d", &n, &m); assert(1 <= n); assert(n <= MAX); assert(1 <= m); assert(m <= MAX); for(int i = 1; i <= n; i++) { scanf("%d %d", &idade[i], &pai[i]); assert(1 <= idade[i]); assert(idade[i] <= MAX); assert(1 <= pai[i]); assert(pai[i] <= n); if(i == 1) assert(pai[i] == i); else assert(pai[i] != i); if(i != 1) grafo[pai[i]].push_back(i); } for(int i = 1; i <= n; i++) assert(idade[i] <= idade[pai[i]]); for(int j = 1; j <= m; j++) { scanf("%d %d %d", &party[j][0], &party[j][1], &party[j][2]); myParties[party[j][0]].push_back(j); assert(1 <= party[j][0]); assert(party[j][0] <= n); assert(1 <= party[j][1]); assert(party[j][1] <= idade[party[j][0]]); assert(idade[party[j][0]] <= party[j][2]); assert(party[j][2] <= MAX); } dfs(1); dfs2(1); for(int i = 1; i <= n; i++) { if(i != 1) printf(" "); printf("%d", resp[i]); } printf("\n"); }