#include <bits/stdc++.h>
#ifndef ONLINE_JUDGE
#define debug(...) fprintf(stderr, __VA_ARGS__)
#else
#define debug(...)
#endif
using namespace std;
using namespace chrono;
typedef long long i64;
constexpr int N(1e5+5);
int n,m,root,rt[N],sz[N],fa[N],cost[N],lead[N];
i64 ans,sum[N];
struct node{
int ch[2];
}t[N];
#define ls(u) t[u].ch[0]
#define rs(u) t[u].ch[1]
#define sum(u) t[u].sum
#define dir(u) rs(fa(u))==u
int merge(int u,int v){
if(!u||!v){
return u|v;
}
if(cost[u]<cost[v]){
swap(u,v);
}
rs(u)=merge(rs(u),v);
swap(ls(u),rs(u));
return u;
}
void erase(int& r){
int new_sz{sz[r]-1};
i64 new_sum{sum[r]-cost[r]};
r=merge(ls(r),rs(r));
sum[r]=new_sum;
sz[r]=new_sz;
}
namespace tree{
int h[N],p;
struct edge{
int p,v;
}e[N];
void add_dir_edge(int u,int v){
e[++p].p=h[u];
e[p].p=v;
h[u]=p;
}
void dfs(int u){
int i,v,new_root;
sz[rt[u]]=1;
sum[rt[u]]=cost[u];
for(i=h[u];i;i=e[i].p){
v=e[i].v;
dfs(v);
new_root=merge(rt[u],rt[v]);
sum[new_root]=sum[rt[u]]+sum[rt[v]];
sz[new_root]=sz[rt[u]]+sz[rt[v]];
rt[u]=new_root;
while(sum[rt[u]]>m){
erase(rt[u]);
}
}
ans=max(ans,sz[rt[u]]*(i64)(lead[u]));
}
}
int main() {
int i;
scanf("%d%d",&n,&m);
for(i=1;i<=n;++i){
scanf("%d%d%d",fa+i,cost+i,lead+i);
if(!fa[i]){
root=i;
}else{
tree::add_dir_edge(fa[i],i);
}
}
tree::dfs(root);
printf("%lld\n",ans);
return 0;
}