#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int MOD = 1000000007;
int L;
ll sum[8040];
int len[8040];
int last[8040];
int lazy[8040];
void init(int v, int l, int r, const vector<int> &xs) {
  len[v] = xs[r] - xs[l - 1];
  if (l < r) {
    int md = (l + r) >> 1;
    init(v << 1, l, md, xs);
    init(v << 1 | 1, md + 1, r, xs);
  }
}
void reset(int v, int l, int r, const vector<int> &go) {
  lazy[v] = -1;
  if (l == r) {
    sum[v] = ll(len[v]) * (L - go[l]);
    last[v] = go[l];
    return;
  }
  int md = (l + r) >> 1;
  reset(v << 1, l, md, go);
  reset(v << 1 | 1, md + 1, r, go);
  sum[v] = sum[v << 1] + sum[v << 1 | 1];
  last[v] = last[v << 1 | 1];
}
void push(int v, int l, int r) {
  if (lazy[v] != -1) {
    last[v] = lazy[v];
    sum[v] = ll(len[v]) * (L - lazy[v]);
    if (l < r) {
      lazy[v << 1] = lazy[v];
      lazy[v << 1 | 1] = lazy[v];
    }
    lazy[v] = -1;
  }
}
void modify(int v, int l, int r, int L, int R, int qv) {
  push(v, l, r);
  if (L > r || R < l) return;
  if (L <= l && r <= R) {
    lazy[v] = qv;
    push(v, l, r);
    return;
  }
  int md = (l + r) >> 1;
  modify(v << 1, l, md, L, R, qv);
  modify(v << 1 | 1, md + 1, r, L, R, qv);
  sum[v] = sum[v << 1] + sum[v << 1 | 1];
  last[v] = last[v << 1 | 1];
}
int walk(int v, int l, int r, int qv) {
  push(v, l, r);
  if (last[v] <= qv) return -1;
  if (l == r) return l;
  int md = (l + r) >> 1;
  int ans = walk(v << 1, l, md, qv);
  if (ans == -1) ans = walk(v << 1 | 1, md + 1, r, qv);
  return ans;
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  int N, K;
  cin >> N >> K >> L;
  vector<int> X(N), Y(N), C(N);
  vector<int> xs = {-1, L};
  vector<int> ys = {-1, L};
  for (int i = 0; i < N; ++i) {
    cin >> X[i] >> Y[i] >> C[i];
    --C[i];
    xs.emplace_back(X[i]);
    ys.emplace_back(Y[i]);
  }
  sort(xs.begin(), xs.end());
  xs.resize(unique(xs.begin(), xs.end()) - xs.begin());
  sort(ys.begin(), ys.end());
  ys.resize(unique(ys.begin(), ys.end()) - ys.begin());
  int NX = xs.size();
  int NY = ys.size();
  {
    vector<int> order(N);
    iota(order.begin(), order.end(), 0);
    sort(order.begin(), order.end(), [&](int i, int j) {
      return make_pair(Y[i], -X[i]) > make_pair(Y[j], -X[j]);
    });
    vector<int> newX(N), newY(N), newC(N);
    for (int i = 0; i < N; ++i) {
      newX[i] = X[order[i]];
      newY[i] = Y[order[i]];
      newC[i] = C[order[i]];
    }
    X.swap(newX), Y.swap(newY), C.swap(newC);
  }
  init(1, 1, NX - 2, xs);
  int ans = 0;
  for (int yr = 1; yr + 1 < NY; ++yr) {
    vector<vector<int>> addAt(NX);
    for (int i = 0; i < N; ++i) {
      if (Y[i] <= ys[yr]) {
        int xi = lower_bound(xs.begin(), xs.end(), X[i]) - xs.begin();
        addAt[xi].emplace_back(C[i]);
      }
    }
    int bad = K;
    vector<int> cnts(K);
    auto inc = [&](int z) {
      if (++cnts[z] == 1) --bad;
    };
    auto dec = [&](int z) {
      if (--cnts[z] == 0) ++bad;
    };
    vector<int> go(NX);
    int ptr = 0;
    for (int i = 1; i + 1 < NX; ++i) {
      while (bad && ptr + 2 < NX) {
        ptr++;
        for (int z : addAt[ptr]) inc(z);
      }
      if (bad)
        go[i] = L;
      else
        go[i] = xs[ptr];
      for (int z : addAt[i]) dec(z);
    }
    reset(1, 1, NX - 2, go);
    vector<int> prv(N);
    vector<int> nxt(N);
    vector<map<int, int>> mp(K);
    for (int i = 0; i < N; ++i) {
      if (Y[i] <= ys[yr]) {
        auto it = mp[C[i]].lower_bound(X[i]);
        if (it == mp[C[i]].end()) {
          nxt[i] = -1;
        } else {
          nxt[i] = it->second;
        }
        it = mp[C[i]].upper_bound(X[i]);
        if (it == mp[C[i]].begin()) {
          prv[i] = -1;
        } else {
          prv[i] = prev(it)->second;
        }
        mp[C[i]][X[i]] = i;
      }
    }
    auto remove = [&](int i) {
      int xprv = (prv[i] == -1 ? -1 : X[prv[i]]);
      int xcur = X[i];
      int xnxt = (nxt[i] == -1 ? L : X[nxt[i]]);
      int l = lower_bound(xs.begin(), xs.end(), xprv) - xs.begin() + 1;
      int r = walk(1, 1, NX - 2, xnxt);
      if (r == -1) r = NX - 1;
      --r;
      r = min(r, int(lower_bound(xs.begin(), xs.end(), xcur) - xs.begin()));
      if (l <= r) modify(1, 1, NX - 2, l, r, xnxt);
    };
    ptr = N - 1;
    for (int yl = 1; yl <= yr; ++yl) {
      ll add = sum[1] % MOD * (ys[yr + 1] - ys[yr]) % MOD *
               (ys[yl] - ys[yl - 1]) % MOD;
      ans = (ans + add) % MOD;
      while (ptr >= 0 && Y[ptr] == ys[yl]) remove(ptr--);
    }
    assert(sum[1] == 0);
  }
  cout << ans << "\n";
  return 0;
}
