#include <bits/stdc++.h>
using namespace std;
const int N = 2e3 + 10, P = 1e9 + 7;
int n, k, L, nxt[N], cnt[N], pos[N];
set<int> s[N];
struct _ {
  int x, y, c, id;
} a[N], b[N];
bool cmpx(_ a, _ b) { return a.x < b.x; }
bool cmpy(_ a, _ b) { return a.y < b.y; }
struct {
  int sum[N << 2], mi[N << 2], ma[N << 2], tag[N << 2];
  void upd(int o, int l, int r, int v) {
    tag[o] = mi[o] = ma[o] = v;
    sum[o] = (int64_t)(L - b[v].y) * (b[r].y - b[l - 1].y) % P;
  }
  void pu(int o) {
    sum[o] = (sum[o << 1] + sum[o << 1 | 1]) % P;
    mi[o] = min(mi[o << 1], mi[o << 1 | 1]);
    ma[o] = max(ma[o << 1], ma[o << 1 | 1]);
  }
  void pd(int o, int l, int r) {
    if (tag[o] != -1) {
      int mid = (l + r) / 2;
      upd(o << 1, l, mid, tag[o]);
      upd(o << 1 | 1, mid + 1, r, tag[o]);
      tag[o] = -1;
    }
  }
  void build(int o, int l, int r) {
    tag[o] = -1;
    if (l == r) return upd(o, l, l, nxt[l]);
    int mid = (l + r) / 2;
    build(o << 1, l, mid), build(o << 1 | 1, mid + 1, r);
    pu(o);
  }
  void update(int o, int l, int r, int ql, int qr, int v) {
    if (mi[o] >= v) return;
    if (ql <= l && r <= qr && ma[o] <= v) return upd(o, l, r, v);
    pd(o, l, r);
    int mid = (l + r) / 2;
    if (mid >= ql) update(o << 1, l, mid, ql, qr, v);
    if (mid < qr) update(o << 1 | 1, mid + 1, r, ql, qr, v);
    pu(o);
  }
} sgt;
int main() {
  scanf("%d%d%d", &n, &k, &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 + 1 + n, cmpx);
  a[0].x = -1, a[n + 1].x = L;
  int ans = 0;
  for (int i = k; i <= n; ++i) {
    int len = a[i + 1].x - a[i].x;
    if (!len) continue;
    for (int j = 1; j <= i; ++j) {
      b[j] = a[j];
      b[j].id = j;
    }
    sort(b + 1, b + 1 + i, cmpy);
    for (int j = 1; j <= i; ++j) {
      nxt[j] = i + 1;
      pos[b[j].id] = j;
      s[b[j].c].insert(j);
    }
    for (int j = 1, now = 1, cur = 0; j <= i; ++j) {
      while (now <= i && cur < k) {
        if (!cnt[b[now++].c]++) ++cur;
      }
      if (cur == k) nxt[j] = now - 1;
      if (!--cnt[b[j].c]) --cur;
    }
    b[0].y = -1, b[i + 1].y = L;
    sgt.build(1, 1, i);
    int res = 0;
    for (int j = 1; j <= i; ++j) {
      int len2 = a[j].x - a[j - 1].x;
      res = (res + (int64_t)len2 * sgt.sum[1]) % P;
      auto p = s[a[j].c].lower_bound(pos[j]);
      int l = p == s[a[j].c].begin() ? 0 : *prev(p);
      int r = next(p) == s[a[j].c].end() ? i + 1 : *next(p);
      s[a[j].c].erase(p);
      sgt.update(1, 1, i, l + 1, pos[j], r);
    }
    ans = (ans + (int64_t)res * len) % P;
  }
  printf("%d\n", ans);
}
