#include <bits/stdc++.h>
using namespace std;
int IN() {
  int c, f, x;
  while (!isdigit(c = getchar()) && c != '-')
    ;
  c == '-' ? (f = 1, x = 0) : (f = 0, x = c - '0');
  while (isdigit(c = getchar())) x = (x << 1) + (x << 3) + c - '0';
  return !f ? x : -x;
}
const int N = 500000 + 19;
struct node {
  int a, b, c;
  bool operator<(const node &B) const { return a < B.a; }
} A[N];
int mxb[N], mxc[N];
int n, p, q, r, c;
long long res;
int mn[N * 4], cov[N * 4];
long long sum[N * 4];
int Ql, Qr, Qv, pos;
void Cov(int x, int L, int R, int v) {
  mn[x] = v;
  cov[x] = v;
  sum[x] = 1ll * v * (R - L + 1);
}
void Down(int x, int L, int R) {
  if (cov[x]) {
    Cov((x << 1), L, ((L + R) >> 1), cov[x]);
    Cov((x << 1 | 1), ((L + R) >> 1) + 1, R, cov[x]);
    cov[x] = 0;
  }
}
void Build(int x, int L, int R) {
  if (L == R) {
    mn[x] = sum[x] = 1;
    return;
  }
  Build((x << 1), L, ((L + R) >> 1));
  Build((x << 1 | 1), ((L + R) >> 1) + 1, R);
  mn[x] = min(mn[(x << 1)], mn[(x << 1 | 1)]);
  sum[x] = sum[(x << 1)] + sum[(x << 1 | 1)];
}
void Modify(int x, int L, int R) {
  if (Ql <= L && R <= Qr) {
    Cov(x, L, R, Qv);
    return;
  }
  Down(x, L, R);
  if (Ql <= ((L + R) >> 1)) Modify((x << 1), L, ((L + R) >> 1));
  if (Qr > ((L + R) >> 1)) Modify((x << 1 | 1), ((L + R) >> 1) + 1, R);
  mn[x] = min(mn[(x << 1)], mn[(x << 1 | 1)]);
  sum[x] = sum[(x << 1)] + sum[(x << 1 | 1)];
}
long long Qsum(int x, int L, int R) {
  if (Ql <= L && R <= Qr) return sum[x];
  Down(x, L, R);
  long long res = 0;
  if (Ql <= ((L + R) >> 1)) res += Qsum((x << 1), L, ((L + R) >> 1));
  if (Qr > ((L + R) >> 1)) res += Qsum((x << 1 | 1), ((L + R) >> 1) + 1, R);
  return res;
}
int Qmin2(int x, int L, int R) {
  if (L == R) return L;
  Down(x, L, R);
  if (mn[(x << 1)] <= Qv) return Qmin2((x << 1), L, ((L + R) >> 1));
  return Qmin2((x << 1 | 1), ((L + R) >> 1) + 1, R);
}
void Qmin(int x, int L, int R) {
  if (~pos) return;
  if (Ql <= L && R <= Qr) {
    if (mn[x] <= Qv) pos = Qmin2(x, L, R);
    return;
  }
  Down(x, L, R);
  if (Ql <= ((L + R) >> 1)) Qmin((x << 1), L, ((L + R) >> 1));
  if (Qr > ((L + R) >> 1)) Qmin((x << 1 | 1), ((L + R) >> 1) + 1, R);
}
void gao(int x, int y) {
  pos = -1;
  Ql = 1, Qr = x, Qv = y;
  Qmin(1, 1, q);
  if (pos == -1) return;
  Ql = pos, Qr = x, Qv = y;
  Modify(1, 1, q);
}
long long qry(int x, int y) {
  if (x > q || y > r) return 0;
  pos = -1;
  Ql = x, Qr = q, Qv = y;
  Qmin(1, 1, q);
  if (pos == -1) pos = q + 1;
  long long res = 0;
  res += 1ll * (r - y + 1) * (q - pos + 1);
  Ql = x, Qr = pos - 1;
  if (Ql <= Qr) {
    res += 1ll * (r + 1) * (Qr - Ql + 1);
    res -= Qsum(1, 1, q);
  }
  return res;
}
int main() {
  n = IN(), p = IN(), q = IN(), r = IN();
  for (int i = 1; i < n + 1; i++) {
    A[i] = (node){IN(), IN(), IN()};
  }
  sort(A + 1, A + n + 1);
  for (int i = n; i; i--) {
    mxb[i] = max(mxb[i + 1], A[i].b);
    mxc[i] = max(mxc[i + 1], A[i].c);
  }
  Build(1, 1, q);
  c = 1;
  for (int u = 1; u <= p; u++) {
    for (; c <= n && A[c].a < u; c++) {
      gao(A[c].b, A[c].c + 1);
    }
    res += qry(mxb[c] + 1, mxc[c] + 1);
  }
  cout << res << endl;
}
