#include <bits/stdc++.h>
using namespace std;
const int P = 1e9 + 7;
int n, k;
int A[200306];
int x[200306], y[200306], w[200306];
vector<int> X, Y;
int fa[200306], second[200306], sz[200306];
int find(int x) { return x == fa[x] ? x : fa[x] = find(fa[x]); }
inline void Inc(int& x, int y) { x = (x + y > P ? x + y - P : x + y); }
vector<pair<int, int>> G[200306];
vector<int> nl, nr;
int bc[200306];
int as[106];
namespace lsjtxdy {
int dp[106][1 << 16 | 66];
void wkr() {
  int sl = nl.size(), sr = nr.size();
  for (int i = (0), iend = (sl + sr); i <= iend; ++i)
    for (int j = (0), jend = ((1 << sl) - 1); j <= jend; ++j) dp[i][j] = 0;
  for (int i = (0), iend = (sl + sr); i <= iend; ++i) as[i] = 0;
  dp[0][0] = 1;
  for (int i = (1), iend = (sr); i <= iend; ++i)
    for (int s = (0), send = ((1 << sl) - 1); s <= send; ++s) {
      Inc(dp[i][s], dp[i - 1][s]);
      int u = nr[i - 1];
      for (auto t : G[u])
        if (~s & (1 << bc[t.first])) {
          int v = t.first, w = t.second;
          int ts = s | (1 << bc[v]);
          Inc(dp[i][ts], dp[i - 1][s] * 1ll * w % P);
        }
    }
  for (int i = (0), iend = ((1 << sl) - 1); i <= iend; ++i)
    Inc(as[__builtin_popcount(i)], dp[sr][i]);
}
}  // namespace lsjtxdy
namespace zjktsdy {
vector<pair<int, pair<int, int>>> fe;
int dep[200306];
vector<pair<int, int>> g[200306];
vector<int> nd;
void dfs(int u, int f) {
  nd.push_back(u);
  dep[u] = dep[f] + 1;
  for (auto t : G[u])
    if (t.first != f) {
      if (!dep[t.first])
        dfs(t.first, u), g[u].push_back(t);
      else if (dep[t.first] > dep[u])
        fe.emplace_back(make_pair(u, t));
    }
}
int fk[200306];
int dp[106][2][52], pd[2][52], siz[106];
void afs(int u) {
  int sz = 1;
  memset(dp[u], 0, sizeof dp[u]);
  dp[u][0][0] = 1;
  for (auto t : g[u]) {
    int v = t.first;
    afs(v);
    memcpy(pd, dp[u], sizeof dp[u]);
    memset(dp[u], 0, sizeof dp[u]);
    for (int i = (0), iend = (sz); i <= iend; ++i)
      for (int j = (0), jend = (siz[v]); j <= jend; ++j) {
        Inc(dp[u][0][i + j], pd[0][i] * 1ll * (dp[v][0][j] + dp[v][1][j]) % P);
        if (!fk[u]) {
          Inc(dp[u][1][i + j],
              pd[1][i] * 1ll * (dp[v][0][j] + dp[v][1][j]) % P);
          if (!fk[v])
            Inc(dp[u][1][i + j + 1],
                pd[0][i] * 1ll * dp[v][0][j] % P * t.second % P);
        }
      }
    sz += siz[v];
  }
  siz[u] = sz;
}
void wkr(int r) {
  nd.clear();
  for (int i = (0), iend = (k * 2); i <= iend; ++i)
    as[i] = dep[i] = 0, g[i].clear();
  fe.clear();
  dfs(r, r);
  int ta = 0, ts = 1;
  for (int s = 0; s < (1 << fe.size()); ++s) {
    for (int x : nd) fk[x] = 0;
    ta = __builtin_popcount(s), ts = 1;
    for (int i = (0), iend = (fe.size() - 1); i <= iend; ++i)
      if (s & (1 << i)) {
        int u = fe[i].first, v = fe[i].second.first;
        if (fk[u] || fk[v]) {
          ts = 0;
          break;
        }
        ts = ts * 1ll * fe[i].second.second % P, fk[u] = fk[v] = 1;
      }
    if (!ts) continue;
    afs(r);
    for (int i = (0), iend = (k); i <= iend; ++i)
      Inc(as[i + ta], (dp[r][0][i] + dp[r][1][i]) * 1ll * ts % P);
  }
}
}  // namespace zjktsdy
int ans[105], pas[105];
int J[100006];
void solve() {
  cin >> n >> k;
  J[0] = 1;
  for (int i = (1), iend = (n); i <= iend; ++i) J[i] = J[i - 1] * 1ll * i % P;
  for (int i = (1), iend = (k); i <= iend; ++i) {
    scanf("%d%d%d", x + i, y + i, w + i);
    --w[i];
    X.push_back(x[i]), Y.push_back(y[i]);
  }
  sort((X).begin(), (X).end()), sort((Y).begin(), (Y).end());
  X.erase(unique((X).begin(), (X).end()), X.end()),
      Y.erase(unique((Y).begin(), (Y).end()), Y.end());
  for (int i = (1), iend = (k); i <= iend; ++i)
    x[i] = lower_bound((X).begin(), (X).end(), x[i]) - X.begin() + 1,
    y[i] = lower_bound((Y).begin(), (Y).end(), y[i]) - Y.begin() + 1;
  int sx = X.size(), sy = Y.size();
  for (int i = (1), iend = (k); i <= iend; ++i) {
    G[x[i]].emplace_back(make_pair(y[i] + sx, w[i]));
    G[y[i] + sx].emplace_back(make_pair(x[i], w[i]));
  }
  for (int i = (1), iend = (sx + sy); i <= iend; ++i) sz[i] = 1, fa[i] = i;
  for (int i = (1), iend = (k); i <= iend; ++i) {
    int u = find(x[i]), v = find(y[i] + sx);
    ++second[v];
    if (u == v) continue;
    fa[u] = v, sz[v] += sz[u], second[v] += second[u];
  }
  ans[0] = 1;
  for (int i = (1), iend = (sx + sy); i <= iend; ++i)
    if (fa[i] == i && sz[i] > 1) {
      if (sz[i] <= 2 * second[i] / 3) {
        nl.clear(), nr.clear();
        for (int j = (1), jend = (sx); j <= jend; ++j)
          if (find(j) == i) nl.push_back(j), bc[j] = nl.size() - 1;
        for (int j = (sx + 1), jend = (sx + sy); j <= jend; ++j)
          if (find(j) == i) nr.push_back(j), bc[j] = nr.size() - 1;
        if (nl.size() > nr.size()) swap(nl, nr);
        lsjtxdy::wkr();
      } else {
        zjktsdy::wkr(i);
      }
      memcpy(pas, ans, sizeof ans);
      memset(ans, 0, sizeof ans);
      for (int i = (0), iend = (k); i <= iend; ++i)
        if (as[i])
          for (int j = (i), jend = (k); j <= jend; ++j)
            Inc(ans[j], as[i] * 1ll * pas[j - i] % P);
    }
  int res = 0;
  for (int i = (0), iend = (k); i <= iend; ++i)
    Inc(res, ans[i] * 1ll * J[n - i] % P);
  cout << res << endl;
}
signed main() { solve(); }
