#include <iostream>
#include<vector>
#include<string>
#include<algorithm>
#include<iomanip>
#include<map>
#include<random>
#include<complex>
#include<math.h>
#include<functional>
#include<stack>
#include<queue>
#include<unordered_map>
#include<set>
#include<numeric>
#include <cassert>
using namespace std;
#define rep(i, n) for (ll i = 0; i < (ll)(n); i++)
#define req(i,n) for(int i = 1;i <=  n; i++)
#define rrep(i,n) for(ll i = n-1;i >= 0;i--)
#define ALL(obj) begin(obj), end(obj)
#define RALL(a) rbegin(a),rend(a)
typedef long long ll;
typedef long double ld;
template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }
const int inf = 0x3fffffff;
const ll INF = 1e18;
int n, m; vector<vector<pair<int, int>>> p;
bool check(int msk) {
	int cnt = 0; vector<int> tp(20,0);
	rep(i, n) {
		if (msk & (1 << i)) cnt++,tp[i]++;
	}rep(i, n) tp[i + 1] += tp[i];
	for (pair<int, int> i : p[cnt]) {
		if (tp[i.first] > i.second) return false;
	}return true;
}
int main() {
	cin >> n >> m; p.resize(n + 1); vector<ll> dp(1 << n,0);
	dp[0] = 1;
	rep(i, m) {
		int x, y, z; cin >> x >> y >> z; y--;
		p[x].push_back({ y,z });
	}rep(i, 1 << n) {
		rep(j, n) if (!(i & (1 << j)) && check(i)) dp[(1<<j)| i] += dp[i];
	}cout << dp[(1 << n)-1] << endl;
}
#include<bits/stdc++.h>
//#include<atcoder/all>
using namespace std;
//using namespace atcoder;
#define fs first
#define sc second
#define pb push_back
#define mp make_pair
#define eb emplace_back
#define ALL(A) A.begin(),A.end()
#define RALL(A) A.rbegin(),A.rend()
typedef long long ll;
typedef pair<double,double> P;
template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }
template<typename T> T gcd(T a,T b){return b?gcd(b,a%b):a;}
const ll mod=998244353;
const ll LINF=1ll<<60;
const int INF=1<<28;
int dx[]={1,0,-1,0,1,-1,1,-1};
int dy[]={0,1,0,-1,1,-1,-1,1};



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<ll> dp(1 << (n + 1), 0);
    dp[0] = 1;
    for (int bit = 0; bit < 1<<n; bit++) {
        int C = __builtin_popcount(bit);
        for (int i = 0; i < m; i++) {
            if(C == x[i]){
                int cnt = 0;
                for (int j = 0; j < n; j++) {
                    if((bit >> j) & 1){
                        if(j < y[i]){
                            cnt++;
                        }
                    }
                }
                if(cnt > z[i]){
                    dp[bit] = 0;
                }
            }
        }
        if(dp[bit] < 0) continue;
        for (int i = 0; i < n; i++) {
            if((bit >> i) & 1) continue;
            int nbit = bit | (1 << i);
            dp[nbit] += dp[bit];
        }
    }
    cout << max(0ll, dp[(1 << n) - 1]) << endl;
    return 0;
}
