#include <bits/stdc++.h>
using namespace std;
const int MAXN = 2e5 + 10;
int n, m, k;
vector<pair<int, int> > v[MAXN];
int te = 0;
class Edges {
 public:
  int next, to;
  int v;
};
int deg[MAXN];
int first[MAXN];
Edges edge[MAXN];
bool flag[101][101];
int Getpos(int pos, int h) { return (pos - 1) * 10 + h; }
void add(int s, int t) {
  ++te;
  edge[te].to = t;
  edge[te].next = first[s];
  first[s] = te;
}
int p[10];
int ans = 0;
bool check() {
  for (int i = 1; i <= k; ++i)
    for (int j = 1; j <= k; ++j)
      if (!flag[p[i]][p[j]]) return 0;
  return 1;
}
void dfs(int x) {
  if (x == k + 1) {
    ans += check();
    return;
  }
  for (int i = 0; i < x; ++i) {
    p[x] = Getpos(x, i);
    dfs(x + 1);
  }
}
int main() {
  scanf("%d%d%d", &n, &m, &k);
  for (int i = 1; i <= m; ++i) {
    int s, t, w;
    scanf("%d%d%d", &s, &t, &w);
    deg[s]++;
    add(t, s);
    v[s].push_back(make_pair(w, te));
  }
  for (int i = 1; i <= n; ++i) {
    sort(v[i].begin(), v[i].end());
    for (int k = 0; k < (int)v[i].size(); ++k) {
      edge[v[i][k].second].v = k;
    }
  }
  memset(flag, 1, sizeof flag);
  for (int i = 1; i <= k; ++i)
    for (int j = 0; j < i; ++j) {
      int now = Getpos(i, j);
      for (int o = 1; o <= n; ++o) {
        bool ok = 0;
        for (int e = first[o]; e; e = edge[e].next) {
          int to = edge[e].to;
          if (deg[to] == i && edge[e].v == j) ok = 1;
        }
        if (ok) {
          int sum = 0;
          for (int e = first[o]; e; e = edge[e].next) {
            int to = edge[e].to;
            if (deg[to] == i && edge[e].v == j) {
              sum++;
              continue;
            } else {
              int tmp = Getpos(deg[to], edge[e].v);
              flag[now][tmp] = 0;
            }
          }
          if (sum > 1) flag[now][now] = 0;
        }
      }
    }
  dfs(1);
  cout << ans << endl;
  return 0;
}
