#include <bits/stdc++.h>
using namespace std;
const int maxn = 5e5 + 10;
struct Info {
  int x, y, z;
  Info() {}
  Info(int x, int y, int z) : x(x), y(y), z(z) {}
  bool operator<(const Info &a) const { return x < a.x; }
} a[maxn];
int n, x, y, z, maxy[maxn], maxz[maxn];
set<pair<int, int> > s;
long long ans;
struct node {
  node *ch[2];
  long long num, tag, len;
  node() {
    memset(ch, 0, sizeof ch);
    num = tag = 0;
    len = 1;
  }
  void M(long long x) {
    num = len * x;
    tag = x;
  }
  void pull() {
    len = 0;
    num = 0;
    for (int i = 0; i < (2); ++i) {
      num += ch[i]->num;
      len += ch[i]->len;
    }
    return;
  }
  void push() {
    if (tag) {
      for (int i = 0; i < (2); ++i) {
        ch[i]->M(tag);
      }
      tag = 0;
    }
    return;
  }
} * root;
void B(node *&u = root, int l = 1, int r = z) {
  u = new node;
  if (l == r) {
    return;
  }
  int mid = l + r >> 1;
  B(u->ch[0], l, mid);
  B(u->ch[1], mid + 1, r);
  return u->pull();
}
int seg_a, seg_b;
long long seg_q;
void M(node *&u = root, int l = 1, int r = z) {
  if (seg_a <= l && r <= seg_b) {
    u->M(seg_q);
    return;
  }
  int mid = l + r >> 1;
  u->push();
  if (seg_a <= mid) {
    M(u->ch[0], l, mid);
  }
  if (seg_b > mid) {
    M(u->ch[1], mid + 1, r);
  }
  return u->pull();
}
void Q(node *&u = root, int l = 1, int r = z) {
  if (seg_a <= l && r <= seg_b) {
    seg_q += u->num;
    return;
  }
  int mid = l + r >> 1;
  u->push();
  if (seg_a <= mid) {
    Q(u->ch[0], l, mid);
  }
  if (seg_b > mid) {
    Q(u->ch[1], mid + 1, r);
  }
  return u->pull();
}
void ins(int y, int z) {
  auto it = s.lower_bound(make_pair(y + 1, 0));
  if (it == s.end()) {
    seg_a = 1;
  } else {
    seg_a = it->second + 1;
  }
  if (it != s.begin()) {
    --it;
    for (;;) {
      if (it->first <= y && it->second <= z) {
        it = s.erase(it);
        if (it == s.begin()) {
          break;
        }
        --it;
      } else {
        break;
      }
    }
  }
  it = s.lower_bound(make_pair(y + 1, 0));
  if (it != s.begin()) {
    --it;
    if (y <= it->first && z <= it->second) {
      return;
    }
  }
  seg_b = z;
  if (seg_a <= seg_b) {
    seg_q = y;
    M();
    s.insert(make_pair(y, z));
  }
  return;
}
int main() {
  scanf("%d%d%d%d", &n, &x, &y, &z);
  for (int i = 0; i < (n); ++i) {
    scanf("%d%d%d", &a[i].x, &a[i].y, &a[i].z);
  }
  sort(a, a + n);
  maxy[n - 1] = a[n - 1].y;
  maxz[n - 1] = a[n - 1].z;
  for (int i = n - 2; ~i; --i) {
    maxy[i] = max(maxy[i + 1], a[i].y);
    maxz[i] = max(maxz[i + 1], a[i].z);
  }
  ans = 1ll * a[0].x * (y - maxy[0]) * (z - maxz[0]);
  B();
  a[n].x = x;
  for (int i = 0; i < n;) {
    int j = i;
    while (j + 1 < n && a[j + 1].x == a[i].x) {
      ++j;
    }
    for (int k = i; k <= j; ++k) {
      ins(a[k].y, a[k].z);
    }
    int ly, lz;
    ly = maxy[j + 1] + 1;
    lz = maxz[j + 1] + 1;
    long long tmp = 1ll * (y - ly + 1) * (z - lz + 1);
    auto it = s.lower_bound(make_pair(ly, 0));
    if (it != s.end()) {
      seg_a = lz;
      seg_b = it->second;
      if (seg_a <= seg_b) {
        seg_q = 0;
        Q();
        tmp -= seg_q;
        tmp += 1ll * (seg_b - seg_a + 1) * (ly - 1);
      }
    }
    ans += tmp * (a[j + 1].x - a[j].x);
    i = j + 1;
  }
  printf("%lld\n", ans);
  return 0;
}
