#include <bits/stdc++.h>
using namespace std;
long long dp[101000];
long long pos[101000];
int val[101000];
int ok[101000];
vector<pair<long long, long long> > v[101000];
int main() {
  long long h, n, m, k;
  cin >> h >> n >> m >> k;
  multiset<int> ans;
  for (int i = 0; i < n; i++) {
    scanf("%I64d%d", pos + i, val + i), pos[i]--;
    v[pos[i] % k].push_back(pair<long long, long long>(pos[i], i));
  }
  for (int i = 0; i < k; i++) sort(v[i].begin(), v[i].end());
  for (int i = 1; i < k; i++) dp[i] = h;
  while (v[0].size()) {
    pair<int, int> u = v[0][v[0].size() - 1];
    v[0].pop_back();
    ans.insert(val[u.second]);
    ok[u.second] = 1;
  }
  while (m--) {
    int t;
    scanf("%d", &t);
    if (t == 3) {
      if (ans.size() == 0)
        printf("0\n");
      else {
        printf("%d\n", *--ans.end());
        ans.erase(--ans.end());
      }
    }
    if (t == 2) {
      int u, dec;
      scanf("%d%d", &u, &dec), u--;
      if (ok[u]) ans.erase(ans.find(val[u]));
      val[u] -= dec;
      if (ok[u]) ans.insert(val[u]);
    }
    if (t == 1) {
      long long a;
      cin >> a;
      priority_queue<pair<long long, long long> > Q;
      for (int i = 0; i < k; i++) Q.push(pair<long long, long long>(-dp[i], i));
      while (Q.size()) {
        pair<long long, long long> u = Q.top();
        u.first *= -1;
        Q.pop();
        if (u.first == h) break;
        if (dp[(a + u.second) % k] > dp[u.second] + a) {
          dp[(a + u.second) % k] = dp[u.second] + a;
          Q.push(pair<long long, long long>(-dp[u.second] - a,
                                            (a + u.second) % k));
        }
      }
      for (int i = 1; i < k; i++) {
        while (v[i].size() > 0 && v[i][v[i].size() - 1].first >= dp[i]) {
          pair<int, int> u = v[i][v[i].size() - 1];
          v[i].pop_back();
          ok[u.second] = 1;
          ans.insert(val[u.second]);
        }
      }
    }
  }
}
