#include <bits/stdc++.h>
using namespace std;
vector<int> mul(vector<int> a, vector<int> b) {
  vector<int> res(a.size() + b.size() - 1);
  for (int i = 0; i < a.size(); i++) {
    for (int j = 0; j < b.size(); j++) {
      res[i + j] = (res[i + j] + (long long)a[i] * b[j]) % 1000000007;
    }
  }
  return res;
}
int main() {
  int n, m, cur_t = 0;
  cin >> n >> m;
  vector<vector<pair<int, int> > > adj(n * 2);
  for (int i = 0; i < m; i++) {
    int u, v, w;
    cin >> u >> v >> w;
    adj[--u].push_back({--v + n, (w + 1000000007 - 1) % 1000000007});
    adj[v + n].push_back({u, (w + 1000000007 - 1) % 1000000007});
  }
  vector<int> ans = {1}, vis(n * 2), idx(n * 2), sz(n * 2);
  vector<vector<pair<int, int> > > tree(n * 2);
  for (int C = 0; C < n; C++) {
    if (!vis[C]) {
      cur_t++;
      vector<int> L, R;
      vector<pair<pair<int, int>, int> > E;
      function<void(int, int)> dfs = [&](int u, int fa) {
        vis[u] = cur_t;
        if (u < n) {
          idx[u] = L.size();
          L.push_back(u);
        } else {
          idx[u] = R.size();
          R.push_back(u);
        }
        sz[u] = 1;
        for (auto &e : adj[u]) {
          int v = e.first, w = e.second;
          if (vis[v] != cur_t) {
            dfs(v, u);
            sz[u] += sz[v];
            tree[u].push_back({v, w});
          } else if (v != fa && v > u) {
            E.push_back({{u, v}, w});
          }
        }
      };
      dfs(C, -1);
      if (min(L.size(), R.size()) <= 18) {
        if (L.size() < R.size()) {
          swap(L, R);
        }
        vector<long long> dp(1 << R.size());
        dp[0] = 1;
        for (int u : L) {
          for (int i = (1 << R.size()) - 1; i >= 0; i--) {
            if (dp[i]) {
              for (auto &e : adj[u]) {
                if (!(i & (1 << idx[e.first]))) {
                  (dp[i | (1 << idx[e.first])] += dp[i] * e.second) %=
                      1000000007;
                }
              }
            }
          }
        }
        vector<int> res(R.size() + 1);
        for (int i = 0; i < 1 << R.size(); i++) {
          (res[__builtin_popcount(i)] += dp[i]) %= 1000000007;
        }
        ans = mul(ans, res);
      } else {
        static vector<vector<vector<int> > > dp(n * 2);
        vector<int> res(sz[C] / 2 + 1), app(n * 2);
        for (int i = 0; i < 1 << E.size(); i++) {
          bool ok = true;
          int w = 1;
          for (int j = 0; j < E.size() && ok; j++) {
            if (i & (1 << j)) {
              int u = E[j].first.first, v = E[j].first.second;
              w = (long long)w * E[j].second % 1000000007;
              if (app[u] || app[v]) {
                ok = false;
              } else {
                app[u] = app[v] = true;
              }
            }
          }
          if (ok) {
            function<void(int)> calc = [&](int u) {
              dp[u] = vector<vector<int> >(2, vector<int>(sz[u] / 2 + 1));
              dp[u][0][0] = 1;
              sz[u] = 1;
              for (auto &e : tree[u]) {
                int v = e.first;
                calc(v);
                for (int x = (sz[u] + sz[v]) / 2; x; x--) {
                  for (int y = 0; y <= sz[v] / 2; y++) {
                    if (y < x) {
                      dp[u][1][x] = (dp[u][1][x] +
                                     (long long)dp[u][0][x - y - 1] *
                                         dp[v][0][y] % 1000000007 * e.second) %
                                    1000000007;
                    }
                    if (y <= x && y) {
                      dp[u][0][x] =
                          (dp[u][0][x] + (long long)dp[u][0][x - y] *
                                             (dp[v][0][y] + dp[v][1][y])) %
                          1000000007;
                      dp[u][1][x] =
                          (dp[u][1][x] + (long long)dp[u][1][x - y] *
                                             (dp[v][0][y] + dp[v][1][y])) %
                          1000000007;
                    }
                  }
                }
                sz[u] += sz[v];
              }
              if (app[u]) {
                dp[u][1] = dp[u][0];
                dp[u][0] = vector<int>(sz[u] / 2 + 1, 0);
              }
            };
            calc(C);
            for (int j = 0; j <= sz[C] / 2; j++) {
              int &x = res[j + __builtin_popcount(i)];
              x = (x + (long long)(dp[C][0][j] + dp[C][1][j]) * w) % 1000000007;
            }
          }
          for (int j = 0; j < E.size(); j++) {
            if (i & (1 << j)) {
              int u = E[j].first.first, v = E[j].first.second;
              app[u] = app[v] = false;
            }
          }
        }
        ans = mul(ans, res);
      }
    }
  }
  vector<int> fact(n + 1);
  fact[0] = 1;
  for (int i = 1; i <= n; i++) {
    fact[i] = (long long)fact[i - 1] * i % 1000000007;
  }
  int sum = 0;
  for (int i = 0; i < ans.size(); i++) {
    sum = (sum + (long long)ans[i] * fact[n - i]) % 1000000007;
  }
  cout << sum << endl;
  return 0;
}
