#include <bits/stdc++.h>
using namespace std;
const int mod = 1e9 + 7;
const int maxn = 2050;
struct node {
  int mn, mx, mk;
  long long s;
  node(int a = 0, int b = 0, long long c = 0ll, int d = 0) {
    mn = a;
    mx = b;
    s = c;
    mk = d;
  }
  node operator+(node b) const {
    return node(min(mn, b.mn), max(mx, b.mx), (long long)(s + b.s) % mod, 0);
  }
} tr[maxn << 1];
struct node1 {
  int l[maxn], r[maxn];
  void del(int x) {
    l[r[x]] = l[x];
    r[l[x]] = r[x];
  }
} nq, q;
struct node2 {
  int x, y, c, i;
} a[maxn];
bool cmpy(node2 a, node2 b) { return a.y < b.y; }
bool cmpx(node2 a, node2 b) { return a.x < b.x; }
int n, m, L;
int ys[maxn], f[maxn], last[maxn], col[maxn], vis[maxn];
void upd(int rt, int l, int r, long long t) {
  tr[rt] = node(t, t, 1ll * (ys[r] - ys[l - 1]) * t % mod, t);
}
void build(int l, int r, int rt) {
  if (l == r) {
    upd(rt, l, r, f[l]);
    return;
  }
  int mid = (l + r) >> 1;
  build(l, mid, rt << 1);
  build(mid + 1, r, rt << 1 | 1);
  tr[rt] = tr[rt << 1] + tr[rt << 1 | 1];
}
void change(int L, long long t, int l, int r, int rt) {
  if (tr[rt].mn >= t) return;
  if (tr[rt].mx <= t && l == L) {
    upd(rt, l, r, t);
    return;
  }
  int mid = (l + r) >> 1;
  if (tr[rt].mk) {
    upd(rt << 1, l, mid, tr[rt].mk);
    upd(rt << 1 | 1, mid + 1, r, tr[rt].mk);
    tr[rt].mk = 0;
  }
  if (L <= mid) change(L, t, l, mid, rt << 1);
  change(max(L, mid + 1), t, mid + 1, r, rt << 1 | 1);
  tr[rt] = tr[rt << 1] + tr[rt << 1 | 1];
}
int main() {
  scanf("%d%d%d", &n, &m, &L);
  for (int i = 1; i <= n; ++i) scanf("%d%d%d", &a[i].x, &a[i].y, &a[i].c);
  sort(a + 1, a + n + 1, cmpy);
  a[0].x = a[0].y = -1;
  a[n + 1].x = a[n + 1].y = L;
  for (int i = 0; i <= n + 1; ++i) ys[i] = a[i].y, a[i].i = i;
  for (int i = 1; i <= n; ++i) {
    int l = nq.l[i] = last[a[i].c];
    last[a[i].c] = i;
    nq.r[i] = n + 1;
    nq.r[l] = i;
  }
  sort(a + 1, a + n + 1, cmpx);
  long long ans = 0;
  for (int i = 1; i <= n; ++i) {
    if (a[i].x ^ a[i - 1].x) {
      for (int j = 1; j < i; ++j) col[a[j].i] = 0;
      for (int j = i; j <= n; ++j) col[a[j].i] = a[j].c;
      int tot = 0;
      for (int l = 1, r = 1; l <= n; ++l) {
        for (; r <= n && tot < m; ++r)
          if (col[r] && !vis[col[r]]++) ++tot;
        f[l] = (tot < m) ? L : ys[r - 1];
        if (col[l] && !--vis[col[l]]) --tot;
      }
      q = nq;
      build(1, n, 1);
      for (int j = n; j >= i; --j) {
        ans += ((1ll * (ys[n] + 1) * L - tr[1].s) % mod *
                (a[i].x - a[i - 1].x) % mod * (a[j + 1].x - a[j].x)) %
               mod;
        int id = a[j].i, l = q.l[id], r = q.r[id];
        change(l + 1, ys[r], 1, n, 1);
        q.del(id);
      }
      ans %= mod;
    }
    nq.del(a[i].i);
  }
  printf("%lld\n", ans);
  return 0;
}
