#include<bits/stdc++.h>
using namespace std;
#define rep(i,n) for(int i = 0; i < n; i++)
#define Rep(i,n) for(int i = 1; i <= n; i++)
#define sz(a) int(a.size())
#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()
#define debug(a) { cerr << #a << ':' << a << endl; }
#define endl '\n'
#define fi first
#define se second
using lint = long long;
using P = pair<int,int>;
template<class T> using V = vector<T>;
template<class T> using priq     = priority_queue<T>;
template<class T> using priq_inv = priority_queue<T, vector<T>, greater<T>>;
const int dx[] = {0,1,0,-1,1,1,-1,-1};
const int dy[] = {1,0,-1,0,1,-1,-1,1};
template<class T> T ceil(const T &a, const T &b) { return (a+b-1)/b; }
template<class T> bool chmin(T &a, T b) { if(a > b) { a = b; return 1; } return 0; }
template<class T> bool chmax(T &a, T b) { if(a < b) { a = b; return 1; } return 0; }
struct INF { template<class T> operator T() { return numeric_limits<T>::max() / 2; } } INF;

template<class T, class U> istream& operator>>(istream &in, pair<T,U> &p) {
    return in >> p.first >> p.second;
}
template<class T, class U> ostream& operator<<(ostream &out, const pair<T,U> &p) {
    return out << p.first << ' ' << p.second;
}
template<class T> istream& operator>>(istream &in, vector<T> &v) {
    for(auto &&e: v) in >> e;
    return in;
}
template<class T> ostream& operator<<(ostream &out, const vector<T> &v) {
    for(const auto &e: v) out << e << ' ';
    return out;
}

/*----------------------------------------------------------------------------------------------------*/


int main() {
    int n, m;
    cin >> n >> m;
    V<V<P>> ps(n+1);
    rep(i,m) {
        int x, y, z;
        cin >> x >> y >> z;
        ps[x].emplace_back(y,z);
    }

    V<lint> dp(1<<n);
    dp[0] = 1;
    rep(s,1<<n) {
        int x = __builtin_popcount(s);
        for(P p: ps[x]) {
            int s2 = s&((1<<p.fi)-1);
            int cnt = __builtin_popcount(s2);
            if(cnt > p.se) dp[s] = 0;
        }
        rep(i,n) {
            if(~s>>i&1) dp[s|1<<i] += dp[s];
        }
    }
    cout << dp[(1<<n)-1] << endl;
}
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int N;
vector<int> X;
vector<vector<pair<int,int>>> B;
ll fact[20];
ll memo[18][1<<18];
bool visited[18][1<<18];
ll f(int p, int q) {
	if (p == (int)X.size()-1) return fact[N-X.back()];
	if (visited[p][q]) return memo[p][q];
	visited[p][q] = true;
	int mask = ((1<<N)-1)^q;
	int c = X[p+1]-X[p];
	ll res = 0;
	for (int m = mask; m > 0; m = (m-1)&mask) if (__builtin_popcount(m) == c) {
		for (auto [y, z] : B[p]) {
			if (__builtin_popcount((q|m)&((1<<y)-1)) > z) goto next;
		}
		res += f(p+1, q|m);
		next:;
	}
	return memo[p][q] = res * fact[c];
}
int main() {
	fact[0] = 1;
	for (int i = 1; i < 20; ++ i) fact[i] = fact[i-1] * i;
	int M;
	cin >> N >> M;
	map<int, vector<pair<int,int>>> A;
	for (int i = 0; i < M; ++ i) {
		int x, y, z;
		cin >> x >> y >> z;
		A[x].push_back({y,z});
	}
	X.push_back(0);
	for (auto& x : A) {
		X.push_back(x.first);
		B.push_back(x.second);
	}
	cout << f(0, 0) << endl;
}
