#include <bits/stdc++.h>
using namespace std;
const int N = 2005, mod = 1e9 + 7;
int n, m, L;
struct P {
  int x, y, c, id;
} a[N];
int yc[N], vis[N], la[N], b[N], col[N];
inline bool cmpx(const P& x, const P& y) { return x.x < y.x; }
inline bool cmpy(const P& x, const P& y) { return x.y < y.y; }
struct List {
  int l[N], r[N];
  inline void del(int x) {
    l[r[x]] = l[x];
    r[l[x]] = r[x];
  }
} q, nq;
struct node {
  int mn, mx, s, tag;
  node(int a = 0, int b = 0, int c = 0, int d = 0) {
    mn = a, mx = b, s = c, tag = d;
  }
  node operator+(const node& b) {
    return node(min(mn, b.mn), max(mx, b.mx), (s + b.s) % mod, 0);
  }
} tr[N << 2];
inline void put_tag(int rt, int l, int r, int v) {
  tr[rt] = node(v, v, 1ll * (yc[r] - yc[l - 1]) * v % mod, v);
}
void build(int rt, int l, int r) {
  if (l == r) {
    put_tag(rt, l, r, b[l]);
    return;
  }
  int mid = (l + r) >> 1;
  build(rt << 1, l, mid);
  build(rt << 1 | 1, mid + 1, r);
  tr[rt] = tr[rt << 1] + tr[rt << 1 | 1];
}
inline void pushdown(int rt, int l, int r) {
  if (tr[rt].tag) {
    int mid = (l + r) >> 1;
    put_tag(rt << 1, l, mid, tr[rt].tag);
    put_tag(rt << 1 | 1, mid + 1, r, tr[rt].tag);
    tr[rt].tag = 0;
  }
}
void modify(int rt, int l, int r, int p, int v) {
  if (tr[rt].mn >= v) return;
  if (tr[rt].mx <= v && l >= p) {
    put_tag(rt, l, r, v);
    return;
  }
  pushdown(rt, l, r);
  int mid = (l + r) >> 1;
  if (p <= mid) modify(rt << 1, l, mid, p, v);
  modify(rt << 1 | 1, mid + 1, r, p, v);
  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++) yc[i] = a[i].y, a[i].id = i;
  for (int i = 1; i <= n; i++) {
    nq.l[i] = la[a[i].c];
    nq.r[i] = n + 1;
    nq.r[nq.l[i]] = i;
    la[a[i].c] = i;
  }
  sort(a + 1, a + n + 1, cmpx);
  int ans = 0;
  for (int i = 1; i <= n; i++) {
    if (a[i].x != a[i - 1].x) {
      memset(col, 0, sizeof(col));
      for (int j = i; j <= n; j++) col[a[j].id] = a[j].c;
      for (int l = 1, r = 1, cnt = 0; l <= n; l++) {
        for (; r <= n && cnt < m; r++) {
          if (col[r]) {
            if (!vis[col[r]]) cnt++;
            vis[col[r]]++;
          }
        }
        if (cnt < m)
          b[l] = L;
        else
          b[l] = yc[r - 1];
        if (col[l]) {
          vis[col[l]]--;
          if (!vis[col[l]]) cnt--;
        }
      }
      q = nq;
      build(1, 1, n);
      for (int j = n; j >= i; j--) {
        ans += (1ll * (yc[n] + 1) * L - tr[1].s) % mod * (a[i].x - a[i - 1].x) %
               mod * (a[j + 1].x - a[j].x) % mod;
        ans %= mod;
        int p = a[j].id;
        modify(1, 1, n, q.l[p] + 1, yc[q.r[p]]);
        q.del(p);
      }
    }
    nq.del(a[i].id);
  }
  printf("%d", ans);
  return 0;
}
