#include <bits/stdc++.h>
using namespace std;
const int MAXN = 100000 + 10, MAXK = 10000 + 10;
long long h, a[MAXN], f[MAXK];
int n, m, k, c[MAXN];
bool del[MAXN], cr[MAXN], vis[MAXK];
priority_queue<pair<int, int> > q;
void Add() {
  long long first;
  cin >> first;
  priority_queue<pair<long long, int> > heap;
  for (int i = 0; i < k; ++i) heap.push(make_pair(-f[i], -i));
  memset(vis, 0, sizeof(vis));
  while (!heap.empty()) {
    pair<long long, int> w = heap.top();
    heap.pop();
    w.first = -w.first, w.second = -w.second;
    if (vis[w.second]) continue;
    vis[w.second] = true;
    long long t = (long long)w.first * k + (long long)w.second + first;
    int a = t % k;
    t /= k;
    if (f[a] > t) f[a] = t, heap.push(make_pair(-t, -a));
  }
  for (int i = 1; i <= n; ++i)
    if (!del[i] && !cr[i])
      if ((long long)f[a[i] % k] * k <= a[i])
        cr[i] = true, q.push(make_pair(c[i], -i));
}
int main() {
  cin >> h >> n >> m >> k;
  for (int i = 1; i <= n; ++i) cin >> a[i] >> c[i], --a[i];
  for (int i = 0; i < k; ++i) f[i] = (long long)1e18 / k + 1;
  f[0] = 0;
  for (int i = 1; i <= n; ++i)
    if (a[i] % k == 0) cr[i] = true, q.push(make_pair(c[i], -i));
  for (int i = 1; i <= m; ++i) {
    int ty;
    scanf("%d", &ty);
    if (ty == 1)
      Add();
    else if (ty == 2) {
      int first, v;
      scanf("%d%d", &first, &v);
      c[first] -= v;
      if (cr[first]) q.push(make_pair(c[first], -first));
    } else {
      pair<int, int> w;
      if (q.empty()) {
        puts("0");
        continue;
      }
      for (;;) {
        if (q.empty()) {
          w.second = -1;
          break;
        }
        w = q.top();
        q.pop();
        w.second = -w.second;
        if (del[w.second] || c[w.second] != w.first) continue;
        break;
      }
      if (w.second == -1) {
        puts("0");
        continue;
      }
      del[w.second] = true;
      printf("%d\n", c[w.second]);
    }
  }
  fclose(stdin);
  fclose(stdout);
  return 0;
}
