#include <bits/stdc++.h>
using namespace std;
int n, m, ktop;
long long h, k[25], dis[25];
int dis2[25];
long long len[10010];
int seq[10000000], head, tail;
bool vis[10010];
long long pla[100100];
int val[100100];
struct ty {
  long long pla;
  int val, num;
} tmp;
bool operator<(ty c1, ty c2) { return c1.pla > c2.pla; }
struct ty2 {
  long long pla;
  int val, num;
} tmp2;
bool operator<(ty2 c1, ty2 c2) {
  if (c1.val != c2.val) return c1.val > c2.val;
  return c1.num < c2.num;
}
void cp(ty2& c1, ty c2) {
  c1.pla = c2.pla;
  c1.val = c2.val;
  c1.num = c2.num;
}
multiset<ty> s[10010];
multiset<ty2> A;
void make() {
  int i;
  for (i = 0; i < k[0]; ++i) len[i] = 2000000000000000000ll;
  len[1] = 0;
  seq[1] = 1;
  head = 0;
  tail = 1;
  vis[1] = 1;
  while (head < tail) {
    ++head;
    for (i = 1; i <= ktop; ++i)
      if (len[seq[head]] + dis[i] + (dis2[i] + seq[head] >= k[0]) <
          len[(seq[head] + dis2[i] >= k[0]) ? seq[head] + dis2[i] - k[0]
                                            : seq[head] + dis2[i]]) {
        len[(seq[head] + dis2[i] >= k[0]) ? seq[head] + dis2[i] - k[0]
                                          : seq[head] + dis2[i]] =
            len[seq[head]] + dis[i] + (dis2[i] + seq[head] >= k[0]);
        if (!vis[(seq[head] + dis2[i] >= k[0]) ? seq[head] + dis2[i] - k[0]
                                               : seq[head] + dis2[i]]) {
          seq[++tail] = (seq[head] + dis2[i] >= k[0])
                            ? seq[head] + dis2[i] - k[0]
                            : seq[head] + dis2[i];
          vis[(seq[head] + dis2[i] >= k[0]) ? seq[head] + dis2[i] - k[0]
                                            : seq[head] + dis2[i]] = 1;
        }
      }
    vis[seq[head]] = 0;
  }
  for (i = 0; i < k[0]; ++i)
    while (!s[i].empty() && len[i] <= (*s[i].begin()).pla / k[0]) {
      cp(tmp2, *s[i].begin());
      A.insert(tmp2);
      s[i].erase(s[i].begin());
    }
}
int main() {
  int i, j, ord, x, y;
  scanf("%I64d%d%d%I64d", &h, &n, &m, k);
  for (i = 1; i <= n; ++i) {
    scanf("%I64d%d", &tmp.pla, &tmp.val);
    pla[i] = tmp.pla;
    val[i] = tmp.val;
    tmp.num = i;
    s[tmp.pla % k[0]].insert(tmp);
  }
  make();
  while (m--) {
    scanf("%d", &ord);
    if (ord == 1) {
      ++ktop;
      scanf("%I64d", k + ktop);
      dis[ktop] = k[ktop] / k[0];
      dis2[ktop] = k[ktop] % k[0];
      make();
    }
    if (ord == 2) {
      scanf("%d%d", &x, &y);
      tmp.pla = pla[x];
      tmp.val = val[x];
      tmp.num = x;
      if (s[pla[x] % k[0]].find(tmp) != s[pla[x] % k[0]].end()) {
        s[pla[x] % k[0]].erase(s[pla[x] % k[0]].find(tmp));
        tmp.val -= y;
        s[pla[x] % k[0]].insert(tmp);
      } else {
        cp(tmp2, tmp);
        A.erase(A.find(tmp2));
        tmp2.val -= y;
        A.insert(tmp2);
      }
      val[x] -= y;
    }
    if (ord == 3) {
      if (A.empty())
        puts("0");
      else {
        printf("%d\n", (*A.begin()).val);
        A.erase(A.begin());
      }
    }
  }
  return 0;
}
