#include <bits/stdc++.h>
using namespace std;
const int MOD = 95542721;
const int INF = 2e9;
const long long INF64 = 2e18;
const long double EPS = 1e-16;
const long double PI = acos(-1);
const long long MD = 1551513443;
const long long T = 2;
const int N = 100011;
const int M = 100;
const int DEBUG = 0;
const int MAGIC = 320;
int n, m, c[N];
long long h, a[N], k, dp[N];
bool use[N];
set<pair<int, int> > qq;
vector<long long> b;
set<pair<long long, long long> > q;
inline void update(long long first) {
  b.push_back(first);
  q.clear();
  fill(dp, dp + k, INF64);
  dp[1 % k] = 0LL;
  q.insert(make_pair(0LL, 1LL % k));
  while (!q.empty()) {
    long long v = q.begin()->second;
    q.erase(q.begin());
    for (long long w : b) {
      long long u = (v + w) % k;
      if (dp[u] > dp[v] + w) {
        q.erase(make_pair(dp[u], u));
        dp[u] = min(dp[v] + w, INF64);
        if (dp[u] < INF64) q.insert(make_pair(dp[u], u));
      }
    }
  }
  qq.clear();
  for (int i = 0; i < int(n); i++)
    if (!use[i] && 1 + dp[a[i] % k] <= a[i]) qq.insert(make_pair(-c[i], i));
}
int main() {
  cin >> h >> n >> m >> k;
  for (int i = 0; i < int(n); i++) scanf("%I64d %d", &a[i], &c[i]);
  update(k);
  for (int u = 0; u < int(m); u++) {
    int t;
    scanf("%d", &t);
    if (t == 1) {
      long long first;
      scanf("%I64d", &first);
      update(first);
    }
    if (t == 2) {
      int first, second;
      scanf("%d %d", &first, &second);
      first--;
      qq.erase(make_pair(-c[first], first));
      c[first] -= second;
      if (dp[a[first] % k] + 1LL <= a[first])
        qq.insert(make_pair(-c[first], first));
    }
    if (t == 3) {
      if (qq.empty())
        printf("0\n");
      else {
        int v = qq.begin()->second;
        qq.erase(qq.begin());
        use[v] = 1;
        printf("%d\n", c[v]);
      }
    }
  }
  return 0;
}
