#include <bits/stdc++.h>
using namespace std;
const int N = 2005;
const int MOD = 1e9 + 7;
int n, m, L, nx, ny, SZ, ans;
int X[N], Y[N], C[N], numx[N], numy[N], tc[N][N];
map<int, int> mpx, mpy;
set<int> st[N];
vector<int> era[N];
int v[N * 2], sz[N * 2], lson[N * 2], rson[N * 2], mn1[N * 2], mnc[N * 2],
    mn2[N * 2], mxt[N * 2], sum[N * 2];
void update(int pos) {
  sum[pos] = (sum[lson[pos]] + sum[rson[pos]]) % MOD;
  if (mn1[lson[pos]] == mn1[rson[pos]]) {
    mn1[pos] = mn1[lson[pos]];
    mnc[pos] = (mnc[lson[pos]] + mnc[rson[pos]]) % MOD;
    mn2[pos] = min(mn2[lson[pos]], mn2[rson[pos]]);
  } else if (mn1[lson[pos]] > mn1[rson[pos]]) {
    mn1[pos] = mn1[rson[pos]];
    mnc[pos] = mnc[rson[pos]];
    mn2[pos] = min(mn1[lson[pos]], mn2[rson[pos]]);
  } else {
    mn1[pos] = mn1[lson[pos]];
    mnc[pos] = mnc[lson[pos]];
    mn2[pos] = min(mn2[lson[pos]], mn1[rson[pos]]);
  }
}
void chmax(int pos, int vl) {
  if (vl <= mn1[pos]) return;
  sum[pos] = (sum[pos] + 1ll * (vl - mn1[pos]) * mnc[pos] % MOD) % MOD;
  mn1[pos] = mxt[pos] = vl;
}
void pushdown(int pos) {
  chmax(lson[pos], mxt[pos]);
  chmax(rson[pos], mxt[pos]);
  mxt[pos] = 0;
}
void build(int pos, int x, int y) {
  sum[pos] = 0;
  mn1[pos] = 0;
  mnc[pos] = sz[pos] = numy[y] - numy[x - 1];
  mn2[pos] = 2000000000;
  mxt[pos] = 0;
  if (x == y) return;
  int mid = (x + y) >> 1;
  lson[pos] = ++SZ;
  rson[pos] = ++SZ;
  build(lson[pos], x, mid);
  build(rson[pos], mid + 1, y);
  update(pos);
}
void modify(int pos, int x, int y, int l, int r, int vl) {
  if (x > r || y < l) return;
  if (x >= l && y <= r) {
    if (vl <= mn1[pos]) return;
    if (mn1[pos] < vl && vl < mn2[pos]) {
      chmax(pos, vl);
      return;
    }
  }
  pushdown(pos);
  int mid = (x + y) >> 1;
  modify(lson[pos], x, mid, l, r, vl);
  modify(rson[pos], mid + 1, y, l, r, vl);
  update(pos);
}
int main() {
  scanf("%d%d%d", &n, &m, &L);
  for (int i = 1; i <= n; i++) {
    scanf("%d%d%d", X + i, Y + i, C + i);
    X[i]++;
    Y[i]++;
    mpx[X[i]];
    mpy[Y[i]];
  }
  for (map<int, int>::iterator it = mpx.begin(); it != mpx.end(); it++)
    numx[it->second = ++nx] = it->first;
  for (map<int, int>::iterator it = mpy.begin(); it != mpy.end(); it++)
    numy[it->second = ++ny] = it->first;
  for (int i = 1; i <= n; i++) X[i] = mpx[X[i]];
  for (int i = 1; i <= n; i++) Y[i] = mpy[Y[i]];
  numx[nx + 1] = numy[ny + 1] = L + 1;
  for (int i = 1; i <= nx; i++) {
    for (int j = 1; j <= nx; j++) era[j].clear();
    for (int j = 1; j <= m; j++) {
      st[j].clear();
      st[j].insert(ny + 1);
    }
    for (int j = 1; j <= n; j++)
      if (X[j] >= i) {
        st[C[j]].insert(Y[j]);
        tc[C[j]][Y[j]]++;
        era[X[j]].push_back(j);
      }
    SZ = 1;
    build(1, 1, ny + 1);
    for (int j = 1; j <= m; j++) {
      modify(1, 1, ny + 1, 1, *st[j].begin(), numy[*st[j].begin()]);
      for (set<int>::iterator it = st[j].begin(); it != st[j].end(); it++) {
        set<int>::iterator nit = it;
        nit++;
        if (nit != st[j].end()) {
          modify(1, 1, ny + 1, (*it) + 1, *nit, numy[*nit]);
        }
      }
    }
    for (int j = nx; j >= i; j--) {
      ans = (ans + 1ll * (1ll * (L + 1) * (L + 1) % MOD - sum[1] + MOD) % MOD *
                       (numx[j + 1] - numx[j]) % MOD * (numx[i] - numx[i - 1]) %
                       MOD) %
            MOD;
      for (int k = 0; k < int(era[j].size()); k++) {
        int x = era[j][k];
        tc[C[x]][Y[x]]--;
        if (!tc[C[x]][Y[x]]) {
          int vl;
          set<int>::iterator it = st[C[x]].find(Y[x]);
          it++;
          vl = numy[*it];
          it--;
          if (it == st[C[x]].begin()) {
            modify(1, 1, ny + 1, 1, Y[x], vl);
          } else {
            it--;
            modify(1, 1, ny + 1, (*it) + 1, Y[x], vl);
          }
          st[C[x]].erase(Y[x]);
        }
      }
    }
  }
  printf("%d\n", ans);
  return 0;
}
