#include <bits/stdc++.h>
using namespace std;
const long long MAXN = 2e5 + 10, MAXK = 10086;
long long dis[MAXK], a[MAXN], c[MAXN], h, n, m, k;
bool vis[MAXN];
set<pair<long long, long long> > q;
struct Edge {
  long long ver, nxt, w;
} e[MAXN * 2];
long long tot = 0, head[MAXN];
void add(long long u, long long v, long long w) {
  e[++tot].ver = v;
  e[tot].w = w;
  e[tot].nxt = head[u];
  head[u] = tot;
}
void Update() {
  long long i;
  set<pair<long long, long long> > st;
  for (i = 0; i < k; i++) st.insert(make_pair(dis[i], i));
  while (st.size()) {
    long long u = st.begin()->second;
    st.erase(st.begin());
    for (i = head[u]; i; i = e[i].nxt) {
      long long v = e[i].ver, w = e[i].w;
      if (dis[v] > dis[u] + w) {
        st.erase(make_pair(dis[v], v));
        dis[v] = dis[u] + w;
        st.insert(make_pair(dis[v], v));
      }
    }
  }
  for (i = 1; i <= n; i++)
    if (!vis[i] && dis[a[i] % k] <= a[i]) {
      vis[i] = true;
      q.insert(make_pair(-c[i], i));
    }
}
int main() {
  long long i, j;
  scanf("%lld %lld %lld %lld", &h, &n, &m, &k);
  memset(dis, 0x3F, sizeof(dis));
  dis[1] = 1;
  for (i = 1; i <= n; i++) {
    scanf("%lld %lld", &a[i], &c[i]);
    if (a[i] % k == 1) {
      vis[i] = true;
      q.insert({-c[i], i});
    }
  }
  while (m--) {
    long long op, x, y;
    scanf("%lld", &op);
    if (op == 1) {
      scanf("%lld", &x);
      for (i = 0; i < k; i++) add(i, (i + x) % k, x);
      Update();
    }
    if (op == 2) {
      scanf("%lld %lld", &x, &y);
      if (q.count({-c[x], x})) {
        q.erase(make_pair(-c[x], x));
        q.insert(make_pair(-c[x] + y, x));
      }
      c[x] -= y;
    }
    if (op == 3) {
      if (!q.size())
        printf("0");
      else {
        printf("%lld", -(q.begin()->first));
        q.erase(q.begin());
      }
      printf("\n");
    }
  }
  return 0;
}
