#include <bits/stdc++.h>          
using namespace std;
using ll = long long;
using ld = long double;
#define rep(i, n) for (ll i = 0; i < (ll)(n); i++)
#define repp(i, st, en) for (ll i = (ll)st; i < (ll)(en); i++)
#define repm(i, st, en) for (ll i = (ll)st; i >= (ll)(en); i--)
#define all(v) v.begin(), v.end()
void chmax(ll &x, ll y) {x = max(x,y);}
void chmin(ll &x, ll y) {x = min(x,y);}
void Yes() {cout << "Yes" << endl; exit(0);}
void No() {cout << "No" << endl; exit(0);}
template<class in_Cout> void Cout(in_Cout x) {cout << x << endl; exit(0);}
template<class in_vec_cout>
void vec_cout(vector<in_vec_cout> vec) {
    for (in_vec_cout res : vec) {cout << res << " ";}
    cout << endl;
}

const ll inf = 1e18;
const ll mod = 1e9 + 7;

int main() {
    ll N, M; cin >> N >> M;
    ll L = 1 << N;
    vector<vector<ll>> vec(N,vector<ll>(N,inf));
    rep(i,M) {
        ll x, y, z; cin >> x >> y >> z;
        x--; y--;
        chmin(vec[x][y],z);
    }

    vector<ll> bitcnt(L);
    rep(bit,L) {
        ll cnt = 0;
        rep(i,N) if ((bit>>i)&1) cnt++;
        bitcnt[bit] = cnt;
    }

    vector<vector<ll>> dp(N+1,vector<ll>(L));
    dp[0][0] = 1;
    rep(i,N) {
        rep(bit,L) {
            ll cnt = bitcnt[bit];
            if (cnt!=i) continue;
            rep(j,N) {
                if ((bit>>j)&1) continue;
                ll nbit = bit | (1<<j);
                ll ncnt = 0;
                bool OK = true;
                rep(k,N) {
                    if ((nbit>>k)&1) ncnt++;
                    if (ncnt>vec[i][k]) {
                        OK = false;
                        break;
                    }
                }
                if (OK) dp[i+1][nbit] += dp[i][bit];
            }
        }
    }

    ll ans = dp[N][L-1];

    cout << ans << endl;
}
#include <bits/stdc++.h>
using namespace std;
int main(){
  int N, M;
  cin >> N >> M;
  vector<int> X(M), Y(M), Z(M);
  for (int i = 0; i < M; i++){
    cin >> X[i] >> Y[i] >> Z[i];
  }
  vector<long long> dp(1 << N, 0);
  dp[0] = 1;
  for (int i = 0; i < (1 << N); i++){
    int c = __builtin_popcount(i);
    for (int j = 0; j < M; j++){
      if (X[j] == c){
        int t  = i & ((1 << Y[j]) - 1);
        if (__builtin_popcount(t) > Z[j]){
          dp[i] = 0;
          break;
        }
      }
    }
    for (int j = 0; j < N; j++){
      if ((i >> j & 1) == 0){
        dp[i | (1 << j)] += dp[i];
      }
    }
  }
  cout << dp[(1 << N) - 1] << endl;
}