#include <bits/stdc++.h>
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
using namespace std;
const int N = 500005;
vector<pair<int, int> > v[N];
int n, X, Y, x, y, z, Z, cnt, vis[N];
long long ans, sum;
struct dui {
  int f[N], l;
  inline void up(int x) {
    if (x == 1) return;
    if (f[x] > f[x / 2]) {
      swap(f[x], f[x / 2]);
      up(x / 2);
    }
  }
  inline void down(int x) {
    int i = x;
    if (x * 2 <= l && f[x] < f[x * 2]) i = x * 2;
    if (x * 2 < l && f[i] < f[x * 2 + 1]) i = x * 2 + 1;
    if (i != x) {
      swap(f[x], f[i]);
      down(i);
    }
  }
  inline void insert(int x) {
    f[++l] = x;
    up(l);
  }
  inline void del() {
    f[1] = f[l--];
    down(1);
  }
} f1, f2, f3, f4;
struct Tree {
  int l, r, num;
} T[N * 4];
inline void build(int x, int l, int r) {
  T[x].l = l;
  T[x].r = r;
  if (l == r) return;
  int mid = (l + r) / 2;
  build(x * 2, l, mid);
  build(x * 2 + 1, mid + 1, r);
}
inline void insert(int x, int y, int z) {
  if (T[x].l > y) return;
  if (T[x].r <= y) {
    T[x].num = max(T[x].num, z);
    return;
  }
  insert(x * 2, y, z);
  insert(x * 2 + 1, y, z);
}
inline int find(int x, int y) {
  if (T[x].l == T[x].r) return T[x].num;
  int mid = (T[x].l + T[x].r) / 2;
  if (y <= mid) return max(find(x * 2, y), T[x].num);
  return max(find(x * 2 + 1, y), T[x].num);
}
int main() {
  scanf("%d%d%d%d", &n, &X, &Y, &Z);
  for (int i = 1; i <= n; i++) {
    scanf("%d%d%d", &x, &y, &z);
    f1.insert(y);
    f2.insert(z);
    v[x].push_back(make_pair(y, z));
  }
  f1.insert(0);
  f2.insert(0);
  build(1, 1, Y);
  int now1 = Y, now2 = Z;
  for (int i = 1; i <= X; i++) {
    for (pair<int, int> j : v[i - 1]) {
      insert(1, j.first, j.second);
      f3.insert(j.first);
      f4.insert(j.second);
      while (f3.l && f1.l && f3.f[1] == f1.f[1]) f3.del(), f1.del();
      while (f4.l && f2.l && f4.f[1] == f2.f[1]) f4.del(), f2.del();
    }
    while (now1 > f1.f[1]) {
      int t = find(1, now1);
      if (t <= now2)
        cnt++, vis[t]++;
      else
        sum += Z - t;
      now1--;
    }
    while (now2 > f2.f[1]) {
      sum += (long long)vis[now2] * (Z - now2);
      cnt -= vis[now2];
      now2--;
    }
    ans += sum + (long long)cnt * (Z - now2);
  }
  printf("%lld\n", ans);
  return 0;
}
