#include <bits/stdc++.h>
using namespace std;
bool debug = false;
int n, m, k;
int dx[4] = {1, 0, -1, 0}, dy[4] = {0, 1, 0, -1};
long long ln, lk, lm;
long long h;
const int MAXN = 10005;
long long a[100005], c[100005];
long long dis[MAXN];
long long iif = 2e18;
bool used[MAXN];
set<long long> ks;
void dd() {
  memset(used, 0, sizeof used);
  for (int(i) = 0; (i) < (int)(k); (i)++) dis[i] = iif;
  dis[1 % k] = 1;
  priority_queue<pair<long long, int>, std::vector<pair<long long, int>>,
                 std::greater<pair<long long, int>>>
      q;
  q.push({1, 1 % k});
  while (!q.empty()) {
    int x = q.top().second;
    q.pop();
    if (used[x]) continue;
    used[x] = 1;
    for (long long p : ks) {
      long long d = p + dis[x];
      if (d > h) continue;
      int y = (p + x) % k;
      if (d < dis[y]) {
        dis[y] = d;
        q.push({dis[y], y});
      }
    }
  }
}
set<pair<long long, long long>> s;
set<int> que;
void add() {
  vector<int> v;
  for (int i : que) {
    if (dis[a[i] % k] <= a[i]) {
      s.insert({-c[i], i});
      v.push_back(i);
    }
  }
  for (int i : v) que.erase(i);
}
int main() {
  scanf("%lld%d%d%d", &h, &n, &m, &k);
  for (int(i) = 1; (i) <= (int)(n); (i)++) {
    scanf("%lld%lld", a + i, c + i);
    que.insert(i);
  }
  dd();
  add();
  int tp;
  int x, y;
  for (int(i) = 0; (i) < (int)(m); (i)++) {
    scanf("%d", &tp);
    if (tp == 1) {
      long long x;
      scanf("%lld", &x);
      ks.insert(x);
      dd();
      add();
    } else if (tp == 2) {
      scanf("%d%d", &x, &y);
      if (que.find(x) != que.end())
        c[x] -= y;
      else {
        s.erase({-c[x], x});
        c[x] -= y;
        s.insert({-c[x], x});
      }
    } else {
      if (s.empty())
        puts("0");
      else {
        auto it = *s.begin();
        printf("%lld\n", -(it.first));
        s.erase(s.begin());
      }
    }
  }
  return 0;
}
