Problem:
For Programming Excellence
A countless number of skills are required to be an excellent programmer.
  Different skills have different importance degrees,
  and the total programming competence is measured by
  the sum of products of levels and importance degrees of his/her skills.
In this summer season,
  you are planning to attend a summer programming school.
  The school offers courses for many of such skills.
  Attending a course for a skill,
  your level of the skill will be improved in proportion to the tuition paid,
  one level per one yen of tuition, however,
  each skill has its upper limit of the level
  and spending more money will never improve the skill level further.
  Skills are not independent: For taking a course for a skill,
  except for the most basic course,
  you have to have at least a certain level of its prerequisite skill.
You want to realize the highest possible programming competence measure
  within your limited budget for tuition fees.
Input
The input consists of no more than 100 datasets, each in the following format.
n
k
h
1
...
h
n
s
1
...
s
n
p
2
...
p
n
l
2
...
l
n
The first line has two integers,
n
, the number of different skills between 2 and 100, inclusive, and
k
, the budget amount available between 1 and 10
5
, inclusive.
    In what follows, skills are numbered 1 through
n
.
The second line has
n
integers
h
1
...
h
n
,
    in which
h
i
is the maximum level of the skill
i
,
    between 1 and 10
5
, inclusive.
The third line has
n
integers
s
1
...
s
n
,
    in which
s
i
is the importance degree of the skill
i
,
    between 1 and 10
9
, inclusive.
The fourth line has
n
−1 integers
p
2
...
p
n
,
    in which
p
i
is the prerequisite skill of the skill
i
,
    between 1 and
i
−1, inclusive.
    The skill 1 has no prerequisites.
The fifth line has
n
−1 integers
l
2
...
l
n
,
    in which
l
i
is the least level of prerequisite skill
p
i
required to learn the skill
i
,
    between 1 and
h
p
i
, inclusive.
The end of the input is indicated by a line containing two zeros.
Output
For each dataset, output a single line containing one integer,
  which is the highest programming competence measure achievable,
  that is,
  the maximum sum of the products of
  levels and importance degrees of the skills,
  within the given tuition budget,
  starting with level zero for all the skills.
  You do not have to use up all the budget.
Sample Input
3 10
5 4 3
1 2 3
1 2
5 2
5 40
10 10 10 10 8
1 2 3 4 5
1 1 2 3
10 10 10 10
5 10
2 2 2 5 2
2 2 2 5 2
1 1 2 2
2 1 2 1
0 0
Output for the Sample Input
18
108
35

Submitted solutions:

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
const ll BIG_NUM = 2e9;
const ll  HUGE_NUM = 99999999999999999;
const ll MOD = 1e9+7;
const double EPS =  1e-9;

using namespace std;

const int SIZE = 100005;

struct Info{
	bool operator<(const struct Info &arg) const{
		return pre_need_level < arg.pre_need_level;
	}

	int index;
	ll limit,value,pre_node,pre_need_level;
};

struct Data{
	void set(ll arg_index,ll arg_diff){
		index = arg_index;
		diff = arg_diff;
	}
	ll index,diff;
};


ll V,K;
ll dp[105][SIZE];
ll first[SIZE],work[SIZE];
Info info[SIZE];
Data DEQ[SIZE];
vector<Info> G[SIZE];

void calc_dp(ll *base,ll *result,ll budget,ll value, ll limit){
	ll head = 0,tail = 0;
	for(int i = 0; i <= budget; i++){
		ll diff = base[i]-i*value;
		while(head < tail && DEQ[tail-1].diff <= diff)tail--;
		DEQ[tail++].set(i,diff);
		result[i] = DEQ[head].diff+i*value;
		if(i-DEQ[head].index == limit)head++;
	}
}

void recursive(int node_id,ll budget,ll *table){
	calc_dp(table,dp[node_id],budget,info[node_id].value,info[node_id].limit);
	for(int i = 0; i < G[node_id].size(); i++){
		int child = G[node_id][i].index;
		if(info[child].pre_need_level > budget)continue;
		
        recursive(child,budget-info[child].pre_need_level,table);
		table = dp[child];
		
        calc_dp(dp[child],work,budget,info[node_id].value,info[node_id].limit-info[child].pre_need_level);
		
        ll add = info[child].pre_need_level*info[node_id].value;
		for(int k = 0; k+info[child].pre_need_level <= budget; k++){
			dp[node_id][k+info[child].pre_need_level] = max(dp[node_id][k+info[child].pre_need_level],work[k]+add);
		}
	}
}

void solve(){
	for(int i = 0; i < V; i++){
		scanf("%lld",&info[i].limit);
		info[i].index = i;
	}
	for(int i = 0; i < V; i++) scanf("%lld",&info[i].value);
	for(int i = 1; i < V; i++){
		scanf("%lld",&info[i].pre_node);
		info[i].pre_node--;
	}
	for(int i = 1; i < V; i++){
		scanf("%lld",&info[i].pre_need_level);
		G[info[i].pre_node].push_back(info[i]);
	}
	for(int i = 0; i < V; i++){
		if(G[i].size() == 0)continue;
		sort(G[i].begin(),G[i].end());
	}
	for(int i = 0; i < V; i++)
		for(int k = 0; k <= K; k++)
			dp[i][k] = 0;
	for(int i = 0; i <= K; i++)	first[i] = 0;
	recursive(0,K,first);
	printf("%lld\n", dp[0][K]);
}

int main(){
	while(1){
		scanf("%lld %lld",&V,&K);
		if(V == 0 && K == 0)break;
		for(int i = 0; i < V; i++) G[i].clear();
		solve();
	}
	return 0;
}
accuracy: 1
time_ms: 3370
memory_kb: 89624
final_rank: 4

code_snippet: #include <algorithm>
#include <cstdio>
#include <vector>
using namespace std;
const int N = 301;
const long long maxn = 1e18;
int n, m;
long long f[N][100001], w[N][100001], tmp[100001];
pair<int, long long> d[100001];
vector<int>g[N];
int r[N], l[N], s[N];
void pre_tmp(){
    for (int i = 0; i <= m; i ++) tmp[i] = -maxn;
}
void work(long long*f, int v, int s) {
    if (!s) return;
    int l = 1;
    int r = 1;
    d[1] = {0, f[0]};
    for (int i = 1; i <= m; i ++) {
        while (l <= r && i - d[l].first > s) l ++;
        d[++r] = {i, f[i] - 1ll * i * v};
        while (r - l + 1 >= 2 && d[r].second >= d[r - 1].second) {
            d[r - 1] = d[r];
            r --;
        }
        f[i] = d[l].second + 1ll * v * i;
    }
}
void dfs(int x) {
    for (auto u:g[x]) {
        pre_tmp();
        for (int i = 0; i + l[u] <= m; i ++)
            tmp[l[u] + i] = f[x][i] + 1ll * l[u] * s[x];
        work(tmp, s[x], r[x] - l[u]);
        for (int i = 0; i <= m; i ++)
            f[u][i] = max(tmp[i], w[x][i]);
        dfs(u);
        for (int i = 0; i <= m; i ++)
            w[x][i] = max(w[x][i], f[u][i]);
    }
    work(f[x], s[x], r[x]);
    for (int i = 0; i <= m; i ++)
        f[x][i] = max(f[x][i], w[x][i]);
}
int main() {
    while (1) {
        scanf("%d %d", &n, &m);
        if (!n && !m) break;
        for (int i = 1; i <= n; i ++)
            scanf("%d", &r[i]);
        for (int i = 1; i <= n; i ++)
            scanf("%d", &s[i]);
        for (int i = 2; i <= n ;i  ++){
            int x;
            scanf("%d", &x);
            g[x].push_back(i);
        }
        for (int i = 2; i <= n; i ++)
            scanf("%d", &l[i]);
        for (int i = 1; i <= n; i ++) {
            sort(g[i].begin(), g[i].end(), [](int x, int y) { return l[x] > l[y]; });
            for (int j = 0; j <= m; j ++)
                f[i][j] = w[i][j] = -maxn;
        }
        f[1][0] = 0;
        dfs(1);
        long long mx = 0;
        for (int i = 0; i <= m; i ++)mx= max(mx, f[1][i]);
        printf("%lld\n", mx);
        for (int i = 1; i <= n; i ++)
            g[i].clear();
    }
    return 0;
}
accuracy: 1
time_ms: 6470
memory_kb: 164784
final_rank: 18

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;
using uint = unsigned int;
#define rep(i, n) for (int i = 0; i < n; i++)
#define all(v) v.begin(), v.end()
template <class T, class U>
inline bool chmax(T &a, U b) {
    if (a < b) {
        a = b;
        return true;
    }
    return false;
}
template <class T, class U>
inline bool chmin(T &a, U b) {
    if (a > b) {
        a = b;
        return true;
    }
    return false;
}
template <class T>
inline void compress(vector<T> &a) {
    sort(a.begin(), a.end());
    a.erase(unique(a.begin(), a.end()), a.end());
}
template <class T>
T rand(T l, T r) {
    static mt19937 mt(random_device{}());
    // [l, r)
    if constexpr (is_integral_v<T>) {
        return uniform_int_distribution<T>(l, r - 1)(mt);
    } else if constexpr (is_floating_point_v<T>) {
        return uniform_real_distribution<T>(l, r)(mt);
    }
}
constexpr int INF = 1001001001;
constexpr ll llINF = 3000000000000000010;
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
using pbds_set = tree<ll, null_type, less<ll>, rb_tree_tag, tree_order_statistics_node_update>;
using pbds_mset = tree<ll, null_type, less_equal<ll>, rb_tree_tag, tree_order_statistics_node_update>;
using pbds_umap = gp_hash_table<int, int>;
using pbds_trie = trie<string, null_type, trie_string_access_traits<>, pat_trie_tag, trie_prefix_search_node_update>;
struct linear_sieve {
    vector<int> least_factor, prime_list;
    linear_sieve(int n) : least_factor(n + 1, 0) {
        for (int i = 2; i <= n; i++) {
            if (least_factor[i] == 0) {
                least_factor[i] = i;
                prime_list.push_back(i);
            }
            for (int p : prime_list) {
                if (ll(i) * p > n || p > least_factor[i]) break;
                least_factor[i * p] = p;
            }
        }
    }
};
template <int modulo>
struct modint {
    int x;
    modint() : x(0) {}
    modint(int64_t y) : x(y >= 0 ? y % modulo : (modulo - (-y) % modulo) % modulo) {}
    modint &operator+=(const modint &p) {
        if ((x += p.x) >= modulo) x -= modulo;
        return *this;
    }
    modint &operator-=(const modint &p) {
        if ((x += modulo - p.x) >= modulo) x -= modulo;
        return *this;
    }
    modint &operator*=(const modint &p) {
        x = (int)(1LL * x * p.x % modulo);
        return *this;
    }
    modint &operator/=(const modint &p) {
        *this *= p.inv();
        return *this;
    }
    modint operator-() const { return modint(-x); }
    modint operator+(const modint &p) const { return modint(*this) += p; }
    modint operator-(const modint &p) const { return modint(*this) -= p; }
    modint operator*(const modint &p) const { return modint(*this) *= p; }
    modint operator/(const modint &p) const { return modint(*this) /= p; }
    bool operator==(const modint &p) const { return x == p.x; }
    bool operator!=(const modint &p) const { return x != p.x; }
    modint inv() const {
        int a = x, b = modulo, u = 1, v = 0, t;
        while (b > 0) {
            t = a / b;
            swap(a -= t * b, b);
            swap(u -= t * v, v);
        }
        return modint(u);
    }
    modint pow(int64_t n) const {
        modint ret(1), mul(x);
        while (n > 0) {
            if (n & 1) ret *= mul;
            mul *= mul;
            n >>= 1;
        }
        return ret;
    }
    friend ostream &operator<<(ostream &os, const modint &p) { return os << p.x; }
    friend istream &operator>>(istream &is, modint &a) {
        int64_t t;
        is >> t;
        a = modint<modulo>(t);
        return (is);
    }
    int val() const { return x; }
    static constexpr int mod() { return modulo; }
    static constexpr int half() { return (modulo + 1) >> 1; }
};
ll extgcd(ll a, ll b, ll &x, ll &y) {
    // ax+by=gcd(|a|,|b|)
    if (a < 0 || b < 0) {
        ll d = extgcd(abs(a), abs(b), x, y);
        if (a < 0) x = -x;
        if (b < 0) y = -y;
        return d;
    }
    if (b == 0) {
        x = 1;
        y = 0;
        return a;
    }
    ll d = extgcd(b, a % b, y, x);
    y -= a / b * x;
    return d;
}
template <typename T>
struct Binomial {
    vector<T> inv, fact, factinv;
    Binomial(int n) {
        inv.resize(n + 1);
        fact.resize(n + 1);
        factinv.resize(n + 1);
        inv[0] = fact[0] = factinv[0] = 1;
        for (int i = 1; i <= n; i++) fact[i] = fact[i - 1] * i;
        factinv[n] = fact[n].inv();
        inv[n] = fact[n - 1] * factinv[n];
        for (int i = n - 1; i >= 1; i--) {
            factinv[i] = factinv[i + 1] * (i + 1);
            inv[i] = fact[i - 1] * factinv[i];
        }
    }
    T C(int n, int r) {
        if (n < 0 || n < r || r < 0) return 0;
        return fact[n] * factinv[n - r] * factinv[r];
    }
    T P(int n, int r) {
        if (n < 0 || n < r || r < 0) return 0;
        return fact[n] * factinv[n - r];
    }
    T H(int n, int r) {
        if (n == 0 && r == 0) return 1;
        if (n < 0 || r < 0) return 0;
        return r == 0 ? 1 : C(n + r - 1, r);
    }
};
template <typename T, typename U>
inline istream &operator>>(istream &is, pair<T, U> &rhs) {
    return is >> rhs.first >> rhs.second;
}
template <typename T>
inline istream &operator>>(istream &is, vector<T> &v) {
    for (auto &e : v) is >> e;
    return is;
}
template <typename T, typename U>
inline ostream &operator<<(ostream &os, const pair<T, U> &rhs) {
    return os << rhs.first << " " << rhs.second;
}
template <typename T>
inline ostream &operator<<(ostream &os, const vector<T> &v) {
    for (auto itr = v.begin(), end_itr = v.end(); itr != end_itr;) {
        os << *itr;
        if (++itr != end_itr) os << " ";
    }
    return os;
}

