#include <bits/stdc++.h>
using namespace std;
long long int szb[30];
int szx[100100 << 2];
int szq[100100];
long long int numz;
int numd;
int numq;
int totb;
int mo;
struct noded {
  long long int x;
  int d;
};
noded szd[100100];
struct nodem {
  bool inq;
  long long int dist;
};
nodem szm[10100];
void setx(int x, int l, int r, int t, int d) {
  int mid;
  if (l == r) {
    szx[x] = d;
    return;
  }
  mid = (((l) + (r)) >> 1);
  if (t <= mid)
    setx(((x) << 1), l, mid, t, d);
  else
    setx((((x) << 1) | 1), mid + 1, r, t, d);
  szx[x] = max(szx[((x) << 1)], szx[(((x) << 1) | 1)]);
  return;
}
int getx(int x, int l, int r) {
  int mid;
  if (l == r) return l;
  mid = (((l) + (r)) >> 1);
  if (szx[((x) << 1)] >= szx[(((x) << 1) | 1)])
    return getx(((x) << 1), l, mid);
  else
    return getx((((x) << 1) | 1), mid + 1, r);
}
void do1() {
  long long int len;
  int head;
  int tail;
  int now;
  int to;
  int f1;
  scanf("%I64d", &szb[++totb]);
  for (f1 = 1; f1 < mo; f1++) szm[f1].dist = ((1LL << 60) - 1);
  for (head = tail = 1, szq[1] = 0, szm[0].inq = true; head <= tail;) {
    now = szq[((head++) % mo)];
    szm[now].inq = false;
    for (f1 = 1; f1 <= totb; f1++) {
      to = (now + szb[f1]) % mo;
      len = (now + szb[f1]) / mo;
      if (szm[to].dist > szm[now].dist + len) {
        szm[to].dist = szm[now].dist + len;
        if (szm[to].inq == false) {
          szm[to].inq = true;
          szq[((++tail) % mo)] = to;
        }
      }
    }
  }
  for (f1 = 1; f1 <= numd; f1++)
    if (szd[f1].x / mo >= szm[szd[f1].x % mo].dist)
      setx(1, 1, numd, f1, szd[f1].d);
    else
      setx(1, 1, numd, f1, 0);
  return;
}
void do2() {
  int wei;
  int d;
  scanf("%d%d", &wei, &d);
  szd[wei].d -= d;
  if (szd[wei].x / mo >= szm[szd[wei].x % mo].dist)
    setx(1, 1, numd, wei, szd[wei].d);
  return;
}
void do3() {
  int wei;
  if (szx[1] == 0) {
    printf("0\n");
    return;
  }
  wei = getx(1, 1, numd);
  printf("%d\n", szd[wei].d);
  setx(1, 1, numd, wei, 0);
  szd[wei].d = 0;
  return;
}
int main() {
  int xuan;
  int f1;
  scanf("%I64d%d%d%d", &numz, &numd, &numq, &mo);
  for (f1 = 1; f1 <= numd; f1++) {
    scanf("%I64d%d", &szd[f1].x, &szd[f1].d);
    szd[f1].x--;
  }
  for (f1 = 1; f1 < mo; f1++) szm[f1].dist = ((1LL << 60) - 1);
  for (f1 = 1; f1 <= numd; f1++)
    if (szd[f1].x % mo == 0)
      setx(1, 1, numd, f1, szd[f1].d);
    else
      setx(1, 1, numd, f1, 0);
  for (f1 = 1; f1 <= numq; f1++) {
    scanf("%d", &xuan);
    switch (xuan) {
      case 1:
        do1();
        break;
      case 2:
        do2();
        break;
      case 3:
        do3();
        break;
    }
  }
  return 0;
}
