#include <bits/stdc++.h>
using namespace std;
long long treasure[101000];
long long value[101000];
bool can[101000];
bool taken[101000];
set<pair<long long, long long> > st;
long long reach[10100];
long long inf = 1.0e20;
int main() {
  long long h, n, m;
  cin >> h >> n >> m;
  long long k;
  cin >> k;
  for (int i = 0; i < n; i++) {
    cin >> treasure[i] >> value[i];
    treasure[i]--;
    if (treasure[i] % k == 0) {
      can[i] = 1;
      st.insert(make_pair(-value[i], i));
    }
  }
  for (int i = 1; i < k; i++) reach[i] = inf;
  for (int i = 0; i < m; i++) {
    int t;
    cin >> t;
    if (t == 1) {
      long long l;
      cin >> l;
      set<pair<long long, long long> > q;
      for (int w = 0; w < k; w++) {
        q.insert(make_pair(reach[w], w));
      }
      while (!q.empty()) {
        pair<long long, long long> pt = *(q.begin());
        if (pt.first == inf) break;
        q.erase(q.begin());
        long long nxt = pt.first + l;
        long long npos = nxt % k;
        if (reach[npos] > nxt) {
          q.erase(make_pair(reach[npos], npos));
          reach[npos] = nxt;
          q.insert(make_pair(reach[npos], npos));
        }
      }
      for (int i = 0; i < n; i++) {
        if (!can[i] && reach[treasure[i] % k] <= treasure[i]) {
          can[i] = 1;
          st.insert(make_pair(-value[i], i));
        }
      }
    } else if (t == 2) {
      long long x, y;
      cin >> x >> y;
      x--;
      if (can[x]) {
        st.erase(make_pair(-value[x], x));
        value[x] -= y;
        st.insert(make_pair(-value[x], x));
      } else
        value[x] -= y;
    } else {
      if (st.size() == 0) {
        cout << 0 << endl;
      } else {
        pair<long long, long long> pt = *(st.begin());
        cout << -pt.first << endl;
        taken[pt.second] = 1;
        st.erase(pt);
      }
    }
  }
}
