#include <bits/stdc++.h>
using namespace std;
int const N = 2000, md = 1e9 + 7, inf = md;
int n, k, L, an;
vector<int> xv;
multiset<int> xk[N + 1];
void ad(int &x, int y) {
  if ((x += y) >= md) x -= md;
}
struct S {
  int mn, mx, z;
  long long sm, dx;
  S() {}
  S(int v) : mn(inf), mx(inf), z(-1), sm(0), dx(v) {}
  S operator+(S const &o) const {
    S an;
    an.mn = min(mn, o.mn);
    an.mx = max(mx, o.mx);
    an.z = -1;
    an.sm = sm + o.sm;
    an.dx = dx + o.dx;
    return an;
  }
  void st(int v) {
    z = v;
    mn = v;
    mx = v;
    sm = v * dx;
  }
} s[N << 2];
void bld(int l = 0, int r = xv.size() - 1, int id = 1) {
  if (l == r) {
    s[id] = S(l + 1 == (int)xv.size() ? 0 : xv[l + 1] - xv[l]);
    return;
  }
  int m = l + r >> 1, a = id << 1, b = a | 1;
  bld(l, m, a);
  bld(m + 1, r, b);
  s[id] = s[a] + s[b];
}
void slp(int id, int a, int b) {
  if (s[id].z == -1) return;
  s[a].st(s[id].z);
  s[b].st(s[id].z);
  s[id].z = -1;
}
void upmn(int x, int y, int v, int l = 0, int r = xv.size() - 1, int id = 1) {
  if (l > y || r < x || s[id].mx <= v) return;
  if (l >= x && r <= y && s[id].mn >= v) {
    s[id].st(v);
    return;
  }
  int m = l + r >> 1, a = id << 1, b = a | 1;
  slp(id, a, b);
  upmn(x, y, v, l, m, a);
  upmn(x, y, v, m + 1, r, b);
  s[id] = s[a] + s[b];
}
struct P {
  int x, y, c;
  P() {}
  P(int a, int b, int d) : x(a), y(b), c(d) {}
  void sc() {
    scanf("%d%d%d", &x, &y, &c);
    ++x;
    ++y;
  }
} p[N];
vector<P> cp;
bool cmpx(P const &a, P const &b) { return a.x < b.x; }
bool cmpy(P const &a, P const &b) { return a.y < b.y; }
int gtid(int v) { return lower_bound(xv.begin(), xv.end(), v) - xv.begin(); }
int go() {
  sort(cp.begin(), cp.end(), cmpx);
  xv.resize(cp.size());
  for (int i = 0; i < (int)(cp.size()); ++i) xv[i] = cp[i].x;
  xv.resize(unique(xv.begin(), xv.end()) - xv.begin());
  bld();
  multiset<int> st;
  for (int i = 0; i < (int)(k); ++i) st.insert(0);
  for (int i = 1; i < (int)(k + 1); ++i) xk[i].clear();
  for (int i = 0; i < (int)(cp.size()); ++i) {
    int j = i;
    while (j < (int)cp.size() && cp[j].x == cp[i].x) {
      int c = cp[j].c;
      st.erase(st.find(xk[c].empty() ? 0 : *xk[c].rbegin()));
      xk[c].insert(cp[j].x);
      st.insert(cp[j].x);
      ++j;
    }
    int t = gtid(cp[i].x);
    upmn(t, t, *st.begin());
    i = j - 1;
  }
  sort(cp.begin(), cp.end(), cmpy);
  int an = s[1].sm % md * cp[0].y % md;
  for (int i = 0; i < (int)(cp.size()); ++i)
    if (cp[i].x <= L) {
      int j = i;
      while (j < (int)cp.size() && cp[j].y == cp[i].y) {
        auto it = xk[cp[j].c].lower_bound(cp[j].x);
        int l = gtid(cp[j].x), r = gtid(*(++it));
        --it;
        int v = it == xk[cp[j].c].begin() ? 0 : *(--it);
        xk[cp[j].c].erase(xk[cp[j].c].lower_bound(cp[j].x));
        upmn(l, r - 1, v);
        ++j;
      }
      ad(an, s[1].sm % md *
                 ((j == (int)cp.size() ? L + 1 : cp[j].y) - cp[j - 1].y) % md);
      i = j - 1;
    }
  return an;
}
int main() {
  scanf("%d%d%d", &n, &k, &L);
  for (int i = 0; i < (int)(n); ++i) p[i].sc();
  sort(p, p + n, cmpy);
  for (int i = 1; i < (int)(k + 1); ++i) cp.emplace_back(L + 1, L + 1, i);
  int uy = -1;
  while (uy + 1 < n) {
    ++uy;
    int t = uy;
    while (t + 1 < n && p[t + 1].y == p[t].y) ++t;
    for (int i = uy; i < (int)(t + 1); ++i) cp.push_back(p[i]);
    ad(an, (long long)go() * ((t + 1 == n ? L + 1 : p[t + 1].y) - p[t].y) % md);
    uy = t;
  }
  printf("%d\n", an);
}
