#include <bits/stdc++.h>
using namespace std;
const int MAXN = (int)2e3 + 5;
const int MOD = (int)1e9 + 7;
set<int> colorCells[MAXN];
vector<int> cellColors[MAXN], vx, vy;
array<int, 3> pts[MAXN];
vector<pair<int, int> > V[MAXN];
int occ[MAXN][MAXN];
int T[MAXN];
int n, k, m, X, Y;
int addMod(int a, int b, int m = MOD) {
  a += b;
  if (m <= a) {
    a -= m;
  }
  return a;
}
int mulMod(int a, int b, int m = MOD) { return a * 1ll * b % m; }
void compress() {
  vx.push_back(-1);
  vy.push_back(-1);
  vx.push_back(m);
  vy.push_back(m);
  for (int i = 1; i <= n; ++i) {
    vx.push_back(pts[i][0]);
    vy.push_back(pts[i][1]);
  }
  sort((vx).begin(), (vx).end());
  sort((vy).begin(), (vy).end());
  vx.resize(unique((vx).begin(), (vx).end()) - vx.begin());
  vy.resize(unique((vy).begin(), (vy).end()) - vy.begin());
  X = (int)vx.size();
  Y = (int)vy.size();
  for (int i = 1; i <= n; ++i) {
    pts[i][0] = lower_bound((vx).begin(), (vx).end(), pts[i][0]) - vx.begin();
    pts[i][1] = lower_bound((vy).begin(), (vy).end(), pts[i][1]) - vy.begin();
  }
}
namespace Window {
int cnt[MAXN];
int distinct;
void init() {
  fill(cnt, cnt + k, 0);
  distinct = 0;
}
void add(int x) {
  if (cnt[x]++ == 0) {
    distinct++;
  }
}
void del(int x) {
  if (--cnt[x] == 0) {
    distinct--;
  }
}
bool good() { return distinct == k; }
};  // namespace Window
namespace Magic {
int L[MAXN][MAXN], R[MAXN][MAXN];
int t[MAXN << 2], ext[MAXN << 2], mn[MAXN << 2], mx[MAXN << 2];
int cnt[MAXN][MAXN];
int arr[MAXN];
int totalSum;
void build(int v, int tl, int tr) {
  ext[v] = -1;
  if (tl == tr) {
    t[v] = mulMod(vy[tl] - vy[tl - 1], m - vy[arr[tl]]);
    mn[v] = mx[v] = arr[tl];
    return;
  }
  int mid = (tl + tr) >> 1;
  int c1 = (v << 1), c2 = (c1 | 1);
  build(c1, tl, mid);
  build(c2, mid + 1, tr);
  t[v] = addMod(t[c1], t[c2]);
  mx[v] = max(mx[c1], mx[c2]);
  mn[v] = min(mn[c1], mn[c2]);
}
void push(int v, int tl, int tr) {
  if (ext[v] != -1) {
    t[v] = mulMod(vy[tr] - vy[tl - 1], m - vy[ext[v]]);
    mn[v] = mx[v] = ext[v];
    if (tl != tr) {
      int c1 = (v << 1), c2 = (c1 | 1);
      ext[c1] = ext[c2] = ext[v];
    }
    ext[v] = -1;
  }
}
void update(int v, int tl, int tr, int l, int r, int x) {
  push(v, tl, tr);
  if (l > r || tl > r || tr < l || mn[v] >= x) {
    return;
  }
  if (l <= tl && tr <= r && mx[v] < x) {
    ext[v] = x;
    push(v, tl, tr);
    return;
  }
  int mid = (tl + tr) >> 1;
  int c1 = (v << 1), c2 = (c1 | 1);
  update(c1, tl, mid, l, r, x);
  update(c2, mid + 1, tr, l, r, x);
  t[v] = addMod(t[c1], t[c2]);
  mx[v] = max(mx[c1], mx[c2]);
  mn[v] = min(mn[c1], mn[c2]);
}
void init() {
  build(1, 1, Y);
  for (int col = 0; col < k; ++col) {
    for (auto it = colorCells[col].begin(); it != colorCells[col].end(); it++) {
      int cur = *it;
      int prv = (it == colorCells[col].begin() ? 0 : *prev(it));
      int nxt = (next(it) == colorCells[col].end() ? Y + 1 : *next(it));
      L[col][cur] = prv;
      R[col][cur] = nxt;
      cnt[col][cur] = occ[cur][col];
    }
  }
}
void del(int col, int idx) {
  if (--cnt[col][idx] == 0) {
    int prv = L[col][idx];
    int nxt = R[col][idx];
    update(1, 1, Y, prv + 1, idx, nxt);
    R[col][prv] = nxt;
    L[col][nxt] = prv;
  }
}
int get() {
  push(1, 1, Y);
  return t[1];
}
};  // namespace Magic
void solve() {
  scanf("%d %d %d", &n, &k, &m);
  for (int i = 1; i <= n; ++i) {
    int x, y, c;
    scanf("%d %d %d", &x, &y, &c);
    pts[i] = {x, y, c - 1};
  }
  compress();
  int ans = 0;
  X -= 2;
  Y -= 2;
  for (int i = 1; i <= n; ++i) {
    V[pts[i][0]].emplace_back(pts[i][1], pts[i][2]);
  }
  for (int x1 = X; x1; --x1) {
    for (auto &[y, col] : V[x1]) {
      if (occ[y][col]++ == 0) {
        cellColors[y].push_back(col);
        colorCells[col].insert(y);
      }
    }
    Window::init();
    for (int l = 1, r = 0; l <= Y; ++l) {
      while (r <= Y && !Window::good()) {
        ++r;
        for (int x : cellColors[r]) {
          Window::add(x);
        }
      }
      Magic::arr[l] = r;
      for (int x : cellColors[l]) {
        Window::del(x);
      }
    }
    Magic::init();
    for (int x2 = X; x2 >= x1; --x2) {
      int cur = mulMod(vx[x1] - vx[x1 - 1], vx[x2 + 1] - vx[x2]);
      cur = mulMod(cur, Magic::get());
      ans = addMod(ans, cur);
      for (auto &[y, col] : V[x2]) {
        Magic::del(col, y);
      }
    }
  }
  printf("%d\n", ans);
}
int main() {
  int tt = 1;
  while (tt--) {
    solve();
  }
  return 0;
}
