#include <bits/stdc++.h>
using namespace std;
long long H;
int N, M, K;
long long A[100002], C[100002];
long long add[100002];
bool can[100002];
long long minget[10002];
set<pair<long long, int> > Q;
set<pair<int, int>, greater<pair<int, int> > > S;
int main() {
  cin.sync_with_stdio(false);
  cin >> H >> N >> M >> K;
  for (int i = 0; i < K; ++i) minget[i] = 1LL << 62;
  minget[0] = 0;
  for (int i = 1; i <= N; ++i) {
    cin >> C[i] >> A[i];
    --C[i];
    if (minget[C[i] % K] <= C[i]) {
      S.insert(make_pair(A[i], -i));
      can[i] = true;
    }
  }
  for (int i = 1, type; i <= M; ++i) {
    cin >> type;
    if (type == 1) {
      long long val;
      cin >> val;
      add[++add[0]] = val;
      for (int j = 0; j < K; ++j) minget[j] = 1LL << 62;
      minget[0] = 0;
      Q.insert(make_pair(0, 0));
      while (!Q.empty()) {
        int now = (*Q.begin()).second;
        Q.erase(Q.begin());
        for (int j = 1; j <= add[0]; ++j)
          if (minget[(now + add[j]) % K] > minget[now] + add[j]) {
            minget[(now + add[j]) % K] = minget[now] + add[j];
            Q.insert(make_pair(minget[(now + add[j]) % K], (now + add[j]) % K));
          }
      }
      for (int j = 1; j <= N; ++j)
        if (!can[j] && minget[C[j] % K] <= C[j]) {
          S.insert(make_pair(A[j], -j));
          can[j] = true;
        }
    } else if (type == 2) {
      int pos, val;
      cin >> pos >> val;
      if (!can[pos])
        A[pos] -= val;
      else {
        S.erase(S.find(make_pair(A[pos], -pos)));
        A[pos] -= val;
        S.insert(make_pair(A[pos], -pos));
      }
    } else if (type == 3) {
      if (S.empty()) {
        cout << 0 << '\n';
        continue;
      }
      cout << (*S.begin()).first << '\n';
      A[-(*S.begin()).second] = 0;
      S.erase(S.begin());
    }
  }
}
