#include <bits/stdc++.h>
using namespace std;
vector<int> f;
long long dis[100100];
bool flag[100100];
long long a[100100];
int c[100100];
long long h;
int n, m, K;
struct Node {
  int max1, max2;
} node[100100 << 2];
void pushdown(int pos) {
  node[pos].max1 = max(node[pos << 1].max1, node[pos << 1 | 1].max1);
  node[pos].max2 = max(node[pos << 1].max2, node[pos << 1 | 1].max2);
}
void build(int pos, int l, int r) {
  node[pos].max1 = -1;
  if (l == r)
    node[pos].max2 = c[l];
  else {
    build(pos << 1, l, ((l + r) >> 1));
    build(pos << 1 | 1, ((l + r) >> 1) + 1, r);
    pushdown(pos);
  }
}
void update(int pos, int l, int r, int p, int add) {
  if (l == r) {
    node[pos].max1 += add;
    node[pos].max2 += add;
  } else {
    if (p <= ((l + r) >> 1))
      update(pos << 1, l, ((l + r) >> 1), p, add);
    else
      update(pos << 1 | 1, ((l + r) >> 1) + 1, r, p, add);
    pushdown(pos);
  }
}
void setnode(int pos, int l, int r) {
  if (l == r)
    node[pos].max1 = -1;
  else {
    if (node[pos << 1].max1 >= node[pos << 1 | 1].max1)
      setnode(pos << 1, l, ((l + r) >> 1));
    else
      setnode(pos << 1 | 1, ((l + r) >> 1) + 1, r);
    pushdown(pos);
  }
}
void trans(int pos, int l, int r, int p) {
  if (l == r) {
    node[pos].max1 = node[pos].max2;
    node[pos].max2 = -1;
  } else {
    if (p <= ((l + r) >> 1))
      trans(pos << 1, l, ((l + r) >> 1), p);
    else
      trans(pos << 1 | 1, ((l + r) >> 1) + 1, r, p);
    pushdown(pos);
  }
}
bool visit[100100];
void spfa() {
  memset(visit, 0, sizeof(visit));
  queue<int> q;
  for (int i = 0; i < (K); ++i)
    if (dis[i] < (1ll << 62)) q.push(i), visit[i] = 1;
  while (!q.empty()) {
    int top = q.front();
    q.pop();
    visit[top] = 0;
    for (int i = 0; i < ((int)f.size()); ++i) {
      long long temp = dis[top] + dis[f[i]];
      int to = (top + f[i]) % K;
      if (temp < dis[to]) {
        dis[to] = temp;
        if (!visit[to]) {
          visit[to] = 1;
          q.push(to);
        }
      }
    }
  }
}
void init() {
  memset(flag, 0, sizeof(flag));
  for (int i = 0; i < (K); ++i) dis[i] = (1ll << 62);
  f.clear();
  dis[0] = 0;
}
int main() {
  int x, y;
  while (cin >> h >> n >> m >> K) {
    init();
    for (int i = (1); i <= (n); ++i) {
      scanf("%I64d%d", &a[i], &c[i]);
      a[i]--;
    }
    build(1, 1, n);
    for (int i = (1); i <= (n); ++i) {
      if (!flag[i] && a[i] >= dis[a[i] % K]) {
        flag[i] = 1;
        trans(1, 1, n, i);
      }
    }
    long long temp;
    while (m--) {
      scanf("%d", &x);
      if (x == 1) {
        scanf("%I64d", &temp);
        f.push_back(temp % K);
        dis[temp % K] = min(dis[temp % K], temp);
        spfa();
        for (int i = (1); i <= (n); ++i) {
          if (!flag[i] && a[i] >= dis[a[i] % K]) {
            flag[i] = 1;
            trans(1, 1, n, i);
          }
        }
      } else if (x == 2) {
        scanf("%d%d", &x, &y);
        update(1, 1, n, x, -y);
      } else if (x == 3) {
        if (node[1].max1 <= -1) {
          puts("0");
        } else {
          printf("%d\n", node[1].max1);
          setnode(1, 1, n);
        }
      }
    }
  }
  return 0;
}