using mint = modint<998244353>;
vector<ll>dp[100];
void solve() {
    int n, k;
    cin >> n >> k;
    if (n == 0 && k == 0) exit(0);
    vector<int> h(n), s(n), p(n), l(n);
    rep(i, n) {
        cin >> h[i];
        chmin(h[i], k);
    }
    cin >> s;
    vector<vector<int>> g(n);
    for (int i = 1; i < n; i++) {
        cin >> p[i];
        p[i]--;
        g[p[i]].push_back(i);
    }
    for (int i = 1; i < n; i++) cin >> l[i];
    auto apply = [&](ll value, int cap, vector<ll> &DP) {
        deque<pair<int, ll>> deq;
        rep(i, k + 1) {
            while (deq.size() && deq.back().second <= DP[i] - i * value) deq.pop_back();
            deq.push_back({i, DP[i] - i * value});
            DP[i] = deq.front().second + i * value;
            if (deq.front().first <= i - cap) deq.pop_front();
        }
        //return dp;
    };
    vector<ll> pre(k + 1);
    function<void(int)> dfs = [&](int v) {
        sort(all(g[v]), [&](int u1, int u2) { return l[u1] < l[u2]; });
        dp[v]=pre;
        apply(s[v],h[v],dp[v]);
        for (int u : g[v]) {
            dfs(u);
            apply(s[v], h[v] - l[u], dp[u]);
            rep(i, k + 1 - l[u]) chmax(dp[v][i + l[u]], dp[u][i] + 1LL * s[v] * l[u]);
        }
        pre=dp[v];
    };
    dfs(0);
    cout << *max_element(all(dp[0])) << endl;
}
int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    int t = 1;
    // cin >> t;
    while (1) solve();
}
accuracy: 1
time_ms: 7480
memory_kb: 84332
final_rank: 17

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;
using uint = unsigned int;
#define rep(i, n) for (int i = 0; i < n; i++)
#define all(v) v.begin(), v.end()
template <class T, class U>
inline bool chmax(T &a, U b) {
    if (a < b) {
        a = b;
        return true;
    }
    return false;
}
template <class T, class U>
inline bool chmin(T &a, U b) {
    if (a > b) {
        a = b;
        return true;
    }
    return false;
}
template <class T>
inline void compress(vector<T> &a) {
    sort(a.begin(), a.end());
    a.erase(unique(a.begin(), a.end()), a.end());
}
template <class T>
T rand(T l, T r) {
    static mt19937 mt(random_device{}());
    // [l, r)
    if constexpr (is_integral_v<T>) {
        return uniform_int_distribution<T>(l, r - 1)(mt);
    } else if constexpr (is_floating_point_v<T>) {
        return uniform_real_distribution<T>(l, r)(mt);
    }
}
constexpr int INF = 1001001001;
constexpr ll llINF = 3000000000000000010;
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
using pbds_set = tree<ll, null_type, less<ll>, rb_tree_tag, tree_order_statistics_node_update>;
using pbds_mset = tree<ll, null_type, less_equal<ll>, rb_tree_tag, tree_order_statistics_node_update>;
using pbds_umap = gp_hash_table<int, int>;
using pbds_trie = trie<string, null_type, trie_string_access_traits<>, pat_trie_tag, trie_prefix_search_node_update>;
struct linear_sieve {
    vector<int> least_factor, prime_list;
    linear_sieve(int n) : least_factor(n + 1, 0) {
        for (int i = 2; i <= n; i++) {
            if (least_factor[i] == 0) {
                least_factor[i] = i;
                prime_list.push_back(i);
            }
            for (int p : prime_list) {
                if (ll(i) * p > n || p > least_factor[i]) break;
                least_factor[i * p] = p;
            }
        }
    }
};
template <int modulo>
struct modint {
    int x;
    modint() : x(0) {}
    modint(int64_t y) : x(y >= 0 ? y % modulo : (modulo - (-y) % modulo) % modulo) {}
    modint &operator+=(const modint &p) {
        if ((x += p.x) >= modulo) x -= modulo;
        return *this;
    }
    modint &operator-=(const modint &p) {
        if ((x += modulo - p.x) >= modulo) x -= modulo;
        return *this;
    }
    modint &operator*=(const modint &p) {
        x = (int)(1LL * x * p.x % modulo);
        return *this;
    }
    modint &operator/=(const modint &p) {
        *this *= p.inv();
        return *this;
    }
    modint operator-() const { return modint(-x); }
    modint operator+(const modint &p) const { return modint(*this) += p; }
    modint operator-(const modint &p) const { return modint(*this) -= p; }
    modint operator*(const modint &p) const { return modint(*this) *= p; }
    modint operator/(const modint &p) const { return modint(*this) /= p; }
    bool operator==(const modint &p) const { return x == p.x; }
    bool operator!=(const modint &p) const { return x != p.x; }
    modint inv() const {
        int a = x, b = modulo, u = 1, v = 0, t;
        while (b > 0) {
            t = a / b;
            swap(a -= t * b, b);
            swap(u -= t * v, v);
        }
        return modint(u);
    }
    modint pow(int64_t n) const {
        modint ret(1), mul(x);
        while (n > 0) {
            if (n & 1) ret *= mul;
            mul *= mul;
            n >>= 1;
        }
        return ret;
    }
    friend ostream &operator<<(ostream &os, const modint &p) { return os << p.x; }
    friend istream &operator>>(istream &is, modint &a) {
        int64_t t;
        is >> t;
        a = modint<modulo>(t);
        return (is);
    }
    int val() const { return x; }
    static constexpr int mod() { return modulo; }
    static constexpr int half() { return (modulo + 1) >> 1; }
};
ll extgcd(ll a, ll b, ll &x, ll &y) {
    // ax+by=gcd(|a|,|b|)
    if (a < 0 || b < 0) {
        ll d = extgcd(abs(a), abs(b), x, y);
        if (a < 0) x = -x;
        if (b < 0) y = -y;
        return d;
    }
    if (b == 0) {
        x = 1;
        y = 0;
        return a;
    }
    ll d = extgcd(b, a % b, y, x);
    y -= a / b * x;
    return d;
}
template <typename T>
struct Binomial {
    vector<T> inv, fact, factinv;
    Binomial(int n) {
        inv.resize(n + 1);
        fact.resize(n + 1);
        factinv.resize(n + 1);
        inv[0] = fact[0] = factinv[0] = 1;
        for (int i = 1; i <= n; i++) fact[i] = fact[i - 1] * i;
        factinv[n] = fact[n].inv();
        inv[n] = fact[n - 1] * factinv[n];
        for (int i = n - 1; i >= 1; i--) {
            factinv[i] = factinv[i + 1] * (i + 1);
            inv[i] = fact[i - 1] * factinv[i];
        }
    }
    T C(int n, int r) {
        if (n < 0 || n < r || r < 0) return 0;
        return fact[n] * factinv[n - r] * factinv[r];
    }
    T P(int n, int r) {
        if (n < 0 || n < r || r < 0) return 0;
        return fact[n] * factinv[n - r];
    }
    T H(int n, int r) {
        if (n == 0 && r == 0) return 1;
        if (n < 0 || r < 0) return 0;
        return r == 0 ? 1 : C(n + r - 1, r);
    }
};
template <typename T, typename U>
inline istream &operator>>(istream &is, pair<T, U> &rhs) {
    return is >> rhs.first >> rhs.second;
}
template <typename T>
inline istream &operator>>(istream &is, vector<T> &v) {
    for (auto &e : v) is >> e;
    return is;
}
template <typename T, typename U>
inline ostream &operator<<(ostream &os, const pair<T, U> &rhs) {
    return os << rhs.first << " " << rhs.second;
}
template <typename T>
inline ostream &operator<<(ostream &os, const vector<T> &v) {
    for (auto itr = v.begin(), end_itr = v.end(); itr != end_itr;) {
        os << *itr;
        if (++itr != end_itr) os << " ";
    }
    return os;
}

