#include <bits/stdc++.h>
using namespace std;
struct node {
  int id, val;
  node() {}
  node(int a, int b) : id(a), val(b) {}
  bool operator<(const node &b) const {
    return b.val > val || b.val == val && b.id < id;
  }
};
priority_queue<node> q;
long long a[100005], dis[100005], e[100005], h;
int c[100005], cnt, k;
bool ok[100005], in[100005];
void spfa() {
  memset(dis, -1, sizeof(dis));
  memset(in, 0, sizeof(in));
  queue<int> sp;
  dis[1] = 1;
  sp.push(1);
  in[1] = true;
  while (!sp.empty()) {
    int u = sp.front();
    sp.pop();
    in[u] = false;
    for (int i = 0; i <= cnt; ++i) {
      int v = (u + e[i]) % k;
      if (dis[v] == -1 || dis[v] > dis[u] + e[i]) {
        dis[v] = dis[u] + e[i];
        if (!in[v]) sp.push(v), in[v] = true;
      }
    }
  }
}
int main() {
  int n, m, t, x, y;
  long long z;
  scanf("%I64d%d%d%d", &h, &n, &m, &k);
  e[cnt++] = k;
  for (int i = 1; i <= n; ++i) {
    scanf("%I64d%d", a + i, c + i);
    if (a[i] % k == 1) {
      ok[i] = true;
      q.push(node(i, c[i]));
    }
  }
  while (m--) {
    scanf("%d", &t);
    if (t == 1) {
      scanf("%I64d", &z);
      e[cnt++] = z;
      spfa();
      while (!q.empty()) q.pop();
      for (int i = 1; i <= n; ++i) {
        x = a[i] % k;
        if (dis[x] != -1 && a[i] >= dis[x])
          ok[i] = true, q.push(node(i, c[i]));
        else
          ok[i] = false;
      }
    } else if (t == 2) {
      scanf("%d%d", &x, &y);
      c[x] -= y;
      if (ok[x]) q.push(node(x, c[x]));
    } else {
      while (!q.empty() && c[q.top().id] != q.top().val) q.pop();
      if (q.empty())
        puts("0");
      else
        printf("%d\n", q.top().val), c[q.top().id] = 0, q.pop();
    }
  }
  return 0;
}
