#define TO_BE_SUBMITTED
#include <bits/stdc++.h>
// #include <atcoder/fenwicktree>
// #include <atcoder/segtree>
// #include <atcoder/lazysegtree>
// #include <atcoder/string>
// #include <atcoder/math>
// #include <atcoder/convolution>
// #include <atcoder/modint>
// #include <atcoder/dsu>
// #include <atcoder/maxflow>
// #include <atcoder/mincostflow>
// #include <atcoder/scc>
// #include <atcoder/twosat>

namespace atcoder{};
using namespace atcoder;
using namespace std;

#define fr first
#define sc second
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define rep1(i, n) for (int i = 1; i <= (n); ++i)
#define rrep(i, n) for (int i = (n)-1; i >= 0; --i)
#define rrep1(i, n) for (int i = (n); i >= 1; --i)
#define srep(i, s, t) for (int i = s; i < t; ++i)
#define rng(a) a.begin(), a.end()
#define rrng(a) a.rbegin(), a.rend()
#define isin(x, l, r) ((l) <= (x) && (x) < (r))
#define pb push_back
#define eb emplace_back
#define sz(x) (int)(x).size()
#define pcnt __builtin_popcountll
#define uni(x) x.erase(unique(rng(x)), x.end())
#define snuke srand((unsigned)clock() + (unsigned)time(NULL));
#define show(x) cout << #x << " = " << x << endl;
#define PQ(T) priority_queue<T, vector<T>, greater<T>>
#define bn(x) ((1 << x) - 1)
#define dup(x, y) (((x) + (y)-1) / (y))
#define newline puts("")
using ll = long long;
using uint = unsigned;
using ull = unsigned long long;
using P = pair<int, int>;
using LP = pair<ll, ll>;
using vi = vector<int>;
using vvi = vector<vi>;
using vl = vector<ll>;
using vvl = vector<vl>;
using vp = vector<P>;
using vlp = vector<LP>;
inline int getInt()
{
    int x;
    scanf("%d", &x);
    return x;
}
template <class T>
bool chmax(T &a, const T &b)
{
    if (a < b)
    {
        a = b;
        return true;
    }
    return false;
}
template <class T>
bool chmin(T &a, const T &b)
{
    if (a > b)
    {
        a = b;
        return true;
    }
    return false;
}

ll N;
vl T, L, R;
vl Xs;
vl x2LNum, x2ExclusiveLNum, x2RNum, x2ExclusiveRNum;

void solve()
{
    cin >> N;
    rep(i, N){
        ll t, l, r;
        cin >> t >> l >> r;
        T.pb(t);
        L.pb(l);
        R.pb(r);
        Xs.pb(l);
        Xs.pb(r);
    }
    N = sz(L);
    sort(rng(Xs));
    uni(Xs);

    x2LNum = vl(sz(Xs), 0);
    x2ExclusiveLNum = vl(sz(Xs), 0);
    x2RNum = vl(sz(Xs), 0);
    x2ExclusiveRNum = vl(sz(Xs), 0);

    rep(i, N){
        L[i] = lower_bound(rng(Xs), L[i]) - Xs.begin();
        R[i] = lower_bound(rng(Xs), R[i]) - Xs.begin();
        if(T[i] == 1LL){
            x2LNum[L[i]]++;
            x2RNum[R[i]]++;
        }
        if(T[i] == 2LL){
            x2LNum[L[i]]++;
            x2ExclusiveRNum[R[i]]++;
        }
        if(T[i] == 3LL){
            x2ExclusiveLNum[L[i]]++;
            x2RNum[R[i]]++;
        }
        if(T[i] == 4LL){
            x2ExclusiveLNum[L[i]]++;
            x2ExclusiveRNum[R[i]]++;
        }
    }

    ll cnt = 0;
    ll ans = 0;

    rep(x, sz(Xs)){
        cnt -= x2ExclusiveRNum[x];
        rep(_, x2LNum[x]){
            ans += cnt;
            cnt++;
        }
        cnt -= x2RNum[x];
        rep(_, x2ExclusiveLNum[x]){
            ans += cnt;
            cnt++;
        }
    }

    cout << ans << "\n";
}

int main()
{
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(15);
    solve();
    return 0;
}
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

const int maxn=2000;
int N;
struct Segment{
	int t,l,r;
	Segment(int at,int al,int ar):t(at),l(al),r(ar){}
};
vector<Segment>segs;
bool comp(Segment a,Segment b){
	if(a.l!=b.l){
		return a.l<b.l;
	}else{
		return a.r<b.r;
	}
}
long total;
int main() {
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	while(cin>>N){
		segs.clear();
		int ct,cl,cr;
		for(int i=0;i<N;i++){
			cin>>ct>>cl>>cr;
			segs.push_back(Segment(ct,cl,cr));
		}
		sort(segs.begin(),segs.end(),comp);//The left endpoint is sorted
		total=0;
		for(int i=0;i<N;i++){
			for(int j=i+1;j<N;j++){
				if(segs[i].r>segs[j].l){//The segment intersects 
					total++;
				}else if(segs[i].r==segs[j].l){//The endpoint is on the same place
					//t=1 = []
					//t=2 = [)
					//t=3 = (]
					//t=4 = ()
					//1,3 = both ]
					//1,2 = both [
					if(segs[i].t%2==1 && segs[j].t<=2){//The intersecting endpoints are both included
						total++;
					}else{
						continue;
					}
				}else{//if segs[i].r < segs[j].l, then i++
					break;
				}
			}
		}
		//Finished checking segments
		cout<<total<<'\n';
	}
}