#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define ull long long
using pii = pair<int, int>;
using pll = pair<long long, long long>;
#define all(x) x.begin(), x.end()
#define fi first
#define se second
#ifdef MARCO
#define infof(str,...) do{ fprintf(stderr, str"\n", ##__VA_ARGS__);} while(0)
#define infor(str,...) do{ fprintf(stderr, str, #__VA_ARGS__);} while(0)
#else
#define infof(str,...)
#define infor(str,...)
#endif
vector<vector<int>> G;
int N;
vector<int> W;
vector<int> tin, tout;
ll leafw, leafn;
void gett(int v) {
static int tt = 0;
tin[v] = tt++;
for(auto &u: G[v]) {
gett(u);
}
tout[v] = tt;
}
vector<ll> p, sfx;
int dfs(int v) {
if(G[v].empty()) return 1;
int k = 0;
for(auto &u: G[v]) {
k += dfs(u);
if(W[v] == 0) {
p.push_back(k);
k = 0;
}
}
if(W[v] == 0) return 1;
else return k;
}
vector<ll> t;
void update(int v, int l, int r, int q, ll x) {
if(r-l == 1) {
t[v] = x;
return;
}
int m = (l+r)/2;
if(q < m) update(v*2, l, m, q, x);
else update(v*2+1, m, r, q, x);
t[v] = t[v*2] + t[v*2+1];
}
ll sum(int v, int l, int r, int ql, int qr) {
if(qr <= l || r <= ql) return 0;
if(ql <= l && r <= qr) return t[v];
int m = (l+r)/2;
return sum(v*2, l, m, ql, qr) + sum(v*2+1, m, r, ql, qr);
}
vector<ll> ans1;
struct dt1{
vector<ll> x, d;
dt1(int k = 1e6+3) {
x.resize(k*4);
d.resize(k*4);
ans1.resize(k);
}
void push(int v, int l, int m, int r) {
x[v*2+1] += x[v];
d[v*2+1] += d[v];
x[v*2] += x[v] + d[v]*(m-r);
d[v*2] += d[v];
x[v] = 0;
d[v] = 0;
}
void add(int v, int l, int r, int ql, int qr, ll k) {
if(qr <= l || r <= ql) return;
if(ql <= l && r <= qr) {
x[v] += k*(qr-r+1);
d[v] += k;
return;
}
int m = (l+r)/2;
add(v*2, l, m, ql, qr, k);
add(v*2+1, m, r, ql, qr, k);
}
void add(int ql, int qr, ll k) {
add(1, 0, 1e6+3, ql, qr, k);
}
void trans(int v, int l, int r) {
if(r-l == 1) {
ans1[l] = x[v];
return;
}
int m = (l+r)/2;
push(v, l, m, r);
trans(v*2, l, m);
trans(v*2+1, m, r);
}
void trans() {
trans(1, 0, 1e6+3);
}
};
struct dt2{
vector<int> t, lazy;
dt2() {
t.resize(N*4, -1);
lazy.resize(N*4, -1);
}
void update(int v, int l, int r, int ql, int qr, int p) {
if(qr <= l || r <= ql) return;
if(ql <= l && r <= qr) {
t[v] = p;
lazy[v] = p;
return;
}
int m = (l+r)/2;
if(lazy[v] != -1) {
for(int u = v*2; u < v*2+2; u++) {
lazy[u] = t[u] = lazy[v];
}
lazy[v] = -1;
}
update(v*2, l, m, ql, qr, p);
update(v*2+1, l, r, ql, qr, p);
}
int get(int v, int l, int r, int q) {
if(r-l == 1) return t[v];
int m = (l+r)/2;
if(lazy[v] != -1) {
for(int u = v*2; u < v*2+2; u++) {
lazy[u] = t[u] = lazy[v];
}
lazy[v] = -1;
}
if(q < m) return get(v*2, l, m, q);
return get(v*2+1, m, r, q);
}
int get(int q) {
return get(1, 0, N, q);
}
};
void init(std::vector<int> P, std::vector<int> W) {
N = P.size();
G.resize(N);
t.resize(N*4);
for(int i=1; i<N; i++) {
G[P[i]].emplace_back(i);
}
tin = tout = vector<int>(N);
gett(0);
vector<int> V;
for(int i=0; i<N; i++) {
if(G[i].empty()) {
leafw+=W[i];
leafn++;
update(1, 0, N, tin[i], 1);
}
else V.push_back(i);
}
sort(all(V), [&](int &i, int &j){return W[i] < W[j];});
dt1 sgans;
dt2 hh;
int solved = leafn;
for(auto &v: V) {
int p = hh.get(tin[v]);
int sub = sum(1, 0, N, tin[v], tout[v]);
if(p == -1) {
// move solved by sub-1!
sgans.add(0, solved, W[v]);
sgans.add(0, solved-sub+1, -W[v]);
solved -= sub-1;
hh.update(1, 0, N, tin[v], tout[v], v);
update(1, 0, N, tin[v], -sub+1);
}
else {
// recover p by stealing the size of sub
sgans.add(0, sub, W[v]-W[p]);
hh.update(1, 0, N, tin[v], tout[v], v);
update(1, 0, N, tin[v], -sub+1);
update(1, 0, N, tin[p], +sub-1);
}
}
sgans.trans();
::W.swap(W);
}
long long query(int L, int R) {
return ans1[R] + leafw;
}
#ifdef MARCO
int main() {
int N;
assert(1 == scanf("%d", &N));
std::vector<int> P(N);
P[0] = -1;
for (int i = 1; i < N; i++)
assert(1 == scanf("%d", &P[i]));
std::vector<int> W(N);
for (int i = 0; i < N; i++)
assert(1 == scanf("%d", &W[i]));
int Q;
assert(1 == scanf("%d", &Q));
std::vector<int> L(Q), R(Q);
for (int j = 0; j < Q; j++)
assert(2 == scanf("%d%d", &L[j], &R[j]));
fclose(stdin);
init(P, W);
std::vector<long long> A(Q);
for (int j = 0; j < Q; j++)
A[j] = query(L[j], R[j]);
for (int j = 0; j < Q; j++)
printf("%lld\n", A[j]);
fclose(stdout);
return 0;
}
#endif