#include <bits/stdc++.h>

using namespace std;

#define lsb(x) x & -x
using ll = long long;

struct Fenwick
{
    vector<ll> aib;
    int n;

    Fenwick(int N)
    {
        n = N;
        aib.assign(n + 2, 0);
    }
    void update(int pos, int val)
    {
         //cerr <<  " + " << val << '\n';
        while(pos < aib.size())
            aib[pos] += val, pos += lsb(pos);
    }
    ll query(int pos)
    {
        ll ans = 0;
        while(pos)
            ans += aib[pos], pos -= lsb(pos);
        return ans;
    }
};

vector<int> vec[800005];
struct mazan
{
    int t, u;
    int voyage;
};
vector<mazan> upd;
int ti[800005], to[800005], times = 0, dist;
int w[800005];
int buniku[800005];
vector<int> stramosi;

void dfs(int nod, int papa)
{
    stramosi.push_back(nod);
    ti[nod] = ++ times;
    if(stramosi.size() > dist + 1)
        buniku[nod] = stramosi[stramosi.size() - dist - 2];
    for(auto i : vec[nod])
        if(i != papa)
            dfs(i, nod);
    to[nod] = times;
    stramosi.pop_back();
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n, q, ninit;
    cin >> n >> q >> dist;
    ninit = n;
    for(int i = 1; i <= n; i ++)
        cin >> w[i];
    for(int i = 2, u; i <= n; i ++)
    {
        cin >> u;
        vec[u].push_back(i);
    }
    for(int i = 0; i < q; i ++)
    {
        int t, u, voyage = 0;
        cin >> t;
        if(t == 1)
        {
            cin >> w[++ n] >> u;
            vec[u].push_back(n);
            u = n;
        }
        if(t == 2) {
            cin >> u >> voyage;
        }
        if(t == 3) {
            cin >> u;
        }
        if(t == 4) {
            cin >> u;   
        }
        upd.push_back({t, u, voyage});
    }
    Fenwick ds(2 * n);
    dfs(1, 0);
    for(int i = 1; i <= ninit; i ++)
    {
        ds.update(ti[i], w[i]);
        if(buniku[i])
            ds.update(ti[buniku[i]], -w[i]);
    }
    for(auto i : upd)
    {
        if(i.t == 4) {//query 
        //cerr << to[i.u] << ' ' << ti[i.u] << ' ' << ds.query(to[i.u]) << ' ' << ds.query(ti[i.u] - 1) << '\n';
            cout << ds.query(to[i.u]) - ds.query(ti[i.u] - 1) << '\n';
         }
        else if(i.t == 1) //add node
        {
            ds.update(ti[i.u], w[i.u]);
            if(buniku[i.u])
                ds.update(ti[buniku[i.u]], -w[i.u]);
        }
        else if(i.t == 3) //remove node
        {
            ds.update(ti[i.u], -w[i.u]);
            if(buniku[i.u])
                ds.update(ti[buniku[i.u]], w[i.u]);
        }
        else if(i.t == 2) {
            ds.update(ti[i.u], -w[i.u]);
            if(buniku[i.u])
                ds.update(ti[buniku[i.u]], w[i.u]);
                
                
            ds.update(ti[i.u], i.voyage);
            if(buniku[i.u])
                ds.update(ti[buniku[i.u]], -i.voyage);
            w[i.u] = i.voyage;
        }
    }
}