#include <bits/stdc++.h>
using namespace std;
//const long nPrime = 1000000007;
//const long nPrime = 998244353;
int main() {
    int n,m;
    cin >> n >> m;
    vector<vector<pair<int,int>>> vviiNum(n);
    for(int i = 0; i < m; i++){
        int x,y,z;
        cin >> x >> y >> z;
        x--, y--;
        vviiNum[x].push_back(make_pair(y,z));
    }
  
    vector<long> viDP((1<<n),0);
    viDP[0] = 1;
    for(int i = 1; i < (1<<n); i++){
        long nCount = 0;
        vector<long> viCount(n,0);
        for(int j = 0; j < n; j++){
            if((i|(1<<j)) != i){
                continue;
            }
            nCount++;
            for(int k = j; k < n; k++){
                viCount[k]++;
            }
        }
        bool b = true;
        for(int j = 0; j < vviiNum[nCount-1].size(); j++){
            int y = vviiNum[nCount-1][j].first;
            int z = vviiNum[nCount-1][j].second;
            if(viCount[y] > z){
                b = false;
                break;
            }
        }
        if(!b){
            continue;
        }
        for(int j = 0; j < n; j++){
            if((i|(1<<j)) != i){
                continue;
            }
            viDP[i] += viDP[i^(1<<j)];
        }
    }
  
    cout << viDP[(1<<n)-1] << endl;
    return 0;
}
#include<bits/stdc++.h>
#define f(i,n) for(long long int i = 0 ; i < n;  i++)
#define F first
#define S second
#define vll vector<ll>
#define vvll vector<vector<ll>>
#define all(s) s.begin(), s.end()
#define u_s unordered_set
#define u_m unordered_map
#define ll long long int
#define pb push_back
#define pll pair<ll,ll>
#define parr(arr) for(auto x: arr)cout<<x<<" ";cout<<endl
#define fast ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0)
#define testcase ll tt; cin>>tt; while(tt--)
using namespace std;
vector<vector<pll>> cond;
ll n, m; 
ll dp[18][524300], dp1[18][524300];
bool check(ll idx, ll taken){
    if(cond[idx].size() == 0) return 1;
    if(dp1[idx][taken] != -1) return dp1[idx][taken];
    ll pre[n+1] = {};
    for(ll i = 1; i <= n; i++){
        pre[i] = ((taken & (1<<i)) != 0);
        pre[i] += pre[i-1];
    }
    for(auto &x: cond[idx]){
        if(pre[x.F] > x.S) return dp1[idx][taken] = 0;
    }
    return dp1[idx][taken] = 1;
}

ll helper(ll idx, ll taken){
    if(idx == n) 
        return 1LL;
    if(dp[idx][taken] != -1) return dp[idx][taken];
    ll ans = 0;
    for(ll i = 1; i <= n; i++){
        if(taken & (1LL<<i)) continue;
        taken ^= (1LL<<i);
        if(check(idx, taken)) ans += helper(idx+1, taken);
        taken ^= (1LL<<i);
    }
    return dp[idx][taken] = ans;
}


void solve(){
    cin>>n>>m;
    cond.resize(n);
    while(m--){
        ll x , y , z; cin>>x>>y>>z; x--;
        cond[x].pb({y,z});
    }
    memset(dp,-1,sizeof dp);
    memset(dp1,-1,sizeof dp1);
    cout<<helper(0, 0);
}



int main() {
    fast;
    solve();   
	return 0;
}