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

#define int long long
#define all(x) x.begin(), x.end()
const int N = 1e5 + 5;
const int INF = 1e18;

struct SegTree {
    struct Node{
        int val, zero, mn;
    };
    int n;
    vector<Node> tree;
    vector<int> lazy;
    #define LEFT node * 2 + 1
    #define RIGHT node * 2 + 2

    SegTree(vector<int> &arr) {
        this->n = arr.size();
        tree.resize(4 * n);
        lazy.assign(4 * n, 0); // 1
        build(0, 0, n - 1, arr);
    }

    Node merge(Node a, Node b) {
        Node r;
        r.val = a.val + b.val;
        r.zero = a.zero + b.zero;
        r.mn = min(a.mn, b.mn);
        return r;
    }

    void build(int node, int start, int end, vector<int>& arr) {
        if (start == end) {
            tree[node] = {arr[start], arr[start] == 0, arr[start]};
            return;
        }
        int mid = (start + end) / 2;
        build(LEFT, start, mid, arr);
        build(RIGHT, mid + 1, end, arr);
        tree[node] = merge(tree[LEFT], tree[RIGHT]);
    }

    void apply(int node, int start, int end, int val) {
        tree[node].mn -= val;
        tree[node].val -= (start - end + 1) * val; // 3
        lazy[node] += val;
    }

    void push(int node, int start, int end) {
        if (!lazy[node]) return;
        if (start == end) {
            lazy[node] = 0;
            return;
        }
        int mid = (start + end) / 2;
        apply(LEFT, start, mid, lazy[node]);
        apply(RIGHT, mid + 1, end, lazy[node]);
        lazy[node] = 0;
    }

    void update(int node, int start, int end, int L, int R, int val) {
        if (R < start || end < L || !tree[node].val) return; // 4
        if (L <= start && end <= R && tree[node].mn > val){ // 2
            apply(node, start, end, val);
            return;
        }
        if(start == end){
            tree[node].val = max(0ll, tree[node].val - val);
            tree[node].zero = tree[node].val == 0;
            tree[node].mn = tree[node].val;
            return;
        }
        push(node, start, end);
        int mid = (start + end) / 2;
        update(LEFT, start, mid, L, R, val);
        update(RIGHT, mid + 1, end, L, R, val);
        tree[node] = merge(tree[LEFT], tree[RIGHT]);
    }

    Node query(int node, int start, int end, int L, int R) {
        if (R < start || end < L) return {0, 0, INF};
        if (L <= start && end <= R) return tree[node];
        push(node, start, end);
        int mid = (start + end) / 2;
        return merge(query(LEFT, start, mid, L, R), query(RIGHT, mid + 1, end, L, R));
    }

    // 0-indexed
    void update(int L, int R, int val){
        if(L > R) return;
        update(0, 0, n - 1, L, R, val);
    }
    Node query(int L, int R) {
        if(L > R) return {0, 0, INF};
        return query(0, 0, n - 1, L, R);
    }
};

vector<int> flat;
int a[N], in[N], out[N];
vector<int> g[N];
int timer = 0;

void dfs(int node, int par){
    in[node] = timer++;
    flat.push_back(a[node]);
    for(auto next : g[node]){
        if(next == par) continue;
        dfs(next, node);
    }
    out[node] = timer - 1;
}


void solve() {
    int n;
    cin >> n;
    for(int i = 1; i <= n; i++){
        int h, p;
        cin >> h >> p;
        a[i] = h;
        g[i].push_back(p);
        g[p].push_back(i);
    }
    // for(int i = 0; i <= n; i++) cout << a[i] << ' ';
    // cout << '\n';
    dfs(0, -1);

    int q;
    cin >> q;
    SegTree st(flat);
    while(q--){
        int t, v, x;
        cin >> t >> v;
        if(t == 1){
            cin >> x;
            st.update(in[v] + 1, out[v], x);
        }else{
            cout << (out[v] - in[v]) - st.query(in[v] + 1, out[v]).zero << '\n';
        }
    }
}

signed main() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  int tc = 1;
  // cin >> tc;
  for (int i = 0; i < tc; i += 1) {
    solve();
  }
  return 0;
}
