#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<ll, ll> ii;
typedef tuple<ll, ll, ll> iii;
typedef vector<ll> vi;
typedef vector<ii> vii;
typedef vector<iii> viii;
typedef vector<vi> vvi;
typedef vector<vii> vvii;
#define REP(i,n) for (ll i = 0; i < n; ++i)
#define REPR(i,n) for (ll i = n-1; i >= 0; --i)
#define FOR(i,m,n) for (ll i = m; i < n; ++i)
#define FORR(i,m,n) for (ll i = n-1; i >= m; --i)
#define FORE(x,xs) for (const auto& x : xs)
#define FORI(i,v) for (auto i = v.begin(); i != v.end(); i++)
#define ALL(v) v.begin(), v.end()
#define SORT(v) sort(ALL(v))
#define REV(v) reverse(ALL(v))
#define UNIQ(v) sort(ALL(v)); v.erase(unique(ALL(v)),end(v))
#define CHMIN(x,y) x = min(x, y)
#define CHMAX(x,y) x = max(x, y)
#define YES(b) cout << ((b) ? "YES" : "NO") << endl
#define Yes(b) cout << ((b) ? "Yes" : "No") << endl

const int MAX = 20;

int N, M;
vii X[MAX];
ll dp[1<<MAX];

int main() {
    cout << fixed << setprecision(15);
    cin >> N >> M;
    REP (i, M) {
        int x, y, z;
        cin >> x >> y >> z;
        X[x].push_back(make_pair(y, z));
    }

    vector<bool> visit(1<<N, false);
    queue<int> q;
    q.push(0);
    dp[0] = 1;
    while (q.size()) {
        int state = q.front(); q.pop();
        int b = __builtin_popcount(state) + 1;
        REP (i, N) if ((state & (1<<i)) == 0) {
            int next = state | (1<<i);
            bool check = true;
            FORE (x, X[b]) {
                if (__builtin_popcount(next&((1<<(x.first))-1)) > x.second) check = false;
            }
            if (check) {
                dp[next] += dp[state];
                if (!visit[next]) {
                    q.push(next);
                    visit[next] = true;
                }
            }
        }
    }
    cout << dp[(1<<N)-1] << endl;
}

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef vector<ll> vi;
ll n, m;
vi x(100), y(100), z(100);

ll cntmask(ll n) {
    ll ans = 0;
    while (n) {
        ans += n%2;
        n /= 2;
    }
    return ans;
}

bool checkrule(ll mask, ll rule) {
    ll cnt = 0;
    for (ll i = 0; i < y[rule]; ++i)
        if (mask & (1<<i))
            ++cnt;
    return cnt <= z[rule];
}

bool check(ll mask) {
    ll elems = cntmask(mask);
    for (ll i = 0; i < m; ++i) {
        if (x[i] != elems) continue;
        if (not checkrule(mask, i)) return false;
    }
    return true;
}

ll solve() {
    vi memo(1<<n);
    memo[0] = 1;

    queue<ll> q;
    q.push(0);

    while (not q.empty()) {
        ll mask = q.front();
        q.pop();
        
        for (ll i = 0; i < n; ++i) {
            if (mask & (1<<i)) continue;
            if (check(mask + (1<<i))) {
                memo[mask + (1<<i)] += memo[mask];
                if (memo[mask + (1<<i)] == memo[mask])
                    q.push(mask + (1<<i));
            }
        }
    }

    return memo[(1<<n) - 1];
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL); cout.tie(NULL);

    cin >> n >> m;
    for (ll i = 0; i < m; ++i)
        cin >> x[i] >> y[i] >> z[i];

    cout << solve() << '\n';
    return 0;
}