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

#define rep(i, n) for (long long i = 0; i < (n); i++)
#define REP(i, s, n) for (long long i = (s); i <= (n); i++)
#define repr(i, n) for (long long i = (n - 1); i >= 0; i--)
#define REPR(i, s, n) for (long long i = (s); i >= (n); i--)
#define all(v) (v).begin(), (v).end() //biginからendへ
#define rall(v) (v).rbegin(), (v).rend()
#define sumvec(v) accumulate(all(v), 0LL)
#define DOUBLE fixed << setprecision(15)
#define OK cerr << "OK\n"
#define OK1 cerr << "OK1\n"
#define OK2 cerr << "OK2\n"
#define sz(s) (long long)s.size()

typedef long long ll;
typedef long double ld;
typedef vector<int> vi;
typedef vector<long long> vll;
typedef vector<double> vd;
typedef vector<char> vc;
typedef vector<bool> vb;
typedef vector<string> vs;
typedef vector<vi> vvi;
typedef vector<vll> vvll;
typedef vector<vd> vvd;
typedef vector<vc> vvc;
typedef vector<vb> vvb;
typedef pair<ll, ll> P;
typedef vector<P> vP;

//vectorの末尾参照は .back()を使おう。
//if(chmax(ans, i))

#define INT(...)     \
    int __VA_ARGS__; \
    IN(__VA_ARGS__)
#define LL(...)            \
    long long __VA_ARGS__; \
    IN(__VA_ARGS__)
#define CHR(...)      \
    char __VA_ARGS__; \
    IN(__VA_ARGS__)
#define DBL(...)        \
    double __VA_ARGS__; \
    IN(__VA_ARGS__)
#define STR(...)        \
    string __VA_ARGS__; \
    IN(__VA_ARGS__)
#define LD(...)              \
    long double __VA_ARGS__; \
    IN(__VA_ARGS__)

void scan(int &a)
{
    cin >> a;
}
void scan(long long &a) { cin >> a; }
void scan(char &a) { cin >> a; }
void scan(double &a) { cin >> a; }
void scan(string &a) { cin >> a; }
void scan(long double &a) { cin >> a; }

void IN() {}
template <class Head, class... Tail>
void IN(Head &head, Tail &...tail)
{
    scan(head);
    IN(tail...);
}

//INT(a,b)とか使う

void YES(bool b) { cout << ((b) ? "YES\n" : "NO\n"); }
void Yes(bool b) { cout << ((b) ? "Yes\n" : "No\n"); }
void yes(bool b) { cout << ((b) ? "yes\n" : "no\n"); }
void Yay(bool b) { cout << ((b) ? "Yay!\n" : ":(\n"); }
void posible(bool b) { cout << ((b) ? "posible\n" : "imposible\n"); }
void Posible(bool b) { cout << ((b) ? "Posible\n" : "Imposible\n"); }
void POsIBLE(bool b) { cout << ((b) ? "POsIBLE\n" : "IMPOsIBLE\n"); }

//出力の形式に合わせて関数をキャスとする

const int inf = 1001001001;
const long long INF = ((1LL << 62) - (1LL << 31));
const long double pi = acos(-1.0);




int main(){
    
    vector<pair<double,double>> v;
    LL(n);
    rep(i,n){
        LL(t);
        DBL(l,r);
        if(t == 2) r -= 0.1;
        if(t == 3) l += 0.1;
        if(t == 4){
            r -= 0.1;
            l += 0.1;
        }
        v.push_back(make_pair(l,r));
    }
    ll ans = 0;
    rep(i,n){
        REP(j,i + 1,n - 1){
            if(v[i].first == v[j].first || v[i].first == v[j].second || v[i].second == v[j].first || v[i].second == v[j].second) ans++;
            else if((v[j].first < v[i].first && v[j].second > v[i].first) || (v[i].first < v[j].first && v[i].second > v[j].first)) ans++;
        }
    }
       
    cout << ans;

}

// Template begins
#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
#include <set>
#include <stdio.h>
#include <math.h>
#include <iomanip>
#include <queue> 
#include <string.h>
#include <string>
using namespace std;
#define fio ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL)
#define ll long long
#define endl "\n"
#define lb lower_bound
#define ub upper_bound
#define fo(i,a,b) for(i=a;i<=b;i++)
#define all(v) (v).begin(),(v).end()
#define sort0(v) sort(all(v))
#define lbb(a,b,arr,x) lower_bound(arr+a,arr+b+1,x)-arr
#define ubb(a,b,arr,x) upper_bound(arr+a,arr+b+1,x)-arr
#define freq(a,b,arr,x) upper_bound(arr+a,arr+b+1,x)-lower_bound(arr+a,arr+b+1,x)
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
#define d0(x) cout<<(x)<<" "
#define d1(x) cout<<(x)<<endl
#define d2(x,y) cout<<(x)<<" "<<(y)<<endl
#define d3(x,y,z) cout<<(x)<<" "<<(y)<<" "<<(z)<<endl
#define d4(a,b,c,d) cout<<(a)<<" "<<(b)<<" "<<(c)<<" "<<(d)<<endl
#define d5(a,b,c,d,e) cout<<(a)<<" "<<(b)<<" "<<(c)<<" "<<(d)<<" "<<(e)<<endl
#define d6(a,b,c,d,e,f) cout<<(a)<<" "<<(b)<<" "<<(c)<<" "<<(d)<<" "<<(e)<<" "<<(f)<<endl
#define max3(a,b,c) max(max((a),(b)),(c))
#define max4(a,b,c,d) max(max((a),(b)),max((c),(d)))
#define ss second
#define ff first
#define pb push_back
#define mp make_pair
#define printp(x) cout << x.ff << " " << x.ss << endl
 
const ll mod=998244353;
#define inf 9999999999999
#define MAXN   100001 
  
// stores smallest prime factor for every number 
 
 
ll inv(ll i){if(i==1) return 1;return (mod-((mod/i)*inv(mod%i))%mod)%mod;}
 
ll gcd(ll a,ll b){if(a==0) return b;return gcd(b,b%a);}
inline void fastio(){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);}
// Template ends
const int MN = 2e5+7;
ll dp[1 << 21];
ll fun(ll mask, ll n, vector <pii> v[]) {
    int i=__builtin_popcount(mask);
    if (i== n) {
        return 1;
    }
    if (dp[mask] != -1) {
        return dp[mask];
    }
    ll temp = 0;
    ll cnt = 0;
    for (auto j: v[i]) {
        cnt = 0;
        for (ll k = 1; k <= j.ff; k++) {
            if (mask & (1LL << k)) {
                ++cnt;
            }
        }
        if (cnt > j.ss) {
            temp = -1e18;
        } 
    }
    for (ll j = 0; j < n; j++) {
        if (mask & (1LL << j)) {
            continue;
        }
        temp+=fun( mask | (1LL << j), n, v);
    }
    temp = max(temp, 0LL);
    return dp[mask] = temp;
}
void solve(){
    ll n,m; cin>>n>>m;
    ll ans;
    if (!m) {
        ans = 1;
        for (ll i = 1; i <= n; i++) {
            ans *= i;
        }
        cout<<ans<<endl;
        return;
    }
    vector <pii> v[20];
    for (ll i = 0; i < m; i++) {
        int x,y,z; cin>>x>>y>>z;
        v[x].pb(mp(y,z));
    }
    memset(dp, -1, sizeof(dp));
    ans = fun( 0, n, v);
    cout<<ans<<endl;
}
int main(){
    fastio();
    //write code
    solve();
    return 0;
}