#include <bits/stdc++.h>
namespace ringo {
template <class T>
inline void read(T &x) {
  x = 0;
  char c = getchar();
  bool f = 0;
  while (!isdigit(c)) f ^= c == '-', c = getchar();
  while (isdigit(c)) x = x * 10 + c - '0', c = getchar();
  if (f) x = -x;
}
template <class T>
inline void print(T x) {
  if (x < 0) putchar('-'), x = -x;
  if (x > 9) print(x / 10);
  putchar('0' + x % 10);
}
template <class T>
inline void print(const std::vector<T> &vet) {
  for (auto it : vet) print(it), putchar(' ');
}
template <class T>
inline void print(T x, char c) {
  print(x), putchar(c);
}
template <class T>
inline void print(T a, int l, int r, std::string s = "") {
  if (s != "") std::cout << s << ": ";
  for (int i = l; i <= r; i++) print(a[i], " \n"[i == r]);
}
const int N = 110, M = 1e5 + 10, mod = 1e9 + 7;
bool vis[N];
std::map<int, int> map;
std::vector<int> node, vet, dp[N][2];
int n, m, ans, sum, cnt, nod, fa[N], fa_x[N], fac[M], ifac[M], mov[1 << 20];
struct edge_t {
  int u, v, w;
};
std::vector<edge_t> e, edge, rest, G[N];
inline int dec(int a, int b) {
  a -= b;
  return a < 0 ? a + mod : a;
}
inline int inc(int a, int b) {
  a += b;
  return a >= mod ? a - mod : a;
}
inline int mul(int a, int b) {
  return (long long)a * b - (long long)a * b / mod * mod;
}
inline void inc_f(int &a, int b) {
  a += b;
  if (a >= mod) a -= mod;
}
inline int find(int x) { return fa[x] == x ? x : fa[x] = find(fa[x]); }
inline int find_x(int x) {
  return fa_x[x] == x ? x : fa_x[x] = find_x(fa_x[x]);
}
inline int binom(int n, int m) {
  return n < m ? 0 : mul(fac[n], mul(ifac[m], ifac[n - m]));
}
int get_id(int x) {
  auto it = map.find(x);
  return it == map.end() ? map[x] = ++nod : it->second;
}
std::vector<int> inc(const std::vector<int> &a, const std::vector<int> &b) {
  std::vector<int> c(std::max(a.size(), b.size()));
  for (int i = 0; i < a.size(); i++) c[i] = a[i];
  for (int i = 0; i < b.size(); i++) c[i] = inc(c[i], b[i]);
  return c;
}
std::vector<int> mul(const std::vector<int> &a, const std::vector<int> &b) {
  std::vector<int> c(a.size() + b.size() - 1);
  for (int i = 0; i < a.size(); i++)
    for (int j = 0; j < b.size(); j++)
      c[i + j] = (c[i + j] + (long long)a[i] * b[j]) % mod;
  return c;
}
void init_fac(int n) {
  fac[0] = fac[1] = ifac[0] = ifac[1] = 1;
  for (int i = 2; i <= n; i++) fac[i] = mul(fac[i - 1], i);
  for (int i = 2; i <= n; i++) ifac[i] = mul(mod - mod / i, ifac[mod % i]);
  for (int i = 2; i <= n; i++) ifac[i] = mul(ifac[i - 1], ifac[i]);
}
void dfs(int u, int father) {
  dp[u][0] = std::vector<int>{1};
  dp[u][1] = std::vector<int>{};
  for (auto it : G[u]) {
    int v = it.v, w = it.w;
    if (v != father) {
      dfs(v, u);
      if (!vis[u] && !vis[v]) {
        dp[u][1] = inc(mul(dp[u][1], inc(dp[v][0], dp[v][1])),
                       mul(dp[u][0], mul(dp[v][0], std::vector<int>{0, w})));
      } else {
        dp[u][1] = mul(dp[u][1], inc(dp[v][0], dp[v][1]));
      }
      dp[u][0] = mul(dp[u][0], inc(dp[v][0], dp[v][1]));
    }
  }
}
std::vector<int> solve(int now) {
  node.clear(), edge.clear();
  for (int i = 1; i <= nod; i++)
    if (find(i) == now) node.push_back(i);
  for (const auto &it : e)
    if (find(it.u) == now) edge.push_back(it);
  if (node.size() == 1) return std::vector<int>{1};
  std::vector<int> res(edge.size() + 1);
  if (node.size() <= 20) {
    std::map<int, int> map;
    for (int i = 0; i < node.size(); i++) map[node[i]] = i;
    memset(mov, 0, 1 << node.size() << 2);
    mov[0] = 1;
    for (int i = 0, u, v; i < edge.size(); i++) {
      u = map[edge[i].u], v = map[edge[i].v];
      for (int x = (1 << node.size()) - 1; x >= 0; x--)
        if (mov[x] && (x & (1 << u)) == 0 && (x & (1 << v)) == 0) {
          inc_f(mov[x | (1 << u) | (1 << v)], mul(mov[x], edge[i].w));
        }
    }
    for (int x = 0; x < (1 << node.size()); x++)
      if (mov[x]) {
        inc_f(res[__builtin_popcount(x) >> 1], mov[x]);
      }
    return res;
  } else {
    rest.clear();
    for (auto it : node) fa_x[it] = it;
    for (auto it : edge)
      if (find_x(it.u) != find_x(it.v)) {
        G[it.u].push_back({it.u, it.v, it.w});
        G[it.v].push_back({it.v, it.u, it.w});
        fa_x[find_x(it.u)] = find_x(it.v);
      } else {
        rest.push_back(it);
      }
    for (int x = 0; x < (1 << rest.size()); x++) {
      sum = 1, cnt = 0;
      memset(vis, 0, nod + 1);
      for (int i = 0; i < rest.size(); i++)
        if ((x >> i) & 1) {
          if (vis[rest[i].u] || vis[rest[i].v]) {
            sum = 0;
            break;
          }
          ++cnt, sum = mul(sum, rest[i].w);
          vis[rest[i].u] = vis[rest[i].v] = 1;
        }
      if (sum) {
        dfs(now, 0);
        std::vector<int> tmp(cnt + 1);
        tmp[cnt] = sum;
        res = inc(res, mul(tmp, inc(dp[now][0], dp[now][1])));
      }
    }
    return res;
  }
}
void main() {
  read(m), read(n), init_fac(std::max(n, m));
  for (int x, y, w, i = 1; i <= n; i++) {
    read(x), read(y), read(w);
    if (w != 1) e.push_back({get_id(x), get_id(y + m), w - 1});
  }
  for (int i = 1; i <= nod; i++) fa[i] = i;
  for (edge_t it : e) fa[find(it.u)] = find(it.v);
  vet.push_back(1);
  for (int i = 1; i <= nod; i++)
    if (find(i) == i) {
      vet = mul(vet, solve(i));
    }
  for (int i = 0; i < vet.size() && i <= m; i++) {
    ans = inc(ans, mul(vet[i], fac[m - i]));
  }
  print(ans, '\n');
}
}  // namespace ringo
signed main() { return ringo::main(), 0; }
