#include <bits/stdc++.h>
using ll = long long;
const int B = 18;
const int mod = 1e9 + 7;
const int maxn = 1e6 + 222;
std::vector<int> ch[maxn], E[maxn << 1];
int x[55], y[55], w[55], fac[maxn], ifac[maxn], n, k, w1, w2, f[155], g[155],
    h[155];
std::set<int> S1, S2;
int calc(int x) { return fac[n - x]; }
namespace TwilightSparkle {
int dp[(1 << B) + 17], id[maxn];
void Magic() {
  int c = 0;
  for (int x : S2) id[x] = ++c;
  std::memset(dp, 0, sizeof(dp));
  dp[0] = 1;
  for (int z : S1) {
    for (int S = (1 << c) - 1; S >= 0; --S) {
      for (int e : ch[z]) {
        int x = id[y[e]];
        if (!(S & (1 << (x - 1)))) continue;
        dp[S] = (dp[S] + (ll)dp[S - (1 << (x - 1))] * w[e] % mod) % mod;
      }
    }
    ch[z].clear();
  }
  for (int S = 0; S < (1 << c); ++S) {
    int w = __builtin_popcount(S);
    f[w] = (f[w] + dp[S]) % mod;
  }
}
}  // namespace TwilightSparkle
namespace dsu {
int fa[maxn << 1];
int getf(int x) { return fa[x] ? fa[x] = getf(fa[x]) : x; }
int merge(int x, int y) {
  x = getf(x);
  y = getf(y);
  if (x == y) return 0;
  fa[x] = y;
  return 1;
}
}  // namespace dsu
namespace StarlightGlimmer {
int vis[maxn << 1], f[55][48][2], g[48][2], id[maxn << 1], hd[100], tl,
    siz[105];
struct edge {
  int v, w, nxt;
} E[5005];
void add_edge(int u, int v, int w) {
  E[++tl].v = v;
  E[tl].w = w;
  E[tl].nxt = hd[u];
  hd[u] = tl;
}
void dfs(int u, int fa) {
  f[u][0][0] = 1;
  siz[u] = 1;
  for (int i = hd[u]; i; i = E[i].nxt) {
    int v = E[i].v, w = E[i].w;
    if (v == fa) continue;
    dfs(v, u);
    std::memcpy(g, f[u], sizeof(g));
    std::memset(f[u], 0, sizeof(f[u]));
    for (int j = 0; j <= siz[u] / 2; ++j)
      for (int k = 0; k <= siz[v] / 2; ++k) {
        f[u][j + k][0] =
            (f[u][j + k][0] + (ll)g[j][0] * (f[v][k][0] + f[v][k][1]) % mod) %
            mod;
        f[u][j + k][1] =
            (f[u][j + k][1] + (ll)g[j][1] * (f[v][k][0] + f[v][k][1]) % mod) %
            mod;
        if ((!vis[u]) && (!vis[v]))
          f[u][j + k + 1][1] =
              (f[u][j + k + 1][1] + (ll)g[j][0] * f[v][k][0] % mod * w % mod) %
              mod;
      }
    siz[u] += siz[v];
  }
}
void Magic(int *ans) {
  std::vector<int> v;
  int c1 = 0;
  tl = 0;
  std::memset(hd, 0, sizeof(hd));
  std::memset(dsu::fa, 0, sizeof(dsu::fa));
  for (int x : S1) id[x] = ++c1;
  for (int y : S2) id[y + n] = ++c1;
  for (int i = 1; i <= k; ++i) {
    if (S1.find(x[i]) == S1.end()) continue;
    if (dsu::merge(x[i], y[i] + n)) {
      add_edge(id[x[i]], id[y[i] + n], w[i]);
      add_edge(id[y[i] + n], id[x[i]], w[i]);
    } else
      v.push_back(i);
  }
  for (int x : S1)
    if (dsu::getf(x) == x) add_edge(0, id[x], 0);
  for (int x : S2)
    if (dsu::getf(x + n) == x + n) add_edge(0, id[x + n], 0);
  int c = v.size();
  for (int S = 0; S < (1 << c); ++S) {
    int coef = 1, cnt = 0;
    for (int i = 1; i <= k; ++i) vis[id[x[i]]] = vis[id[y[i] + n]] = 0;
    for (int i = 0; i < c; ++i) {
      if (S & (1 << i)) {
        coef = (ll)coef * w[v[i]] % mod;
        if (vis[id[x[v[i]]]] || vis[id[y[v[i]] + n]]) {
          coef = 0;
          break;
        }
        vis[id[x[v[i]]]] = vis[id[y[v[i]] + n]] = 1;
        cnt++;
      }
    }
    if (!coef) continue;
    std::memset(f, 0, sizeof(f));
    dfs(0, 0);
    for (int i = 0; i <= siz[0] / 2; ++i) {
      int w = (f[0][i][0] + f[0][i][1]) % mod;
      ans[i + cnt] = (ans[i + cnt] + (ll)coef * w % mod) % mod;
    }
  }
}
}  // namespace StarlightGlimmer
void solve() {
  for (int i = 0; i <= k; ++i) f[i] = 0;
  w1 = S1.size();
  w2 = S2.size();
  int N = 0;
  for (int i = 1; i <= k; ++i)
    if (S1.find(x[i]) != S1.end()) N++;
  if (N == 0) return;
  if (w2 <= (N + 1) / 3) {
    for (int i = 1; i <= k; ++i)
      if (S1.find(x[i]) != S1.end()) ch[x[i]].push_back(i);
    TwilightSparkle::Magic();
  } else if (w1 <= (N + 1) / 3) {
    std::vector<int> rec;
    for (int i = 1; i <= k; ++i)
      if (S1.find(x[i]) != S1.end()) {
        std::swap(x[i], y[i]);
        ch[x[i]].push_back(i);
        rec.push_back(i);
      }
    std::swap(w1, w2);
    std::swap(S1, S2);
    TwilightSparkle::Magic();
    for (int i : rec) std::swap(x[i], y[i]);
  } else {
    StarlightGlimmer::Magic(f);
  }
}
int mark[maxn << 1];
void dfs1(int u, int m) {
  mark[u] = 1;
  if (m)
    S2.insert(u - n);
  else
    S1.insert(u);
  for (int v : E[u])
    if (!mark[v]) dfs1(v, m ^ 1);
}
int main() {
  scanf("%d%d", &n, &k);
  fac[0] = ifac[0] = ifac[1] = 1;
  for (int i = 1; i <= n; ++i) fac[i] = (ll)fac[i - 1] * i % mod;
  for (int i = 2; i <= n; ++i)
    ifac[i] = (ll)(mod - mod / i) * ifac[mod % i] % mod;
  for (int i = 1; i <= n; ++i) ifac[i] = (ll)ifac[i - 1] * ifac[i] % mod;
  for (int i = 1; i <= k; ++i) {
    scanf("%d%d%d", &x[i], &y[i], &w[i]);
    w[i] = (w[i] - 1 + mod) % mod;
    E[x[i]].push_back(y[i] + n);
    E[y[i] + n].push_back(x[i]);
  }
  h[0] = 1;
  for (int j = 1; j <= k; ++j) {
    int i = x[j];
    if (!mark[i]) {
      S1.clear();
      S2.clear();
      dfs1(i, 0);
      if (S1.size() + S2.size() == 1) continue;
      solve();
      std::memcpy(g, h, sizeof(g));
      std::memset(h, 0, sizeof(h));
      for (int j = 0; j <= k; ++j)
        for (int l = 0; l <= k; ++l)
          h[j + l] = (h[j + l] + (ll)g[j] * f[l] % mod) % mod;
    }
  }
  int ans = 0;
  for (int i = 0; i <= k && i <= n; ++i) {
    ans = (ans + (ll)calc(i) * h[i] % mod) % mod;
  }
  printf("%d", ans);
  return 0;
}
