#include <bits/stdc++.h>
using namespace std;
inline int readInt() {
  static int n, ch;
  n = 0, ch = getchar();
  while (!isdigit(ch)) ch = getchar();
  while (isdigit(ch)) n = n * 10 + ch - '0', ch = getchar();
  return n;
}
const int MAX_N = 500000 + 3;
int n, p, q, r, a[MAX_N], b[MAX_N], c[MAX_N];
struct SegmentTree {
  static const int MAX_NODE = (1 << 19) * 2;
  struct Data {
    long long sum;
    int mx;
    Data(long long sum = 0, int mx = 0) : sum(sum), mx(mx) {}
    Data operator+(const Data &ano) const {
      return Data(sum + ano.sum, max(mx, ano.mx));
    }
  } nodes[MAX_NODE];
  int n, tagSet[MAX_NODE];
  void init(int _n) {
    n = _n;
    memset(tagSet, -1, sizeof tagSet);
  }
  inline void set(int o, int l, int r, int v) {
    tagSet[o] = v;
    nodes[o].sum = (long long)(r - l) * v;
    nodes[o].mx = v;
  }
  inline void pushDown(int o, int l, int r) {
    if (tagSet[o] != -1) {
      set((((o) << 1) + 1), l, (((l) + (r)) >> 1), tagSet[o]);
      set((((o) << 1) + 2), (((l) + (r)) >> 1), r, tagSet[o]);
      tagSet[o] = -1;
    }
  }
  void set(int o, int l, int r, int a, int b, int v) {
    if (r <= a || l >= b) return;
    if (l >= a && r <= b)
      set(o, l, r, v);
    else {
      pushDown(o, l, r);
      set((((o) << 1) + 1), l, (((l) + (r)) >> 1), a, b, v);
      set((((o) << 1) + 2), (((l) + (r)) >> 1), r, a, b, v);
      nodes[o] = nodes[(((o) << 1) + 1)] + nodes[(((o) << 1) + 2)];
    }
  }
  int get(int o, int l, int r, int v) {
    if (r - l == 1) return nodes[o].mx < v ? l : r;
    pushDown(o, l, r);
    if (nodes[(((o) << 1) + 2)].mx < v)
      return get((((o) << 1) + 1), l, (((l) + (r)) >> 1), v);
    return get((((o) << 1) + 2), (((l) + (r)) >> 1), r, v);
  }
  int query(int o, int l, int r, int pos) {
    if (r - l == 1) return nodes[o].mx;
    pushDown(o, l, r);
    if (pos < (((l) + (r)) >> 1))
      return query((((o) << 1) + 1), l, (((l) + (r)) >> 1), pos);
    return query((((o) << 1) + 2), (((l) + (r)) >> 1), r, pos);
  }
  inline void update(int l, int r, int v) {
    int pos = get(0, 0, n, v);
    set(0, 0, n, pos, r, v);
  }
  inline long long sum() const { return nodes[0].sum; }
  void print() {
    for (int i = 0; i < n; ++i) cout << query(0, 0, n, i) << ' ';
    cout << endl;
  }
} segmentTree;
vector<pair<int, int> > vec[MAX_N];
int main() {
  n = readInt(), p = readInt(), q = readInt(), r = readInt();
  segmentTree.init(p);
  for (int i = 0; i < n; ++i) {
    a[i] = readInt(), b[i] = readInt(), c[i] = readInt();
    vec[c[i]].push_back(make_pair(a[i], b[i]));
    segmentTree.update(0, a[i], b[i]);
  }
  long long sum = 0;
  for (int i = r - 1; i >= 0; --i) {
    for (int j = 0; j < (int)vec[i + 1].size(); ++j) {
      pair<int, int> pi = vec[i + 1][j];
      segmentTree.update(0, pi.first, q);
      segmentTree.update(pi.first, p, pi.second);
    }
    sum += (long long)p * q - segmentTree.sum();
  }
  printf("%lld\n", sum);
  return 0;
}
