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

#define ll long long

const int N = 3e5+15;
const int M = 20;

int a[N],c[N];

int anc[N][M], depth[N];

void add_child(int p,int ch) {
  anc[ch][0] = p;

  depth[ch] = depth[p] + 1;

  for(int i=1;i<M;++i) {
    anc[ch][i] = anc[anc[ch][i-1]][i-1];
  }
}

int jump(int node,int x) {
  for(int i=0;i<M;++i) {
    if(x&(1<<i)) {
      node = anc[node][i];
    }
  }
  return node;
}

void solve2() {
  int q;
  scanf("%d%d%d", &q,&a[0],&c[0]);

  for(int iter=1;iter<=q;++iter) {
    int type;
    scanf("%d", &type);

    if(type==1) {
      int p;
      scanf("%d%d%d", &p,&a[iter],&c[iter]);
      add_child(p,iter);
    } else {
      int v,w;
      scanf("%d%d", &v,&w);

      ll cost = 0;
      int wei = 0;

      int node = v,cur = 0;

      for(int i=M-1;i>=0;--i) {
        int ncur = cur + (1<<i),
        nnode = anc[node][i];
        if(ncur<= depth[v] &&  a[nnode]>0) {
          node = nnode, cur = ncur;
        }
      }

      while(w>0) {
        if(a[node]==0) {
          if(node==v) break;
          --cur;
          int g = jump(v,cur);
          assert(anc[g][0]==node);
          node = g;
          continue;
        }
        int need = min(a[node],w);
        w -= need;
        a[node] -= need;
        wei += need;
        cost += (ll)need*c[node];
      }

      printf("%d %lld\n", wei,cost);
    }
    fflush(stdout);
  }
}

void solve() {
    // int t;
    // scanf("%d",&t);
    // while(t--)
    solve2();
}

inline bool exists_test0 (const std::string& name);
inline bool exists_test1 (const std::string& name);
int main() {
#ifdef LOCAL
  string file_name = "input.txt";
  assert(exists_test0(file_name));
  assert(exists_test1(file_name));
  freopen("input.txt","r",stdin);
#endif
  solve();
  return 0;
}

/*
0. Enough array size? Enough array size? Integer overflow?

1. Think TWICE, Code ONCE!
Are there any counterexamples to your algo?

2. Be careful about the BOUNDARIES!
N=1? P=1? Something about 0?

3. Do not make STUPID MISTAKES!
Time complexity? Memory usage? Precision error?

4. Be careful to use wrong variable.
*/
inline bool exists_test0 (const std::string& name) {
    ifstream f(name.c_str());
    return f.good();
}

inline bool exists_test1 (const std::string& name) {
    if (FILE *file = fopen(name.c_str(), "r")) {
        fclose(file);
        return true;
    } else {
        return false;
    }
}