using mint = modint<998244353>;
vector<ll>dp[100];
deque<pair<int, ll>> deq;
void solve() {
    int n, k;
    cin >> n >> k;
    if (n == 0 && k == 0) exit(0);
    vector<int> h(n), s(n), p(n), l(n);
    rep(i, n) {
        cin >> h[i];
        chmin(h[i], k);
    }
    cin >> s;
    vector<vector<int>> g(n);
    for (int i = 1; i < n; i++) {
        cin >> p[i];
        p[i]--;
        g[p[i]].push_back(i);
    }
    for (int i = 1; i < n; i++) cin >> l[i];
    auto apply = [&](ll value, int cap, vector<ll> &DP) {
        rep(i, k + 1) {
            while (deq.size() && deq.back().second <= DP[i] - i * value) deq.pop_back();
            deq.push_back({i, DP[i] - i * value});
            DP[i] = deq.front().second + i * value;
            if (deq.front().first <= i - cap) deq.pop_front();
        }
        deq.clear();
        //return dp;
    };
    vector<ll> pre(k + 1);
    function<void(int)> dfs = [&](int v) {
        sort(all(g[v]), [&](int u1, int u2) { return l[u1] < l[u2]; });
        dp[v]=pre;
        apply(s[v],h[v],dp[v]);
        for (int u : g[v]) {
            dfs(u);
            apply(s[v], h[v] - l[u], dp[u]);
            rep(i, k + 1 - l[u]) chmax(dp[v][i + l[u]], dp[u][i] + 1LL * s[v] * l[u]);
        }
        pre=dp[v];
    };
    dfs(0);
    cout << *max_element(all(dp[0])) << endl;
}
int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    int t = 1;
    // cin >> t;
    while (1) solve();
}
accuracy: 1
time_ms: 6500
memory_kb: 85476
final_rank: 14

code_snippet: #pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")

#include <bits/stdc++.h>

#define rep(i, s, n) for (int i = (int)(s); i < (int)(n); i++)
#define rrep(i, s, n) for (int i = (int)(n)-1; i >= (int)(s); i--)
#define all(v) v.begin(), v.end()

using i64 = std::int64_t;

template <typename T> bool chmin(T &a, const T &b) {
    if (a <= b) return false;
    a = b;
    return true;
}
template <typename T> bool chmax(T &a, const T &b) {
    if (a >= b) return false;
    a = b;
    return true;
}

const i64 INF = std::numeric_limits<i64>::max() / 4;

i64 dp[101][100010];

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    int n,k;
    while(std::cin >> n >> k, !(n == 0 && k == 0)) {
        std::vector g(n, std::vector<int>());
        std::vector<int> h(n);
        std::vector<i64> s(n);
        rep(i,0,n) {
            std::cin >> h[i];
            chmin(h[i], k);
        }
        rep(i,0,n) std::cin >> s[i];
        rep(i,1,n) {
            int p;
            std::cin >> p;
            p--;
            g[p].emplace_back(i);
        }
        std::vector<int> l(n);
        rep(i,1,n) std::cin >> l[i];
        std::vector<int> dfs_order, nxt(n);
        auto dfs1 = [&](auto &&self, int v, int nv) -> void {
            dfs_order.emplace_back(v);
            nxt[v] = nv;
            std::sort(all(g[v]), [&](int a, int b) { return l[a] > l[b]; });
            rep(i,0,g[v].size()) {
                self(self, g[v][i], (i == (int)g[v].size() - 1) ? nv : g[v][i+1]);
            }
        };
        dfs1(dfs1, 0, n);
        std::deque<int> d;
        auto f = [&](int u, int v, int l, int r) -> void {
            d.clear();
            auto tmp = dp[u];
            auto nxt = dp[v];
            rep(i,l,k+1) {
                while(!d.empty() && tmp[d.back()] - d.back() * s[u] < tmp[i - l] - (i - l) * s[u]) {
                    d.pop_back();
                }
                d.push_back(i - l);
                chmax(nxt[i], tmp[d.front()] - d.front() * s[u] + i * s[u]);
                if(d.front() == i - r) d.pop_front();
            }
        };
        rep(i,0,n+1) rep(j,0,k+1) dp[i][j] = -INF;
        dp[0][0] = 0;
        for(auto u: dfs_order) {
            for(auto v: g[u]) {
                f(u, v, l[v], h[u]);
            }
            f(u, nxt[u], 0, h[u]);
        }
        i64 ans = -1;
        rep(i,0,k+1) chmax(ans, dp[n][i]);
        std::cout << ans << '\n';
    }
}
accuracy: 1
time_ms: 4840
memory_kb: 82556
final_rank: 8

code_snippet: #pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")

#include <bits/stdc++.h>

#define rep(i, s, n) for (int i = (int)(s); i < (int)(n); i++)
#define rrep(i, s, n) for (int i = (int)(n)-1; i >= (int)(s); i--)
#define all(v) v.begin(), v.end()

using i64 = std::int64_t;

template <typename T> bool chmin(T &a, const T &b) {
    if (a <= b) return false;
    a = b;
    return true;
}
template <typename T> bool chmax(T &a, const T &b) {
    if (a >= b) return false;
    a = b;
    return true;
}

struct simple_deque {
    int l = 0, r = 0;
    int d[100100];
    simple_deque() = default;
    bool empty() { return l == r; }
    void push_back(int x) { d[r++] = x; }
    void pop_back() { r--; }
    void pop_front() { l++; }
    void clear() { l = r = 0; }
    int back() { return d[r - 1]; }
    int front() { return d[l]; }
};

const i64 INF = std::numeric_limits<i64>::max() / 4;

i64 dp[101][100010];

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    int n,k;
    while(std::cin >> n >> k, !(n == 0 && k == 0)) {
        std::vector g(n, std::vector<int>());
        std::vector<int> h(n);
        std::vector<i64> s(n);
        rep(i,0,n) {
            std::cin >> h[i];
            chmin(h[i], k);
        }
        rep(i,0,n) std::cin >> s[i];
        rep(i,1,n) {
            int p;
            std::cin >> p;
            p--;
            g[p].emplace_back(i);
        }
        std::vector<int> l(n);
        rep(i,1,n) std::cin >> l[i];
        std::vector<int> dfs_order, nxt(n);
        auto dfs1 = [&](auto &&self, int v, int nv) -> void {
            dfs_order.emplace_back(v);
            nxt[v] = nv;
            std::sort(all(g[v]), [&](int a, int b) { return l[a] > l[b]; });
            rep(i,0,g[v].size()) {
                self(self, g[v][i], (i == (int)g[v].size() - 1) ? nv : g[v][i+1]);
            }
        };
        dfs1(dfs1, 0, n);
        std::deque<int> d;
        auto f = [&](int u, int v, int l, int r) -> void {
            d.clear();
            auto tmp = dp[u];
            auto nxt = dp[v];
            rep(i,l,k+1) {
                while(!d.empty() && tmp[d.back()] - d.back() * s[u] < tmp[i - l] - (i - l) * s[u]) {
                    d.pop_back();
                }
                d.push_back(i - l);
                chmax(nxt[i], tmp[d.front()] - d.front() * s[u] + i * s[u]);
                if(d.front() == i - r) d.pop_front();
            }
        };
        rep(i,0,n+1) rep(j,0,k+1) dp[i][j] = -INF;
        dp[0][0] = 0;
        for(auto u: dfs_order) {
            for(auto v: g[u]) {
                f(u, v, l[v], h[u]);
            }
            f(u, nxt[u], 0, h[u]);
        }
        i64 ans = -1;
        rep(i,0,k+1) chmax(ans, dp[n][i]);
        std::cout << ans << '\n';
    }
}
accuracy: 1
time_ms: 4800
memory_kb: 82596
final_rank: 7

code_snippet: #pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")

#include <bits/stdc++.h>

#define rep(i, s, n) for (int i = (int)(s); i < (int)(n); i++)
#define rrep(i, s, n) for (int i = (int)(n)-1; i >= (int)(s); i--)
#define all(v) v.begin(), v.end()

using i64 = std::int64_t;

template <typename T> bool chmin(T &a, const T &b) {
    if (a <= b) return false;
    a = b;
    return true;
}
template <typename T> bool chmax(T &a, const T &b) {
    if (a >= b) return false;
    a = b;
    return true;
}

struct simple_deque {
    int l = 0, r = 0;
    int d[100100];
    simple_deque() = default;
    bool empty() { return l == r; }
    void push_back(int x) { d[r++] = x; }
    void pop_back() { r--; }
    void pop_front() { l++; }
    void clear() { l = r = 0; }
    int back() { return d[r - 1]; }
    int front() { return d[l]; }
};

const i64 INF = std::numeric_limits<i64>::max() / 4;

i64 dp[101][100010];

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    int n,k;
    while(std::cin >> n >> k, !(n == 0 && k == 0)) {
        std::vector g(n, std::vector<int>());
        std::vector<int> h(n);
        std::vector<i64> s(n);
        rep(i,0,n) {
            std::cin >> h[i];
            chmin(h[i], k);
        }
        rep(i,0,n) std::cin >> s[i];
        rep(i,1,n) {
            int p;
            std::cin >> p;
            p--;
            g[p].emplace_back(i);
        }
        std::vector<int> l(n);
        rep(i,1,n) std::cin >> l[i];
        std::vector<int> dfs_order, nxt(n);
        auto dfs1 = [&](auto &&self, int v, int nv) -> void {
            dfs_order.emplace_back(v);
            nxt[v] = nv;
            std::sort(all(g[v]), [&](int a, int b) { return l[a] > l[b]; });
            rep(i,0,g[v].size()) {
                self(self, g[v][i], (i == (int)g[v].size() - 1) ? nv : g[v][i+1]);
            }
        };
        dfs1(dfs1, 0, n);
        simple_deque d;
        auto f = [&](int u, int v, int l, int r) -> void {
            d.clear();
            auto tmp = dp[u];
            auto nxt = dp[v];
            rep(i,l,k+1) {
                while(!d.empty() && tmp[d.back()] - d.back() * s[u] < tmp[i - l] - (i - l) * s[u]) {
                    d.pop_back();
                }
                d.push_back(i - l);
                chmax(nxt[i], tmp[d.front()] - d.front() * s[u] + i * s[u]);
                if(d.front() == i - r) d.pop_front();
            }
        };
        rep(i,0,n+1) rep(j,0,k+1) dp[i][j] = -INF;
        dp[0][0] = 0;
        for(auto u: dfs_order) {
            for(auto v: g[u]) {
                f(u, v, l[v], h[u]);
            }
            f(u, nxt[u], 0, h[u]);
        }
        i64 ans = -1;
        rep(i,0,k+1) chmax(ans, dp[n][i]);
        std::cout << ans << '\n';
    }
}
accuracy: 1
time_ms: 3850
memory_kb: 82704
final_rank: 5

