#include <bits/stdc++.h>
using namespace std;
const int N = 2e3 + 10;
const int mod = 1e9 + 7;
int qpow(int a, int b) {
  int ret = 1;
  while (b) {
    if (b & 1) ret = 1ll * ret * a % mod;
    a = 1ll * a * a % mod;
    b >>= 1;
  }
  return ret;
}
int n, k, l, x[N], y[N], c[N], stx[N], tpx, sty[N], tpy, lenx[N], leny[N],
    sleny[N], mx[N << 2], se[N << 2], sum[N << 2], tag[N << 2], sumy[N << 2];
multiset<int> pos[N];
vector<int> vec[N];
void up(int x) {
  sum[x] = (sum[(x << 1)] + sum[(x << 1 | 1)]) % mod;
  mx[x] = max(mx[(x << 1)], mx[(x << 1 | 1)]);
  se[x] = max(mx[x] == mx[(x << 1)] ? se[(x << 1)] : mx[(x << 1)],
              mx[x] == mx[(x << 1 | 1)] ? se[(x << 1 | 1)] : mx[(x << 1 | 1)]);
  sumy[x] = 0;
  if (mx[x] == mx[(x << 1)]) sumy[x] = (sumy[x] + sumy[(x << 1)]) % mod;
  if (mx[x] == mx[(x << 1 | 1)]) sumy[x] = (sumy[x] + sumy[(x << 1 | 1)]) % mod;
}
void build(int x = 1, int l = 1, int r = tpy) {
  tag[x] = 0;
  if (l == r) {
    mx[x] = l + 1;
    se[x] = -1e9;
    sum[x] = 1ll * leny[l] * sleny[l + 1] % mod;
    sumy[x] = leny[l];
    return;
  }
  int mid = (l + r) >> 1;
  build((x << 1), l, mid);
  build((x << 1 | 1), mid + 1, r);
  up(x);
}
void mdf(int x, int v) {
  sum[x] = (sum[x] - 1ll * sleny[mx[x]] * sumy[x]) % mod;
  if (sum[x] < 0) sum[x] += mod;
  mx[x] += v;
  tag[x] += v;
  sum[x] = (sum[x] + 1ll * sleny[mx[x]] * sumy[x]) % mod;
}
void down(int x) {
  if (tag[x]) {
    int tmp = max(mx[(x << 1)], mx[(x << 1 | 1)]);
    if (mx[(x << 1)] == tmp) mdf((x << 1), tag[x]);
    if (mx[(x << 1 | 1)] == tmp) mdf((x << 1 | 1), tag[x]);
    tag[x] = 0;
  }
}
void modify(int L, int R, int v, int x = 1, int l = 1, int r = tpy) {
  if (L > R || mx[x] <= v) return;
  if (L <= l && r <= R && se[x] < v) return mdf(x, v - mx[x]);
  down(x);
  int mid = (l + r) >> 1;
  if (L <= mid) modify(L, R, v, (x << 1), l, mid);
  if (R > mid) modify(L, R, v, (x << 1 | 1), mid + 1, r);
  up(x);
}
void print(int x = 1, int l = 1, int r = tpy) {
  if (l == r) {
    cerr << mx[x] << ' ';
    return;
  }
  down(x);
  int mid = (l + r) >> 1;
  print((x << 1), l, mid);
  print((x << 1 | 1), mid + 1, r);
}
int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  cin >> n >> k >> l;
  for (int i = 1; i <= n; i++) {
    cin >> x[i] >> y[i] >> c[i];
    stx[++tpx] = x[i];
    sty[++tpy] = y[i];
  }
  stx[++tpx] = sty[++tpy] = l;
  sort(stx + 1, stx + tpx + 1);
  tpx = unique(stx + 1, stx + tpx + 1) - stx - 1;
  sort(sty + 1, sty + tpy + 1);
  tpy = unique(sty + 1, sty + tpy + 1) - sty - 1;
  stx[0] = sty[0] = -1;
  for (int i = 0; i < tpx; i++) lenx[i] = stx[i + 1] - stx[i];
  for (int i = 0; i < tpy; i++) leny[i] = sty[i + 1] - sty[i];
  for (int i = 1; i <= n; i++) {
    x[i] = lower_bound(stx + 1, stx + tpx + 1, x[i]) - stx;
    y[i] = lower_bound(sty + 1, sty + tpy + 1, y[i]) - sty;
    vec[x[i]].push_back(i);
  }
  --tpx;
  --tpy;
  for (int i = 1; i <= tpy + 5; i++) {
    sleny[i] = (sleny[i - 1] + (i - 2 >= 0 ? leny[i - 2] : 0)) % mod;
  }
  int ans = 0;
  for (int i = 1; i <= tpx; i++) {
    for (int j = 1; j <= k; j++) {
      pos[j].clear();
      pos[j].insert(0);
      pos[j].insert(tpy + 1);
    }
    for (int j = i; j <= tpx; j++)
      for (auto id : vec[j]) pos[c[id]].insert(y[id]);
    build();
    for (int j = 1; j <= k; j++) {
      auto it = pos[j].begin();
      while (1) {
        auto nxt = it;
        ++nxt;
        if (nxt == pos[j].end()) break;
        modify(*it + 1, *nxt - 1, *it + 1);
        it = nxt;
      }
    }
    for (int j = tpx; j >= i; j--) {
      ans = (ans + 1ll * lenx[i - 1] * lenx[j] % mod * sum[1]) % mod;
      for (auto id : vec[j]) {
        auto it = pos[c[id]].lower_bound(y[id]);
        auto pre = it, nxt = it;
        --pre;
        ++nxt;
        pos[c[id]].erase(it);
        modify(*pre + 1, *nxt - 1, *pre + 1);
      }
    }
  }
  cout << ans;
  return 0;
}
