/*
ROAD TO TST
*/
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define fi first
#define se second
#define pii pair<int, int>
#define el "\n"
#define pb push_back
#define all(v) v.begin(), v.end()
#define rep(i, x, y) for(int i = x, _y = y; i <= _y; i++)
#define rev(i, x, y) for(int i = x, _y = y; i >= _y; i--)
void file() {
#define name "test"
if(fopen(name".inp", "r")) {freopen(name".inp", "r", stdin);freopen(name".out", "w", stdout);}
else {
#undef name
#define name "C:\\Users\\hminh\\Desktop\\2026\\AIO\\test"
if(fopen(name".inp", "r")) {freopen(name".inp", "r", stdin);freopen(name".out", "w", stdout);}
}
}
const int nmax = 2e6 + 7;
int n, p[nmax], k[nmax], q, h[nmax], st[nmax], en[nmax], timedfs = 0;
vector<int> g[nmax];
void dfs(int u) {
st[u] = ++timedfs;
for(int v : g[u]) {
h[v] = h[u] + 1;
dfs(v);
}
en[u] = timedfs;
}
struct segtree {
struct node {
int sum, l, r;
node(int _sum = 0, int _l = 0, int _r = 0) {
sum = _sum, l = _l, r = _r;
}
} it[40 * nmax];
int root[nmax], cur, cnt[nmax];
int new_node() {
++cur;
it[cur] = node();
return cur;
}
void update(int& id, int l, int r, int u, int val) {
if(!id) id = new_node();
if(l == r) {
it[id].sum += val;
return;
}
int mid = (l + r) >> 1;
if(u <= mid) update(it[id].l, l, mid, u, val);
else update(it[id].r, mid + 1, r, u, val);
it[id].sum = it[it[id].l].sum + it[it[id].r].sum;
}
int get(int id, int l, int r, int u, int v) {
if(l > v || u > r || !id) return 0;
if(l >= u && v >= r) return it[id].sum;
int mid = (l + r) >> 1;
return get(it[id].l, l, mid, u, v) + get(it[id].r, mid + 1, r, u, v);
}
int merge(int a, int b, int l, int r) {
if(l == r) {
if(a == 0) swap(a, b);
it[a].sum += it[b].sum;
return a;
}
if(!a) return b;
if(!b) return a;
int mid = (l + r) >> 1;
it[a].l = merge(it[a].l, it[b].l, l, mid);
it[a].r = merge(it[a].r, it[b].r, mid + 1, r);
it[a].sum = it[it[a].l].sum + it[it[a].r].sum;
return a;
}
} tr;
int main()
{
file();
ios_base::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
cin >> n;
rep(i, 2, n) {
cin >> p[i];
g[p[i]].pb(i);
}
rep(i, 1, n) cin >> k[i];
dfs(1);
rep(i, 1, n) {
tr.update(tr.root[h[i]], 1, n, st[i], k[i]);
tr.cnt[h[i]]++;
}
cin >> q;
while(q -- ) {
int t;
cin >> t;
if(t == 1) {
int x, y;
cin >> x >> y;
// cout << tr.it[7].l << ' ' << tr.it[7].r << ' ' << tr.it[7].sum << el;
if(tr.cnt[x] > tr.cnt[y]) swap(tr.root[x], tr.root[y]);
// cout << "MERGE" << ' ' << tr.root[x] << ' ' << tr.root[y] << el;
tr.root[y] = tr.merge(tr.root[y], tr.root[x], 1, n);
tr.cnt[y] += tr.cnt[x];
tr.root[x] = 0;
tr.cnt[x] = 0;
}
else if(t == 2) {
int u, v;
cin >> u >> v;
tr.update(tr.root[h[u]], 1, n, st[u], v);
// cout << "UPDATE" << ' ' << u << ' ' << tr.root[h[u]] << el;
tr.cnt[h[u]]++;
}
else {
int u;
cin >> u;
cout << tr.get(tr.root[h[u]], 1, n, st[u], en[u]) << el;
}
}
return 0;
}