code_snippet: #ifdef noimi
#include <stdc++.h>
#else
#include <bits/stdc++.h>
#endif

#define ll long long

#define REP0(n) for(ll iiii = 0; iiii < (n); i++)
#define REP1(i, n) for(ll i = 0; i < (n); i++)
#define REP2(i, a, b) for(ll i = (a); i < (b); i++)
#define overload3(a, b, c, name, ...) name
#define rep(...) overload3(__VA_ARGS__, REP2, REP1, REP0)(__VA_ARGS__)

#define vi vector<int>
using namespace std;

template <typename T, typename S> bool chmax(T &x, const S &y) { return (x < y ? x = y, true : false); }

template <typename T> ostream &operator<<(ostream &os, const vector<T> &v) {
    os << "{";
    rep(i, v.size()) {
        if(i) os << ", ";
        os << v[i];
    }
    return os << "}";
}
struct S {
    int l, r;
    ll v, d;
};

ostream &operator<<(ostream &os, S s) { return os << "(" << s.l << ", " << s.r << ", " << s.v << ", " << s.d << ")"; }

// deque
struct DEQUE {
    int l, r;
    int d[100100];
    DEQUE() : l(0), r(0) {}
    bool empty() { return l == r; }
    void push_back(int x) { d[r++] = x; }
    void pop_back() { r--; }
    void pop_front() { l++; }
    void clear() { l = r = 0; }
    int back() { return d[r - 1]; }
    int front() { return d[l]; }
};

ll dp[101][100010];

int main() {
    DEQUE d;
    while(true) {
        int n, k;
        cin >> n >> k;
        if(!n) exit(0);

        vi h(n);
        vector<ll> s(n);
        vector<vi> g(n);
        rep(i, n) cin >> h[i], h[i] = min(h[i], k);
        rep(i, n) cin >> s[i];

        rep(i, 1, n) {
            int x;
            cin >> x;
            x--;
            g[x].emplace_back(i);
        }
        vi l(n);
        rep(i, 1, n) cin >> l[i];

        constexpr ll inf = 1e18;
        rep(i, n + 1) rep(j, k + 1) dp[i][j] = -inf;

        vector<int> idx, nxt(n);
        {
            auto dfs = [&](auto &&f, int x, int nv) -> void {
                idx.emplace_back(x);
                sort(begin(g[x]), end(g[x]), [&](int i, int j) { return l[i] > l[j]; });
                rep(i, g[x].size()) { f(f, g[x][i], (i == g[x].size() - 1 ? nv : g[x][i + 1])); }
                nxt[x] = nv;
            };
            dfs(dfs, 0, n);
        }

        dp[0][0] = 0;

        auto f = [&](ll *tmp, ll *nxt, ll s, ll L, ll R) {
            // rep(i, k + 1) tmp[i] -= i * s;
            d.clear();
            rep(i, L, k + 1) {
                while(!d.empty() and tmp[d.back()] - d.back() * s < tmp[i - L] - (i - L) * s) d.pop_back();
                d.push_back(i - L);
                chmax(nxt[i], tmp[d.front()] - d.front() * s + i * s);
                if(d.front() == i - R) d.pop_front();
            }
        };

        rep(i, n) {
            int x = idx[i];
            for(auto e : g[x]) {
                int L = l[e], R = h[x];
                f(dp[x], dp[e], s[x], L, R);
            }
            int e = idx[i + 1];
            f(dp[x], dp[nxt[x]], s[x], 0, h[x]);
        }

        ll ma = 0;
        rep(j, k + 1) chmax(ma, dp[n][j]);
        cout << ma << endl;
    }
}
accuracy: 1
time_ms: 3300
memory_kb: 82456
final_rank: 1

code_snippet: #ifdef noimi
#include <stdc++.h>
#else
#include <bits/stdc++.h>
#endif

#define ll long long

#define REP0(n) for(ll iiii = 0; iiii < (n); i++)
#define REP1(i, n) for(ll i = 0; i < (n); i++)
#define REP2(i, a, b) for(ll i = (a); i < (b); i++)
#define overload3(a, b, c, name, ...) name
#define rep(...) overload3(__VA_ARGS__, REP2, REP1, REP0)(__VA_ARGS__)

#define vi vector<int>
using namespace std;

template <typename T, typename S> bool chmax(T &x, const S &y) { return (x < y ? x = y, true : false); }

template <typename T> ostream &operator<<(ostream &os, const vector<T> &v) {
    os << "{";
    rep(i, v.size()) {
        if(i) os << ", ";
        os << v[i];
    }
    return os << "}";
}
struct S {
    int l, r;
    ll v, d;
};

ostream &operator<<(ostream &os, S s) { return os << "(" << s.l << ", " << s.r << ", " << s.v << ", " << s.d << ")"; }

// deque
struct DEQUE {
    int l, r;
    int d[100100];
    DEQUE() : l(0), r(0) {}
    bool empty() { return l == r; }
    void push_back(int x) { d[r++] = x; }
    void pop_back() { r--; }
    void pop_front() { l++; }
    void clear() { l = r = 0; }
    int back() { return d[r - 1]; }
    int front() { return d[l]; }
};

ll dp[101][100010];

int main() {
    DEQUE d;
    while(true) {
        int n, k;
        cin >> n >> k;
        if(!n) exit(0);

        vi h(n), par(n);
        vector<ll> s(n);
        vector<vi> g(n);
        rep(i, n) cin >> h[i], h[i] = min(h[i], k);
        rep(i, n) cin >> s[i];

        rep(i, 1, n) {
            int x;
            cin >> x;
            x--;
            g[x].emplace_back(i);
            par[i] = x;
        }
        vi l(n);
        rep(i, 1, n) cin >> l[i];

        constexpr ll inf = 1e18;
        rep(i, n + 1) rep(j, k + 1) dp[i][j] = -inf;
        // vector<vector<ll>> dp(n + 1, vector<ll>(k + 1, -inf));

        vector<int> idx, nxt(n);
        {
            auto dfs = [&](auto &&f, int x, int nv) -> void {
                idx.emplace_back(x);
                sort(begin(g[x]), end(g[x]), [&](int i, int j) { return l[i] > l[j]; });
                rep(i, g[x].size()) { f(f, g[x][i], (i == g[x].size() - 1 ? nv : g[x][i + 1])); }
                nxt[x] = nv;
            };
            dfs(dfs, 0, n);
        }

        dp[0][0] = 0;
        idx.emplace_back(n);
        par.emplace_back(-1);

        auto f = [&](ll *tmp, ll *nxt, ll s, ll L, ll R) {
            // rep(i, k + 1) tmp[i] -= i * s;
            d.clear();
            rep(i, L, k + 1) {
                while(!d.empty() and tmp[d.back()] - d.back() * s < tmp[i - L] - (i - L) * s) d.pop_back();
                d.push_back(i - L);
                chmax(nxt[i], tmp[d.front()] - d.front() * s + i * s);
                if(d.front() == i - R) d.pop_front();
            }
        };

        rep(i, n) {
            int x = idx[i];
            for(auto e : g[x]) {
                int L = l[e], R = h[x];
                f(dp[x], dp[e], s[x], L, R);
            }
            int e = idx[i + 1];
            f(dp[x], dp[nxt[x]], s[x], 0, h[x]);
        }

        ll ma = 0;
        rep(j, k + 1) chmax(ma, dp[n][j]);
        cout << ma << endl;
    }
}
accuracy: 1
time_ms: 3300
memory_kb: 82676
final_rank: 2

code_snippet: #ifdef noimi
#include <stdc++.h>
#else
#include <bits/stdc++.h>
#endif

#define ll long long

#define REP0(n) for(ll iiii = 0; iiii < (n); i++)
#define REP1(i, n) for(ll i = 0; i < (n); i++)
#define REP2(i, a, b) for(ll i = (a); i < (b); i++)
#define overload3(a, b, c, name, ...) name
#define rep(...) overload3(__VA_ARGS__, REP2, REP1, REP0)(__VA_ARGS__)

#define vi vector<int>
using namespace std;

template <typename T, typename S> bool chmax(T &x, const S &y) { return (x < y ? x = y, true : false); }

template <typename T> ostream &operator<<(ostream &os, const vector<T> &v) {
    os << "{";
    rep(i, v.size()) {
        if(i) os << ", ";
        os << v[i];
    }
    return os << "}";
}
struct S {
    int l, r;
    ll v, d;
};

ostream &operator<<(ostream &os, S s) { return os << "(" << s.l << ", " << s.r << ", " << s.v << ", " << s.d << ")"; }

// deque
struct DEQUE {
    int l, r;
    int d[100100];
    DEQUE() : l(0), r(0) {}
    bool empty() { return l == r; }
    void push_back(int x) { d[r++] = x; }
    void pop_back() { r--; }
    void pop_front() { l++; }
    void clear() { l = r = 0; }
    int back() { return d[r - 1]; }
    int front() { return d[l]; }
};

int main() {
    DEQUE d;
    while(true) {
        int n, k;
        cin >> n >> k;
        if(!n) exit(0);

        vi h(n), par(n);
        vector<ll> s(n);
        vector<vi> g(n);
        rep(i, n) cin >> h[i], h[i] = min(h[i], k);
        rep(i, n) cin >> s[i];

        rep(i, 1, n) {
            int x;
            cin >> x;
            x--;
            g[x].emplace_back(i);
            par[i] = x;
        }
        vi l(n);
        rep(i, 1, n) cin >> l[i];

        constexpr ll inf = 1e18;
        vector<vector<ll>> dp(n + 1, vector<ll>(k + 1, -inf));

        vector<int> idx, nxt(n);
        {
            auto dfs = [&](auto &&f, int x, int nv) -> void {
                idx.emplace_back(x);
                sort(begin(g[x]), end(g[x]), [&](int i, int j) { return l[i] > l[j]; });
                rep(i, g[x].size()) { f(f, g[x][i], (i == g[x].size() - 1 ? nv : g[x][i + 1])); }
                nxt[x] = nv;
            };
            dfs(dfs, 0, n);
        }

        dp[0][0] = 0;
        idx.emplace_back(n);
        par.emplace_back(-1);

        auto f = [&](vector<ll> &tmp, vector<ll> &nxt, ll s, ll L, ll R) {
            // rep(i, k + 1) tmp[i] -= i * s;
            d.clear();
            rep(i, L, k + 1) {
                while(!d.empty() and tmp[d.back()] - d.back() * s < tmp[i - L] - (i - L) * s) d.pop_back();
                d.push_back(i - L);
                chmax(nxt[i], tmp[d.front()] - d.front() * s + i * s);
                if(d.front() == i - R) d.pop_front();
            }
        };

        vector<ll> DP(k + 1, -inf);
        DP[0] = 0;

        rep(i, n) {
            int x = idx[i];
            for(auto e : g[x]) {
                int L = l[e], R = h[x];
                f(dp[x], dp[e], s[x], L, R);
            }
            int e = idx[i + 1];
            f(dp[x], dp[nxt[x]], s[x], 0, h[x]);
        }

        ll ma = 0;
        rep(j, k + 1) chmax(ma, dp[n][j]);
        cout << ma << endl;
    }
}
accuracy: 1
time_ms: 4620
memory_kb: 83812
final_rank: 6

