#include <bits/stdc++.h>
using namespace std;
const int inf = 1e9 + 333;
const long long linf = 1e18 + 333;
const int N = 1e5 + 5;
const int K = 1e4 + 5;
int n, m, k, c[N];
bool dead[N];
long long h, a[N], dist[K];
set<pair<int, long long> > s;
vector<long long> jump;
void add(long long x) {
  jump.push_back(x);
  for (int i = 0; i < k; i++) dist[i] = linf;
  priority_queue<pair<long long, int> > Q;
  dist[1] = 1;
  Q.push(make_pair(-1, 1));
  while (!Q.empty()) {
    long long d = -Q.top().first;
    int x = Q.top().second;
    Q.pop();
    if (d > dist[x]) continue;
    for (__typeof((jump).begin()) it = (jump).begin(); it != (jump).end();
         it++) {
      long long t = *it;
      if (d + t < dist[(x + t) % k]) {
        dist[(x + t) % k] = d + t;
        Q.push(make_pair(-(d + t), (x + t) % k));
      }
    }
  }
  for (int i = 1; i <= n; i++)
    if (!dead[i] and dist[a[i] % k] <= a[i]) s.insert(make_pair(c[i], -i));
}
int main() {
  ios ::sync_with_stdio(0);
  cin >> h >> n >> m >> k;
  for (int i = 1; i <= n; i++) cin >> a[i] >> c[i];
  add(k);
  for (int i = 1; i <= m; i++) {
    int type;
    cin >> type;
    if (type == 1) {
      long long x;
      cin >> x;
      add(x);
    }
    if (type == 2) {
      int x, y;
      cin >> x >> y;
      if (s.count(make_pair(c[x], -x))) {
        s.erase(make_pair(c[x], -x));
        c[x] -= y;
        s.insert(make_pair(c[x], -x));
      } else
        c[x] -= y;
    }
    if (type == 3) {
      if (s.size()) {
        cout << s.rbegin()->first << endl;
        dead[-s.rbegin()->second] = 1;
        s.erase(s.find(*s.rbegin()));
      } else
        cout << 0 << endl;
    }
  }
  return 0;
}
