#include <bits/stdc++.h>
using namespace std;
const int N = 201000;
struct record {
  int x, y;
  bool operator<(const record &b) const { return x == b.x ? y > b.y : x < b.x; }
  record() {}
  record(int _x, int _y) { x = _x, y = _y; }
};
priority_queue<record> seq;
vector<int> R[N];
queue<int> que;
int n, m, k, p, t, x, y;
int c[N], v[N], F[N];
long long h;
long long d[N], a[N], pet[N];
bool cmprec(int x, int y) { return a[x] < a[y]; }
void work() {
  for (int i = 0; i < k; i++)
    if (d[i] < 1e18 + 12345) que.push(i), F[i] = 1;
  while (!que.empty()) {
    int x = que.front(), y;
    F[x] = 0;
    que.pop();
    for (int i = 0; i < p; i++)
      if (d[y = (x + pet[i]) % k] > d[x] + pet[i]) {
        d[y] = d[x] + pet[i];
        if (!F[y]) F[y] = 1, que.push(y);
      }
  }
  for (int i = 0; i < k; i++)
    while (R[i].size() && a[R[i][R[i].size() - 1]] >= d[i]) {
      v[R[i][R[i].size() - 1]] = 1;
      seq.push(record(c[R[i][R[i].size() - 1]], R[i][R[i].size() - 1]));
      R[i].pop_back();
    }
}
int main() {
  cin >> h >> n >> m >> k;
  for (int i = 0; i < n; i++) {
    cin >> a[i] >> c[i];
    a[i]--;
    R[a[i] % k].push_back(i);
  }
  for (int i = 0; i < k; i++) {
    sort(R[i].begin(), R[i].end(), cmprec);
    d[i] = (long long)(1e18 + 20);
  }
  d[0] = 0;
  work();
  while (m--) {
    cin >> t;
    if (t == 1) {
      cin >> pet[p++];
      work();
    } else if (t == 2) {
      cin >> x >> y;
      c[--x] -= y;
      if (v[x]) seq.push((record){c[x], x});
    } else {
      while (!seq.empty() && seq.top().x != c[seq.top().y]) seq.pop();
      if (!seq.empty()) {
        cout << seq.top().x << endl;
        c[seq.top().y] = 0, seq.pop();
      } else
        cout << 0 << endl;
    }
  }
  return 0;
}