code_snippet: #ifdef noimi
#include <stdc++.h>
#else
#include <bits/stdc++.h>
#endif

#define ll long long

#define REP0(n) for(ll iiii = 0; iiii < (n); i++)
#define REP1(i, n) for(ll i = 0; i < (n); i++)
#define REP2(i, a, b) for(ll i = (a); i < (b); i++)
#define overload3(a, b, c, name, ...) name
#define rep(...) overload3(__VA_ARGS__, REP2, REP1, REP0)(__VA_ARGS__)

#define vi vector<int>
using namespace std;

template <typename T, typename S> bool chmax(T &x, const S &y) { return (x < y ? x = y, true : false); }

template <typename T> ostream &operator<<(ostream &os, const vector<T> &v) {
    os << "{";
    rep(i, v.size()) {
        if(i) os << ", ";
        os << v[i];
    }
    return os << "}";
}
struct S {
    int l, r;
    ll v, d;
};

ostream &operator<<(ostream &os, S s) { return os << "(" << s.l << ", " << s.r << ", " << s.v << ", " << s.d << ")"; }

// deque
struct DEQUE {
    int l, r;
    int d[100100];
    DEQUE() : l(0), r(0) {}
    bool empty() { return l == r; }
    void push_back(int x) { d[r++] = x; }
    void pop_back() { r--; }
    void pop_front() { l++; }
    void clear() { l = r = 0; }
    int back() { return d[r - 1]; }
    int front() { return d[l]; }
};

int main() {
    DEQUE d;
    while(true) {
        int n, k;
        cin >> n >> k;
        if(!n) exit(0);

        vi h(n), par(n);
        vector<ll> s(n);
        vector<vi> g(n);
        rep(i, n) cin >> h[i], h[i] = min(h[i], k);
        rep(i, n) cin >> s[i];

        rep(i, 1, n) {
            int x;
            cin >> x;
            x--;
            g[x].emplace_back(i);
            par[i] = x;
        }
        vi l(n);
        rep(i, 1, n) cin >> l[i];

        constexpr ll inf = 1e18;
        vector<vector<ll>> dp(n + 1, vector<ll>(k + 1, -inf));

        vector<int> idx, nxt(n);
        {
            auto dfs = [&](auto &&f, int x, int nv) -> void {
                idx.emplace_back(x);
                sort(begin(g[x]), end(g[x]), [&](int i, int j) { return l[i] > l[j]; });
                rep(i, g[x].size()) { f(f, g[x][i], (i == g[x].size() - 1 ? nv : g[x][i + 1])); }
                nxt[x] = nv;
            };
            dfs(dfs, 0, n);
        }

        dp[0][0] = 0;
        idx.emplace_back(n);
        par.emplace_back(-1);

        auto f = [&](vector<ll> tmp, vector<ll> &nxt, ll s, ll L, ll R) {
            rep(i, k + 1) tmp[i] -= i * s;
            d.clear();
            rep(i, L, k + 1) {
                while(!d.empty() and tmp[d.back()] < tmp[i - L]) d.pop_back();
                d.push_back(i - L);
                chmax(nxt[i], tmp[d.front()] + i * s);
                if(d.front() == i - R) d.pop_front();
            }
        };

        vector<ll> DP(k + 1, -inf);
        DP[0] = 0;

        rep(i, n) {
            int x = idx[i];
            for(auto e : g[x]) {
                int L = l[e], R = h[x];
                f(dp[x], dp[e], s[x], L, R);
            }
            int e = idx[i + 1];
            f(dp[x], dp[nxt[x]], s[x], 0, h[x]);
        }

        ll ma = 0;
        rep(j, k + 1) chmax(ma, dp[n][j]);
        cout << ma << endl;
    }
}
accuracy: 1
time_ms: 5420
memory_kb: 84748
final_rank: 10

code_snippet: #ifdef noimi
#include <stdc++.h>
#else
#include <bits/stdc++.h>
#endif

#define ll long long

#define REP0(n) for(ll iiii = 0; iiii < (n); i++)
#define REP1(i, n) for(ll i = 0; i < (n); i++)
#define REP2(i, a, b) for(ll i = (a); i < (b); i++)
#define overload3(a, b, c, name, ...) name
#define rep(...) overload3(__VA_ARGS__, REP2, REP1, REP0)(__VA_ARGS__)

#define vi vector<int>
using namespace std;

template <typename T, typename S> bool chmax(T &x, const S &y) { return (x < y ? x = y, true : false); }

template <typename T> ostream &operator<<(ostream &os, const vector<T> &v) {
    os << "{";
    rep(i, v.size()) {
        if(i) os << ", ";
        os << v[i];
    }
    return os << "}";
}
struct S {
    int l, r;
    ll v, d;
};

ostream &operator<<(ostream &os, S s) { return os << "(" << s.l << ", " << s.r << ", " << s.v << ", " << s.d << ")"; }

// deque
struct DEQUE {
    int l, r;
    int d[100100];
    DEQUE() : l(0), r(0) {}
    bool empty() { return l == r; }
    void push_back(int x) { d[r++] = x; }
    void pop_back() { r--; }
    void pop_front() { l++; }
    void clear() { l = r = 0; }
    int back() { return d[r - 1]; }
    int front() { return d[l]; }
};

int main() {
    DEQUE d;
    while(true) {
        int n, k;
        cin >> n >> k;
        if(!n) exit(0);

        vi h(n), par(n);
        vector<ll> s(n);
        vector<vi> g(n);
        rep(i, n) cin >> h[i], h[i] = min(h[i], k);
        rep(i, n) cin >> s[i];

        rep(i, 1, n) {
            int x;
            cin >> x;
            x--;
            g[x].emplace_back(i);
            par[i] = x;
        }
        vi l(n);
        rep(i, 1, n) cin >> l[i];

        constexpr ll inf = 1e18;
        vector<vector<ll>> dp(n + 1, vector<ll>(k + 1, -inf));

        vector<int> idx, nxt(n);
        {
            auto dfs = [&](auto &&f, int x, int nv) -> void {
                idx.emplace_back(x);
                sort(begin(g[x]), end(g[x]), [&](int i, int j) { return l[i] > l[j]; });
                rep(i, g[x].size()) { f(f, g[x][i], (i == g[x].size() - 1 ? nv : g[x][i + 1])); }
                nxt[x] = nv;
            };
            dfs(dfs, 0, n);
        }

        dp[0][0] = 0;
        idx.emplace_back(n);
        par.emplace_back(-1);

        auto f = [&](vector<ll> tmp, vector<ll> &nxt, ll s, ll L, ll R) {
            rep(i, k + 1) tmp[i] -= i * s;
            d.clear();
            rep(i, L, k + 1) {
                while(!d.empty() and tmp[d.back()] < tmp[i - L]) d.pop_back();
                d.push_back(i - L);
                chmax(nxt[i], tmp[d.front()] + i * s);
                if(d.front() == i - R) d.pop_front();
            }
        };

        vector<ll> DP(k + 1, -inf);
        DP[0] = 0;

        rep(i, n) {
            int x = idx[i];
            for(auto e : g[x]) {
                int L = l[e], R = h[x];
                f(dp[x], dp[e], s[x], L, R);
            }
            int e = idx[i + 1];
            f(dp[x], dp[nxt[x]], s[x], 0, h[x]);
        }

        ll ma = 0;
        rep(i, n + 1) rep(j, k + 1) chmax(ma, dp[i][j] + (i == n ? 0 : min<int>(h[i], k - j) * s[i]));
        cout << ma << endl;
    }
}
accuracy: 1
time_ms: 6070
memory_kb: 84784
final_rank: 12

code_snippet: #ifdef noimi
#include <stdc++.h>
#else
#include <bits/stdc++.h>
#endif

#define ll long long

#define REP0(n) for(ll iiii = 0; iiii < (n); i++)
#define REP1(i, n) for(ll i = 0; i < (n); i++)
#define REP2(i, a, b) for(ll i = (a); i < (b); i++)
#define overload3(a, b, c, name, ...) name
#define rep(...) overload3(__VA_ARGS__, REP2, REP1, REP0)(__VA_ARGS__)

#define vi vector<int>
using namespace std;

template <typename T, typename S> bool chmax(T &x, const S &y) { return (x < y ? x = y, true : false); }

template <typename T> ostream &operator<<(ostream &os, const vector<T> &v) {
    os << "{";
    rep(i, v.size()) {
        if(i) os << ", ";
        os << v[i];
    }
    return os << "}";
}
struct S {
    int l, r;
    ll v, d;
};

ostream &operator<<(ostream &os, S s) { return os << "(" << s.l << ", " << s.r << ", " << s.v << ", " << s.d << ")"; }

// deque
struct DEQUE {
    int l, r;
    int d[100100];
    DEQUE() : l(0), r(0) {}
    bool empty() { return l == r; }
    void push_back(int x) { d[r++] = x; }
    void pop_back() { r--; }
    void pop_front() { l++; }
    void clear() { l = r = 0; }
    int back() { return d[r - 1]; }
    int front() { return d[l]; }
};

