1 #include <iostream>
2 #include <cstdio>
3 #include <algorithm>
4 #include <cstring>
5 #include <vector>
6 #include <utility>
7 #include <iomanip>
8 #include <string>
9 #include <cmath>
10 #include <queue>
11 #include <assert.h>
12 #include <map>
13 #include <ctime>
14 #include <cstdlib>
15 #include <stack>
16 #define LOCAL
17 const int MAXN = 1020000 + 10;
18 const int INF = 100000000;
19 const int SIZE = 450;
20 const int maxnode = 0x7fffffff + 10;
21 using namespace std;
22 vector<long long>G[MAXN];
23 stack<long long>S;
24 long long n;
25 long long b[MAXN];
26 long long c[MAXN], l[MAXN], m;
27
28 struct SPLAY{
29 struct Node{
30 long long size;
31 long long val, sum;
32 Node *parent, *ch[2];
33
34 long long cmp(){
35 if (parent->ch[0] == this) return 0;
36 else return 1;
37 }
38 }*nil, _nil, mem[MAXN], *root[MAXN];
39 long long tot, pos;//pos表示当前根是哪一个
40
41 void update(Node *&t){
42 if (t == nil) return;
43 t->size = 1;
44 t->size += t->ch[0]->size + t->ch[1]->size;
45 t->sum = t->val;
46 t->sum += t->ch[0]->sum + t->ch[1]->sum;
47 return;
48 }
49 void init(){
50 //循环哨兵
51 nil = &_nil;
52 _nil.val = _nil.size =_nil.sum = 0;
53 _nil.parent = _nil.ch[0] = _nil.ch[1] = nil;
54
55 tot = 0;
56 //没有根就只能加一点特判断了
57 }
58 Node *NEW(long long val){
59 Node *p = &mem[tot++];
60 p->size = 1;
61 p->val = p->sum = val;
62 p->parent = p->ch[0] = p->ch[1] = nil;
63 return p;
64 }
65 //旋转,d代表1右旋
66 void Rotate(Node *t, long long d){
67 Node *p = t->parent;
68 t = p->ch[d ^ 1];
69 p->ch[d ^ 1] = t->ch[d];
70 if (t->ch[d] != nil) t->ch[d]->parent = p;
71 t->ch[d] = p;
72 t->parent = p->parent;
73 //注意不是引用
74 if (t->parent != nil){
75 if (t->parent->ch[0] == p) t->parent->ch[0] = t;
76 else t->parent->ch[1] = t;
77 }
78 p->parent = t;
79 if (t->parent == nil) root[pos] = t;
80 update(p);
81 update(t);
82 }
83 //没标记就是好TAT
84 Node* splay(Node *x, Node *y){
85 while (x->parent != y){
86 if (x->parent->parent == y){
87 Rotate(x, x->cmp() ^ 1);
88 break;
89 }else{
90 Rotate(x->parent, x->parent->cmp() ^ 1);
91 Rotate(x, x->cmp() ^ 1);
92 }
93 update(x);
94 }
95 update(x);
96 return x;
97 }
98 void insert(Node *&t, long long val){
99 if (t == nil){
100 t = NEW(val);
101 return;
102 }
103 Node *x = t;
104 Node *y = t;
105 while (1){
106 long long d = (val >= x->val);
107 if (x->ch[d] == nil){
108 x->ch[d] = NEW(val);
109 x->ch[d]->parent = x;
110 //update(x);
111 t = splay(x->ch[d], nil);
112 return;
113 }else {x = x->ch[d];}
114 }
115 return;//不用update
116 }
117 void push(Node *&t){
118 if ( t == nil) return;
119 push(t->ch[1]);
120 S.push(t->val);
121 push(t->ch[0]);
122 }
123 //感动天地没有find!
124 Node* merge(Node *a, Node *b, long long pa, long long pb){
125 if (a == nil) return b;
126 else if (b == nil) return a;
127 //注意是将b插入a,为了启发式合并要判断大小
128 if (a->size < b->size){
129 //swap(root[pa], root[pb]);
130 swap(a, b);
131 }
132 push(b);//把p推到栈里面
133 while (!S.empty()){
134 insert(a, S.top());
135 S.pop();
136 }
137 //delete b;//可以删掉吧....
138 return a;
139 }
140
141 //表示在Node*t中sum比m小
142 long long get(Node *t, long long val){
143 Node *x = t;
144 long long cnt = 0;
145 while (1){
146 if (x == nil) break;
147 if (val >= x->sum) {cnt += x->size; break;}//一次性全部拿完,包括子树
148 //能往左走当然尽量往左
149 long long tmp = (x->ch[0]->sum);
150 //拿完左子树去右边拿
151 if (val >= (tmp + x->val)) {cnt += x->ch[0]->size + 1; val -= tmp + x->val; x = x->ch[1];}
152 else x = x->ch[0];//往左边拿
153 }
154 return cnt;
155 }
156 void work(){
157 init();
158 while (!S.empty()) S.pop();
159 long long Ans = 0;
160 for (long long i = n; i >= 1; i--){
161 if (G[i].size() == 0){//叶子节点
162 root[i] = NEW(c[i]);
163 if (c[i] <= m) Ans = max(Ans, l[i]);
164 continue;
165 }
166 if (i == 3){
167 //prlong long(root[8]);
168 //printf("\n\n\n");
169 }
170 root[i] = nil;//枚举每个管理者
171 pos = i;
172 insert(root[i], c[i]);
173 for (long long j = 0; j < G[i].size(); j++){
174 long long v = G[i][j];
175 root[i] = merge(root[i], root[G[i][j]], i, v);
176 if (i == 3){
177 // prlong long(root[3]);
178 //printf("\n\n\n");
179 }
180 }
181 //printf("%d\n", tot);
182 //if ((get(root[i], m) * l[i]) == 12)
183 //printf("");
184 if (i == 8){
185 //printf("%d", root[3]->size);
186 //prlong long(root[8]);
187 }
188 Ans = max(Ans, get(root[i], m) * l[i]);
189 }
190 /*pos = n;
191 insert(root[n], 10);
192 insert(root[n], 1);*/
193 printf("%lld\n", Ans);
194 //printf("%d", tot);
195 }
196 /*void print(Node *t){
197 if (t == nil) return ;
198 prlong long(t->ch[0]);
199 printf("%lld %lld\n", t->val, t->parent->val);
200 prlong long(t->ch[1]);
201 }*/
202 void debug(){
203 init();
204 Node *p = NEW(5);
205 insert(p, 3);
206 printf("%lld", p->val);
207 }
208 }A;
209
210
211 void read(){
212 //memest
213 long long sum = 0;
214 scanf("%lld%lld", &n, &m);//m为薪水总预算
215 for (long long i = 1; i <= n; i++){
216 //分别代表上级薪水领导力
217 scanf("%lld%lld%lld", &b[i], &c[i], &l[i]);
218 G[b[i]].push_back(i);
219 //sum += c[i];
220 //printf("%d %lld %d\n", b[i], c[i], (2568 / 428));
221 }
222 //第3个有6个
223 //printf("%d\n", m);
224 }
225
226 int main(){
227
228 read();
229 A.work();
230 //A.debug();
231 return 0;
232 }