#include <bits/stdc++.h>
using namespace std;
long long h;
int n, m, k;
long long a[100000];
int c[100000];
bool vis[100000];
set<pair<long long, long long> > st;
vector<long long> jump;
map<long long, int> idx;
long long dist[10000];
void update() {
  fill(dist, dist + 10000, 1LL << 60);
  priority_queue<pair<long long, int>, vector<pair<long long, int> >,
                 greater<pair<long long, int> > >
      Q;
  Q.push(make_pair(1, 1));
  while (!Q.empty()) {
    long long v = Q.top().first;
    int x = Q.top().second;
    Q.pop();
    if (dist[x] < v) continue;
    for (int i = 0; i < (int)(jump.size()); i++) {
      int xx = (x + jump[i]) % k;
      if (dist[xx] > v + jump[i]) {
        dist[xx] = v + jump[i];
        Q.push(make_pair(dist[xx], xx));
      }
    }
  }
  st.clear();
  for (int i = 0; i < (int)(n); i++) {
    if (vis[i]) continue;
    if (a[i] >= dist[a[i] % k]) {
      st.insert(make_pair(-c[i], i));
    }
  }
}
int main() {
  cin >> h >> n >> m >> k;
  for (int i = 0; i < (int)(n); i++) {
    cin >> a[i] >> c[i];
    idx[a[i]] = i;
  }
  jump.push_back(k);
  update();
  for (int i = 0; i < (int)(m); i++) {
    int type;
    cin >> type;
    if (type == 1) {
      long long x;
      cin >> x;
      jump.push_back(x);
      update();
    } else if (type == 2) {
      int x, y;
      cin >> x >> y;
      --x;
      if (vis[x]) continue;
      __typeof(st.begin()) itr = st.find(make_pair(-c[x], x));
      c[x] -= y;
      if (itr != st.end()) {
        st.erase(itr);
        st.insert(make_pair(-c[x], x));
      }
    } else {
      if (st.empty())
        cout << 0 << endl;
      else {
        __typeof(st.begin()) itr = st.begin();
        long long x = -itr->first;
        long long y = itr->second;
        cout << x << endl;
        vis[y] = true;
        st.erase(itr);
      }
    }
  }
  return 0;
}