int main() {
    DEQUE d;
    while(true) {
        int n, k;
        cin >> n >> k;
        if(!n) exit(0);

        vi h(n), par(n);
        vector<ll> s(n);
        vector<vi> g(n);
        rep(i, n) cin >> h[i], h[i] = min(h[i], k);
        rep(i, n) cin >> s[i];

        rep(i, 1, n) {
            int x;
            cin >> x;
            x--;
            g[x].emplace_back(i);
            par[i] = x;
        }
        vi l(n);
        rep(i, 1, n) cin >> l[i];

        constexpr ll inf = 1e18;
        vector<vector<ll>> dp(n + 1, vector<ll>(k + 1, -inf));

        vector<int> idx, nxt(n);
        {
            auto dfs = [&](auto &&f, int x, int nv) -> void {
                idx.emplace_back(x);
                sort(begin(g[x]), end(g[x]), [&](int i, int j) { return l[i] > l[j]; });
                rep(i, g[x].size()) { f(f, g[x][i], (i == g[x].size() - 1 ? nv : g[x][i + 1])); }
                nxt[x] = nv;
            };
            dfs(dfs, 0, n);
        }

        dp[0][0] = 0;
        idx.emplace_back(n);
        par.emplace_back(-1);

        auto f = [&](vector<ll> tmp, vector<ll> &nxt, ll s, ll L, ll R) {
            rep(i, k + 1) tmp[i] -= i * s;
            d.clear();
            // deque<int> d;
            rep(i, k + 1) {
                if(i - L >= 0) {
                    while(!d.empty() and tmp[d.back()] < tmp[i - L]) d.pop_back();
                    d.push_back(i - L);
                }
                if(!d.empty()) chmax(nxt[i], tmp[d.front()] + i * s);
                if(!d.empty() and d.front() == i - R) d.pop_front();
            }
            // rep(i, k + 1) { rep(j, i - R, i - L + 1) if(0 <= j) chmax(nxt[i], tmp[j] + s * i); }
        };

        vector<ll> DP(k + 1, -inf);
        DP[0] = 0;

        rep(i, n) {
            int x = idx[i];
            for(auto e : g[x]) {
                int L = l[e], R = h[x];
                f(dp[x], dp[e], s[x], L, R);
            }
            int e = idx[i + 1];
            f(dp[x], dp[nxt[x]], s[x], 0, h[x]);
        }

        ll ma = 0;
        rep(i, n + 1) rep(j, k + 1) chmax(ma, dp[i][j] + (i == n ? 0 : min<int>(h[i], k - j) * s[i]));
        cout << ma << endl;
    }
}
accuracy: 1
time_ms: 6370
memory_kb: 84820
final_rank: 13

code_snippet: #include <queue>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;

const long long INF = (1LL << 61);

class segment {
public:
	// segment y = a(x-l) + b (l <= x <= r)
	long long a, b; int l, r;
	segment() : a(0LL), b(0LL), l(0), r(0) {};
	segment(long long a_, long long b_, int l_, int r_) : a(a_), b(b_), l(l_), r(r_) {};
};

vector<segment> get_polyline(int K, const vector<long long>& v) {
	vector<segment> res;
	int pre = 0;
	for (int i = 0; i <= K + 1; i++) {
		if (i >= 2 && (i == K + 1 || v[i] - v[i - 1] != v[i - 1] - v[i - 2])) {
			if (v[i - 1] != -INF && v[pre] != -INF) {
				res.push_back(segment(v[i - 1] - v[i - 2], v[pre], pre, i - 1));
			}
			pre = i;
		}
		if (v[i] != -INF && (i == 0 || v[i - 1] == -INF) && (i == K || v[i + 1] == -INF)) {
			res.push_back(segment(0, v[i], i, i));
		}
	}
	return res;
}

vector<long long> max_convolve(int K, const vector<long long>& v1, const vector<long long>& v2) {
	vector<segment> p1 = get_polyline(K, v1);
	vector<segment> p2 = get_polyline(K, v2);
	vector<long long> res(K + 1, -INF);
	for (segment s1 : p1) {
		for (segment s2 : p2) {
			for (int i = s1.l + s2.l; i <= s1.r + s2.r && i <= K; i++) {
				int d = i - (s1.l + s2.l);
				long long x = s1.b + s2.b;
				if (s1.a > s2.a) {
					x += (d <= s1.r - s1.l ? s1.a * d : s1.a * (s1.r - s1.l) + s2.a * (d - (s1.r - s1.l)));
				}
				else {
					x += (d <= s2.r - s2.l ? s2.a * d : s2.a * (s2.r - s2.l) + s1.a * (d - (s2.r - s2.l)));
				}
				res[i] = max(res[i], x);
			}
		}
	}
	return res;
}

vector<long long> apply_skill(int K, int H, long long S, int L, const vector<long long>& v) {
	if (L > H) {
		return vector<long long>(K + 1, -INF);
	}
	vector<long long> res(K + 1, -INF);
	deque<pair<long long, int> > que;
	for (int i = 0; i <= K; i++) {
		if (i >= L && v[i - L] != -INF) {
			long long vs = v[i - L] - S * (i - L);
			while (!que.empty() && que.back().first <= vs) {
				que.pop_back();
			}
			que.push_back(make_pair(vs, i - L));
		}
		if (!que.empty() && que.front().second == i - (H + 1)) {
			que.pop_front();
		}
		if (!que.empty()) {
			res[i] = max(res[i], que.front().first + S * i);
		}
	}
	return res;
}

long long solve(int N, int K, const vector<int>& H, const vector<long long>& S, const vector<int>& P, const vector<int>& L) {
	vector<vector<int> > G(N);
	for (int i = 1; i < N; i++) {
		G[P[i]].push_back(i);
	}
	for (int i = 0; i < N; i++) {
		if (!G[i].empty()) {
			sort(G[i].begin(), G[i].end(), [&](int va, int vb) {
				return L[va] < L[vb];
			});
		}
	}
	vector<vector<long long> > dp(N, vector<long long>(K + 1, -INF));
	for (int i = N - 1; i >= 0; i--) {
		vector<long long> seq(K + 1, -INF);
		seq[0] = 0;
		for (int j = 0; j < int(G[i].size()); j++) {
			seq = max_convolve(K, seq, dp[G[i][j]]);
			vector<long long> res = apply_skill(K, H[i], S[i], L[G[i][j]], seq);
			for (int k = 0; k <= K; k++) {
				dp[i][k] = max(dp[i][k], res[k]);
			}
		}
		for (int j = 0; j <= K && j <= H[i]; j++) {
			dp[i][j] = max(dp[i][j], S[i] * j);
		}
	}
	long long answer = *max_element(dp[0].begin(), dp[0].end());
	return answer;
}

