#include <bits/stdc++.h>
using namespace std;
const long long oo = 1LL << 60;
long long H;
int N, Q, K;
int val[100005];
vector<pair<long long, int> > T[10005];
vector<long long> mod;
priority_queue<pair<long long, int> > reach;
long long dist[10005];
void dijkstra() {
  priority_queue<pair<long long, int> > Q;
  for (int i = 1; i < K; i++) dist[i] = oo;
  Q.push(pair<long long, int>(0, 0));
  while (!Q.empty()) {
    pair<long long, int> p = Q.top();
    Q.pop();
    int x = p.second;
    for (int i = 0; i < (int)mod.size(); i++) {
      long long D = dist[x] + mod[i];
      int y = D % K;
      if (D < dist[y]) {
        dist[y] = D;
        Q.push(pair<long long, int>(-D, y));
      }
    }
  }
  for (int i = 1; i < K; i++)
    while (!T[i].empty()) {
      pair<long long, int> p = T[i].back();
      if (p.first < dist[i]) break;
      reach.push(pair<long long, int>(val[p.second], -p.second));
      T[i].pop_back();
    }
}
int query() {
  while (!reach.empty()) {
    pair<long long, int> p = reach.top();
    reach.pop();
    if (p.first != val[-p.second])
      reach.push(pair<long long, int>(val[-p.second], p.second));
    else
      return (int)p.first;
  }
  return 0;
}
int main() {
  scanf("%I64d%d%d%d", &H, &N, &Q, &K);
  for (int i = 0; i < N; i++) {
    long long pos;
    scanf("%I64d%d", &pos, val + i);
    pos--;
    if (pos % K == 0)
      reach.push(pair<long long, int>(val[i], -i));
    else
      T[pos % K].push_back(pair<long long, int>(pos, i));
  }
  for (int i = 1; i < K; i++) sort(T[i].begin(), T[i].end());
  while (Q--) {
    int typ;
    scanf("%d", &typ);
    if (typ == 1) {
      long long x;
      scanf("%I64d", &x);
      mod.push_back(x);
      dijkstra();
    } else if (typ == 2) {
      int x, y;
      scanf("%d%d", &x, &y);
      val[x - 1] -= y;
    } else {
      int v = query();
      printf("%d\n", v);
    }
  }
  return 0;
}