int main() {
	while (true) {
		int N, K;
		cin >> N >> K;
		if (N == 0 && K == 0) {
			break;
		}
		vector<long long> S(N);
		vector<int> H(N), P(N, -1), L(N, -1);
		for (int i = 0; i < N; i++) {
			cin >> H[i];
		}
		for (int i = 0; i < N; i++) {
			cin >> S[i];
		}
		for (int i = 1; i < N; i++) {
			cin >> P[i];
			P[i] -= 1;
		}
		for (int i = 1; i < N; i++) {
			cin >> L[i];
		}
		long long answer = solve(N, K, H, S, P, L);
		cout << answer << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 7340
memory_kb: 84552
final_rank: 16

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using uint = unsigned int;
using ull = unsigned long long;
#define rep(i,n) for(int i=0;i<int(n);i++)
#define rep1(i,n) for(int i=1;i<=int(n);i++)
#define per(i,n) for(int i=int(n)-1;i>=0;i--)
#define per1(i,n) for(int i=int(n);i>0;i--)
#define all(c) c.begin(),c.end()
#define si(x) int(x.size())
#define pb push_back
#define eb emplace_back
#define fs first
#define sc second
template<class T> using V = vector<T>;
template<class T> using VV = vector<vector<T>>;
template<class T,class U> bool chmax(T& x, U y){
	if(x<y){ x=y; return true; }
	return false;
}
template<class T,class U> bool chmin(T& x, U y){
	if(y<x){ x=y; return true; }
	return false;
}
template<class T> void mkuni(V<T>& v){sort(all(v));v.erase(unique(all(v)),v.end());}
template<class T> int lwb(const V<T>& v, const T& a){return lower_bound(all(v),a) - v.begin();}
template<class T>
V<T> Vec(size_t a) {
    return V<T>(a);
}
template<class T, class... Ts>
auto Vec(size_t a, Ts... ts) {
  return V<decltype(Vec<T>(ts...))>(a, Vec<T>(ts...));
}
template<class S,class T> ostream& operator<<(ostream& o,const pair<S,T> &p){
	return o<<"("<<p.fs<<","<<p.sc<<")";
}
template<class T> ostream& operator<<(ostream& o,const vector<T> &vc){
	o<<"{";
	for(const T& v:vc) o<<v<<",";
	o<<"}";
	return o;
}
constexpr ll TEN(int n) { return (n == 0) ? 1 : 10 * TEN(n-1); }

#ifdef LOCAL
#define show(x) cerr << "LINE" << __LINE__ << " : " << #x << " = " << (x) << endl
void dmpr(ostream& os){os<<endl;}
template<class T,class... Args>
void dmpr(ostream&os,const T&t,const Args&... args){
	os<<t<<" ~ ";
	dmpr(os,args...);
}
#define shows(...) cerr << "LINE" << __LINE__ << " : ";dmpr(cerr,##__VA_ARGS__)
#define dump(x) cerr << "LINE" << __LINE__ << " : " << #x << " = {";  \
	for(auto v: x) cerr << v << ","; cerr << "}" << endl;
#else
#define show(x) void(0)
#define dump(x) void(0)
#define shows(...) void(0)
#endif

template<class D> D divFloor(D a, D b){
	return a / b - (((a ^ b) < 0 && a % b != 0) ? 1 : 0);
}
template<class D> D divCeil(D a, D b) {
	return a / b + (((a ^ b) > 0 && a % b != 0) ? 1 : 0);
}

namespace SlideMax{
	using D = ll;
	const int X = 1000000;
	D a[X];
	int idx[X];
	int L,R,I,num_del;
	void clear(){
		L = R = I = num_del = 0;
	}
	void add(D v){
		while(L<R && v>a[R-1]) R--;			// D-D comparison v<a[R-1]
		a[R] = v;
		idx[R] = I;
		R++,I++;
	}
	void del(){
		if(L<R && idx[L] == num_del) L++;
		num_del++;
	}
	D getmax(){
		assert(L<R);
		return a[L];
	}
	int getargmax(){
		assert(L<R);
		return idx[L];
	}
}
const ll inf = TEN(18);
struct Item{
	// 重さw, 価値p の物体が n個
	// n個全部使い切ると下の頂点を使えるようになる
	int w; ll p; int n;
	friend ostream& operator<<(ostream &o,const Item& x){ return o<<"("<<x.w<<","<<x.p<<" * " << x.n << ")";}
};
void slide(V<ll>& f, int w, ll p, int n){
	int W = si(f)-1;
	rep(r,w){
		SlideMax::clear();
		if(r > W) break;
		for(int i=0,x=r;x<=W;i++,x+=w){
			SlideMax::add(f[x]-i*p);
			f[x] = SlideMax::getmax() + i*p;
			if(f[x] < -inf/2) f[x] = -inf;
			if(i >= n) SlideMax::del();
		}
	}
}
V<ll> treeKnapsack(VV<int> G, V<Item> items, int W){
	assert(si(G) == si(items));
	auto rec = [&](auto& self, int v, int p, V<ll>& dp_init)->void{
		V<ll> dp(W+1,-inf);
		auto& f = items[v];
		for(ll i=0; i+ll(f.w)*f.n<=W; i++){
			if(dp_init[i] != -inf) dp[i+f.w*f.n] = dp_init[i] + f.p * f.n;
		}
		for(int u: G[v]) if(u != p){
			self(self,u,v,dp);
		}
		slide(dp_init,f.w,f.p,f.n);	// <= n
		rep(i,W+1) chmax(dp[i], dp_init[i]);
		dp_init = dp;
	};
	V<ll> dp(W+1,-inf); dp[0] = 0;
	rec(rec,0,-1,dp); return dp;
}

int main(){
	cin.tie(0);
	ios::sync_with_stdio(false);		//DON'T USE scanf/printf/puts !!
	cout << fixed << setprecision(20);

	while(true){
		int N,W; cin >> N >> W;
		if(N == 0) break;
		V<int> h(N); rep(i,N) cin >> h[i];
		V<ll> p(N); rep(i,N) cin >> p[i];
		VV<int> child(N);
		rep1(i,N-1){
			int x; cin >> x; x--;
			child[x].pb(i);
		}
		V<int> need(N);
		rep1(i,N-1) cin >> need[i];

		VV<int> G;
		V<Item> items;
		int I = 0;
		V<int> par(N,-1);
		V<int> base(N);
		rep(v,N){
			sort(all(child[v]),[&](int l,int r){return need[l]<need[r];});
			int K = si(child[v]);
			rep(k,K+1){
				int id = I++;
				int n = (k == K ? h[v] : need[child[v][k]]) - (k == 0 ? 0 : need[child[v][k-1]]);
				items.pb({1,p[v],n});
				G.pb({});
				if(k != K){
					par[child[v][k]] = id;
				}
				if(k != 0){
					G[id-1].pb(id);
				}
				if(k == 0){
					base[v] = id;
				}
			}
		}
		rep1(v,N-1) G[par[v]].pb(base[v]);
		auto f = treeKnapsack(G,items,W);
		cout << *max_element(all(f)) << endl;
	}
}
accuracy: 1
time_ms: 7000
memory_kb: 86564
final_rank: 15

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using uint = unsigned int;
using ull = unsigned long long;
#define rep(i,n) for(int i=0;i<int(n);i++)
#define rep1(i,n) for(int i=1;i<=int(n);i++)
#define per(i,n) for(int i=int(n)-1;i>=0;i--)
#define per1(i,n) for(int i=int(n);i>0;i--)
#define all(c) c.begin(),c.end()
#define si(x) int(x.size())
#define pb push_back
#define eb emplace_back
#define fs first
#define sc second
template<class T> using V = vector<T>;
template<class T> using VV = vector<vector<T>>;
template<class T,class U> bool chmax(T& x, U y){
	if(x<y){ x=y; return true; }
	return false;
}
template<class T,class U> bool chmin(T& x, U y){
	if(y<x){ x=y; return true; }
	return false;
}
template<class T> void mkuni(V<T>& v){sort(all(v));v.erase(unique(all(v)),v.end());}
template<class T> int lwb(const V<T>& v, const T& a){return lower_bound(all(v),a) - v.begin();}
template<class T>
V<T> Vec(size_t a) {
    return V<T>(a);
}
template<class T, class... Ts>
auto Vec(size_t a, Ts... ts) {
  return V<decltype(Vec<T>(ts...))>(a, Vec<T>(ts...));
}
template<class S,class T> ostream& operator<<(ostream& o,const pair<S,T> &p){
	return o<<"("<<p.fs<<","<<p.sc<<")";
}
template<class T> ostream& operator<<(ostream& o,const vector<T> &vc){
	o<<"{";
	for(const T& v:vc) o<<v<<",";
	o<<"}";
	return o;
}
constexpr ll TEN(int n) { return (n == 0) ? 1 : 10 * TEN(n-1); }

#ifdef LOCAL
#define show(x) cerr << "LINE" << __LINE__ << " : " << #x << " = " << (x) << endl
void dmpr(ostream& os){os<<endl;}
template<class T,class... Args>
void dmpr(ostream&os,const T&t,const Args&... args){
	os<<t<<" ~ ";
	dmpr(os,args...);
}
#define shows(...) cerr << "LINE" << __LINE__ << " : ";dmpr(cerr,##__VA_ARGS__)
#define dump(x) cerr << "LINE" << __LINE__ << " : " << #x << " = {";  \
	for(auto v: x) cerr << v << ","; cerr << "}" << endl;
#else
#define show(x) void(0)
#define dump(x) void(0)
#define shows(...) void(0)
#endif

template<class D> D divFloor(D a, D b){
	return a / b - (((a ^ b) < 0 && a % b != 0) ? 1 : 0);
}
template<class D> D divCeil(D a, D b) {
	return a / b + (((a ^ b) > 0 && a % b != 0) ? 1 : 0);
}

namespace SlideMax{
	using D = ll;
	const int X = 1000000;
	D a[X];
	int idx[X];
	int L,R,I,num_del;
	void clear(){
		L = R = I = num_del = 0;
	}
	void add(D v){
		while(L<R && v>a[R-1]) R--;			// D-D comparison v<a[R-1]
		a[R] = v;
		idx[R] = I;
		R++,I++;
	}
	void del(){
		if(L<R && idx[L] == num_del) L++;
		num_del++;
	}
	D getmax(){
		assert(L<R);
		return a[L];
	}
	int getargmax(){
		assert(L<R);
		return idx[L];
	}
}
const ll inf = TEN(18);
struct Item{
	// 重さw, 価値p の物体が n個
	// n個全部使い切ると下の頂点を使えるようになる
	int w; ll p; int n;
	friend ostream& operator<<(ostream &o,const Item& x){ return o<<"("<<x.w<<","<<x.p<<" * " << x.n << ")";}
};
void slide(V<ll>& f, int w, ll p, int n){
	int W = si(f)-1;
	rep(r,w){
		SlideMax::clear();
		if(r > W) break;
		for(int i=0,x=r;x<=W;i++,x+=w){
			SlideMax::add(f[x]-i*p);
			f[x] = SlideMax::getmax() + i*p;
			if(f[x] < -inf/2) f[x] = -inf;
			if(i >= n) SlideMax::del();
		}
	}
}
V<ll> treeKnapsack(VV<int> G, V<Item> items, int W){
	assert(si(G) == si(items));
	auto rec = [&](auto& self, int v, int p, V<ll> dp_init) -> V<ll>{
		V<ll> dp(W+1,-inf);
		auto& f = items[v];
		for(ll i=0; i+ll(f.w)*f.n<=W; i++){
			if(dp_init[i] != -inf) dp[i+f.w*f.n] = dp_init[i] + f.p * f.n;
		}
		for(int u: G[v]) if(u != p){
			dp = self(self,u,v,dp);
		}
		slide(dp_init,f.w,f.p,f.n);	// <= n
		rep(i,W+1) chmax(dp[i], dp_init[i]);
		return dp;
	};
	V<ll> dp(W+1,-inf); dp[0] = 0;
	return rec(rec,0,-1,dp);
}

int main(){
	cin.tie(0);
	ios::sync_with_stdio(false);		//DON'T USE scanf/printf/puts !!
	cout << fixed << setprecision(20);

	while(true){
		int N,W; cin >> N >> W;
		if(N == 0) break;
		V<int> h(N); rep(i,N) cin >> h[i];
		V<ll> p(N); rep(i,N) cin >> p[i];
		VV<int> child(N);
		rep1(i,N-1){
			int x; cin >> x; x--;
			child[x].pb(i);
		}
		V<int> need(N);
		rep1(i,N-1) cin >> need[i];

		VV<int> G;
		V<Item> items;
		int I = 0;
		V<int> par(N,-1);
		V<int> base(N);
		rep(v,N){
			sort(all(child[v]),[&](int l,int r){return need[l]<need[r];});
			int K = si(child[v]);
			rep(k,K+1){
				int id = I++;
				int n = (k == K ? h[v] : need[child[v][k]]) - (k == 0 ? 0 : need[child[v][k-1]]);
				items.pb({1,p[v],n});
				G.pb({});
				if(k != K){
					par[child[v][k]] = id;
				}
				if(k != 0){
					G[id-1].pb(id);
				}
				if(k == 0){
					base[v] = id;
				}
			}
		}
		rep1(v,N-1) G[par[v]].pb(base[v]);
		auto f = treeKnapsack(G,items,W);
		cout << *max_element(all(f)) << endl;
	}
}
accuracy: 1
time_ms: 7840
memory_kb: 164676
final_rank: 20

code_snippet: #include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll> P;

#define fi first
#define se second
#define repl(i,a,b) for(ll i=(ll)(a);i<(ll)(b);i++)
#define rep(i,n) repl(i,0,n)
#define all(x) (x).begin(),(x).end()
#define dbg(x) cout<<#x"="<<x<<endl
#define mmax(x,y) (x>y?x:y)
#define mmin(x,y) (x<y?x:y)
#define maxch(x,y) x=mmax(x,y)
#define minch(x,y) x=mmin(x,y)
#define uni(x) x.erase(unique(all(x)),x.end())
#define exist(x,y) (find(all(x),y)!=x.end())
#define bcnt __builtin_popcountll

#define INF 1e16
#define mod 1000000007

vector<int> h,l,s;
vector<int> g[300];
vector<ll> dp[301];
vector<ll> update;

void knapsackDP(ll v,ll lim,ll clim,const vector<ll>& pre,vector<ll>& ret){
    deque<ll> deq,deqv;
    rep(i,clim+1){
        ll val=pre[i]-i*v;
        while(deq.size()&&deqv.back()<=val){
            deq.pop_back(); deqv.pop_back();
        }
        deq.push_back(i);
        deqv.push_back(val);
        ret[i]=deqv.front()+i*v;
        if(deq.front()==i-lim){
            deq.pop_front();
            deqv.pop_front();
        }
    }
}

void dfs(int v,int clim,vector<ll>& ret){
    knapsackDP(s[v],h[v],clim,ret,dp[v]);
    for(int nv : g[v]){
        dfs(nv,clim-l[nv],ret);
        ret=dp[nv];
        knapsackDP(s[v],h[v]-l[nv],clim,ret,update);
        rep(i,clim+1-l[nv])maxch(dp[v][i+l[nv]],update[i]+(ll)l[nv]*s[v]);
    }
}

int main(){
    while(1){
        int N,C;
        scanf("%d%d",&N,&C);
        if(N==0)break;
        rep(i,N){
            g[i].clear();
            dp[i].resize(C+1,0);
        }
        h.resize(N,0); l.resize(N,0); s.resize(N,0); update.resize(C+1,0);
        rep(i,N)scanf("%d",&h[i]);
        rep(i,N)scanf("%d",&s[i]);
        rep(i,N-1){
            int p;
            scanf("%d",&p); p--;
            g[p].push_back(i+1);
        }
        rep(i,N-1)scanf("%d",&l[i+1]);
        rep(i,N){
            sort(all(g[i]),[&](const int& a,const int& b){ return l[a] < l[b]; });
        }
        vector<ll> ret(C+1,0);
        dfs(0,C,ret);
        cout<<dp[0][C]<<endl;
    }

    return 0;
}
accuracy: 1
time_ms: 5670
memory_kb: 84644
final_rank: 11

code_snippet: #include<iostream>
#include<string>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<algorithm>
#include<functional>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cassert>
#include<ctime>
using namespace std;

#define mind(a,b) (a>b?b:a)
#define maxd(a,b) (a>b?a:b)
#define absd(x) (x<0?-(x):x)
#define pow2(x) ((x)*(x))
#define rep(i,n) for(int i=0; i<n; ++i)
#define repr(i,n) for(int i=n-1; i>=0; --i)
#define repl(i,s,n) for(int i=s; i<=n; ++i)
#define replr(i,s,n) for(int i=n; i>=s; --i)
#define repf(i,s,n,j) for(int i=s; i<=n; i+=j)
#define repe(e,obj) for(auto e : obj)

#define SP << " " <<
#define COL << " : " <<
#define COM << ", " <<
#define ARR << " -> " <<
#define PNT(STR) cout << STR << endl
#define POS(X,Y) "(" << X << ", " << Y << ")"
#define DEB(A) " (" << #A << ") " << A
#define DEBREP(i,n,val) for(int i=0; i<n; ++i) cout << val << " "; cout << endl
#define ALL(V) (V).begin(), (V).end()
#define INF 1000000007
#define INFLL 1000000000000000007LL
#define EPS 1e-9

typedef unsigned int uint;
typedef unsigned long ulong;
typedef unsigned long long ull;
typedef long long ll;
typedef long double ld;
#define P_TYPE int
typedef pair<P_TYPE, P_TYPE> P;
typedef pair<P, P_TYPE> PI;
typedef pair<P_TYPE, P> IP;
typedef pair<P, P> PP;
typedef priority_queue<P, vector<P>, greater<P> > pvqueue;

#define N 102
#define K 100008

ll dp[N][K];
ll ss[N];
int hs[N], ls[N];
vector<int> g[N];
ll ps[K], qs[K];

int n, k;

void calc(int v, int w, int mi, int ma) {
  ll *p0 = dp[v], *p1 = dp[w];
  int d = (ma - mi);
  ll sv = ss[v];
  int s = 0, t = 0;
  rep(i, k-mi+1) {
    ll v0 = p0[i] + sv*(mi - i);
    while(s < t && qs[t-1] <= v0) --t;
    ps[t] = i; qs[t] = v0;
    ++t;

    p1[i+mi] = max(p1[i+mi], qs[s] + sv*i);

    if(s < t && ps[s] <= i-d) ++s;
  }
}

stack<int> st;
void dfs(int v) {
  while(!st.empty()) {
    int u = st.top(); st.pop();
    calc(u, v, 0, hs[u]);
  }
  sort(ALL(g[v]), [](int i, int j)->bool{ return ls[i] > ls[j];});
  for(int w : g[v]) {
    calc(v, w, ls[w], hs[v]);
    dfs(w);
  }
  st.push(v);
}

int main() {
  while(cin >> n >> k && n && k) {
    rep(i, n) cin >> hs[i];
    rep(i, n) cin >> ss[i];
    rep(i, n) g[i].clear();
    rep(i, n-1) {
      int j; cin >> j;
      g[j-1].push_back(i+1);
    }
    rep(i, n-1) cin >> ls[i+1];
    rep(i, n+1) rep(j, k+1) dp[i][j] = -INFLL;
    dp[0][0] = 0;

    dfs(0);
    while(!st.empty()) {
      int u = st.top(); st.pop();
      calc(u, n, 0, hs[u]);
    }
    ll ans = 0;
    rep(i, k+1) ans = max(ans, dp[n][i]);
    cout << ans << endl;
  }
  return 0;
}
accuracy: 1
time_ms: 3410
memory_kb: 83608
final_rank: 3

code_snippet: #pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
using namespace std;

#define int long long

#define rep(i, n) for (int i = 0; i < (n); i++)
#define loop(i, a, b) for (int i = (a); i < (b); i++)
#define pb push_back
#define eb emplace_back
#define all(v) (v).begin(), (v).end()
#define fi first
#define se second

using vint = vector<int>;
using pint = pair<int, int>;
using vpint = vector<pint>;

template <typename A, typename B>
inline void chmin(A& a, B b) {
    if (a > b) a = b;
}
template <typename A, typename B>
inline void chmax(A& a, B b) {
    if (a < b) a = b;
}

template <class A, class B>
ostream& operator<<(ostream& ost, const pair<A, B>& p) {
    ost << "{" << p.first << "," << p.second << "}";
    return ost;
}

template <class T>
ostream& operator<<(ostream& ost, const vector<T>& v) {
    ost << "{";
    for (int i = 0; i < v.size(); i++) {
        if (i) ost << ",";
        ost << v[i];
    }
    ost << "}";
    return ost;
}

inline int topbit(unsigned long long x) {
    return x ? 63 - __builtin_clzll(x) : -1;
}

inline int popcount(unsigned long long x) {
    return __builtin_popcountll(x);
}

inline int parity(unsigned long long x) {
    return __builtin_parity(x);
}

template <typename F>
class
    FixPoint : private F {
   public:
    explicit constexpr FixPoint(F&& f) noexcept
        : F{std::forward<F>(f)} {}

    template <typename... Args>
    constexpr decltype(auto)
    operator()(Args&&... args) const {
        return F::operator()(*this, std::forward<Args>(args)...);
    }
};

namespace {
template <typename F>
inline constexpr decltype(auto)
makeFixPoint(F&& f) noexcept {
    return FixPoint<F>{std::forward<F>(f)};
}
}  // namespace

const int INF = 1001001001001001001;

signed main() {
    auto solve = [](int N, int K) {
        vector<int> H(N), S(N);
        rep(i, N) scanf("%lld", &H[i]);
        rep(i, N) scanf("%lld", &S[i]);

        vector<int> P(N), L(N);
        loop(i, 1, N) scanf("%lld", &P[i]), P[i]--;
        loop(i, 1, N) scanf("%lld", &L[i]);

        vector<vpint> G(N);
        loop(i, 1, N) G[P[i]].eb(L[i], i);

        /*
            Xを初期配列として，vのitemをl個以上使う場合のナップサックをやる
        */
        auto calc = [&](const vint& X, int l, int v) {
            vint Z(K + 1, -INF);
            deque<pint> deq;
            for (int i = l; i <= K; i++) {
                int tmp = X[i - l] - (i - l) * S[v];
                while (deq.size() && deq.back().fi <= tmp) deq.pop_back();
                deq.emplace_back(tmp, i - l);
                Z[i] = deq.front().fi + i * S[v];
                if (deq.front().se == i - H[v]) deq.pop_front();
            }
            return Z;
        };

        auto dfs = makeFixPoint([&](auto dfs, int v, int p, vint& X) -> void {
            sort(all(G[v]));
            reverse(all(G[v]));
            vint Y(K + 1, -INF);

            for (auto& e : G[v]) {
                auto [l, u] = e;
                auto Z = calc(X, l, v);
                rep(i, K + 1) chmax(Y[i], Z[i]);
                dfs(u, v, Y);
            }
            X = calc(X, 0, v);
            rep(i, K + 1) chmax(X[i], Y[i]);
        });

        vint X(K + 1, -INF);
        X[0] = 0;
        dfs(0, -1, X);
        printf("%lld\n", *max_element(all(X)));
    };

    int N, K;
    while (scanf("%lld%lld", &N, &K), N || K) solve(N, K);
    return 0;
}
accuracy: 1
time_ms: 7990
memory_kb: 161944
final_rank: 19

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 99999999999999999
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;



#define SIZE 100005

struct Info{

	bool operator<(const struct Info &arg) const{

		return pre_need_level < arg.pre_need_level;
	}

	int index;
	ll limit,value,pre_node,pre_need_level;
};

struct Data{

	void set(ll arg_index,ll arg_diff){
		index = arg_index;
		diff = arg_diff;
	}
	ll index,diff;
};


ll V,K;
ll dp[105][SIZE];
ll first[SIZE],work[SIZE];
Info info[SIZE];
Data DEQ[SIZE];
vector<Info> G[SIZE];


void calc_dp(ll *base,ll *result,ll budget,ll value, ll limit){

	ll head = 0,tail = 0;

	for(int i = 0; i <= budget; i++){

		ll diff = base[i]-i*value;

		while(head < tail && DEQ[tail-1].diff <= diff)tail--;

		DEQ[tail++].set(i,diff);

		result[i] = DEQ[head].diff+i*value;

		if(i-DEQ[head].index == limit)head++;
	}
}


void recursive(int node_id,ll budget,ll *table){

	calc_dp(table,dp[node_id],budget,info[node_id].value,info[node_id].limit);

	for(int i = 0; i < G[node_id].size(); i++){

		int child = G[node_id][i].index;

		if(info[child].pre_need_level > budget)continue;

		recursive(child,budget-info[child].pre_need_level,table);

		table = dp[child];

		calc_dp(dp[child],work,budget,info[node_id].value,info[node_id].limit-info[child].pre_need_level);

		ll add = info[child].pre_need_level*info[node_id].value;

		for(int k = 0; k+info[child].pre_need_level <= budget; k++){

			dp[node_id][k+info[child].pre_need_level] = max(dp[node_id][k+info[child].pre_need_level],work[k]+add);
		}
	}
}

void func(){

	for(int i = 0; i < V; i++){

		scanf("%lld",&info[i].limit);
		info[i].index = i;
	}
	for(int i = 0; i < V; i++){

		scanf("%lld",&info[i].value);
	}
	for(int i = 1; i < V; i++){

		scanf("%lld",&info[i].pre_node);
		info[i].pre_node--;
	}
	for(int i = 1; i < V; i++){

		scanf("%lld",&info[i].pre_need_level);
		G[info[i].pre_node].push_back(info[i]);
	}

	for(int i = 0; i < V; i++){
		if(G[i].size() == 0)continue;

		sort(G[i].begin(),G[i].end());
	}

	for(int i = 0; i < V; i++){
		for(int k = 0; k <= K; k++){
			dp[i][k] = 0;
		}
	}

	for(int i = 0; i <= K; i++){

		first[i] = 0;
	}

	recursive(0,K,first);

	printf("%lld\n", dp[0][K]);
}

int main(){

	while(true){

		scanf("%lld %lld",&V,&K);
		if(V == 0 && K == 0)break;

		for(int i = 0; i < V; i++)G[i].clear();

		func();
	}

	return 0;
}
accuracy: 1
time_ms: 5020
memory_kb: 86868
final_rank: 9