#include <iostream>
#include <string>
#include <vector>
#include <functional>
#include <numeric>
#include <algorithm>
#include <queue>
#include <bitset>
#include <cmath>
#include <map>
using namespace std;
#define rep(i,n)  for(int i=0 ; i<(n) ; ++i)
typedef long long ll;
typedef pair<int,int> p;
const double PI=3.14159265358979323846;
const int MOD = 1000000000+7;
const int INF = 1001000100;


int main(){
  ll n;
  cin >> n;
  ll t[n],l[n],r[n];
  rep(i,n) cin >> t[i] >> l[i] >> r[i];

  ll ans=0;
  for(int i=1 ; i<n ; ++i){
    rep(j,i){
      if(l[i]>r[j] || l[j]>r[i]){
        continue;
      }else if(l[i]==r[j]){
        if((t[i]==1 || t[i]==2) && (t[j]==1 || t[j]==3)){
          ans++;
        }
      }else if(l[j]==r[i]){
        if((t[j]==1 || t[j]==2) && (t[i]==1 || t[i]==3)){
          ans++;
        }
      }else ans++;
    }
  }
  cout << ans;
  return 0;
}
#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;

#define rep(i, n) for(int i = 0;i < n;i++)
#define rep1(i, n) for(int i = 1;i < n;i++)
#define repr(i, n) for(int i = n;i >= 0;i--)
#define FOR(i, m, n) for(int i = m;i < n;i++)

#define ALL(a)  (a).begin(),(a).end()

vector<vector<ll>> near8={{-1,1},{0,1},{1,1},{-1,0},{1,0},{-1,-1},{0,-1},{1,-1}};
vector<vector<ll>> near4={{0,1},{-1,0},{1,0},{0,-1}};

ll INF = INT64_MAX;

bool ll_sqrt(ll x, ll& lower_bound, ll& upper_bound)
{
	constexpr ll ll_max = numeric_limits<ll>::max();
 
	bool first_boost = true;
 
	lower_bound = 0;
	upper_bound = x;
	while (upper_bound - lower_bound > 1)
	{
		if (first_boost)
		{
			ll guess = (ll)sqrt((double)x);
			lower_bound = max(guess - 1, (ll)0);
			upper_bound = lower_bound + 3;
			first_boost = false;
		}
 
		ll newval = (lower_bound + upper_bound) / 2;
		if ((newval != 0) && (newval > ll_max / newval))  // newval*newval becomes overflow
			upper_bound = newval;  // because overflow means newval is too big
		else
		{
			ll newval_sqr = newval * newval;
			if (newval_sqr < x)
				lower_bound = newval;
			else
				upper_bound = newval;
		}
	}
 
	if ((upper_bound != 0) && (upper_bound > ll_max / upper_bound))
	{
		if (lower_bound * lower_bound == x)
			upper_bound = lower_bound;
	}
	else
	{
		if (lower_bound * lower_bound == x)
			upper_bound = lower_bound;
		else if (upper_bound * upper_bound == x)
			lower_bound = upper_bound;
	}
	bool is_exact = (lower_bound == upper_bound);
	return is_exact;
}

ll ll_ceil(ll x, int digit);
ll ll_floor(ll x, int digit);


ll ll_floor(ll x, int digit)
{
	if (x < 0)
		return -ll_ceil(-x, digit);
 
	ll div = 1;
	while (digit != 0)
	{
		div *= 10;
		digit--;
	}
	ll modval = x % div;
	ll ans = x - modval;
	return ans;
}

ll ll_ceil(ll x, int digit)
{
	if (x < 0)
		return -ll_floor(-x, digit);
 
	ll div = 1;
	while (digit != 0)
	{
		div *= 10;
		digit--;
	}
	ll modval = x % div;
	ll ans = x - modval;
	if (modval != 0)
		ans += div;
	return ans;
}

struct UnionFind {
    vector<ll> par; // par[i]:iの親の番号　(例) par[3] = 2 : 3の親が2

    UnionFind(ll N) : par(N) { //最初は全てが根であるとして初期化
        for(ll i = 0; i < N; i++) par[i] = i;
    }

    ll root(ll x) { // データxが属する木の根を再帰で得る：root(x) = {xの木の根}
        if (par[x] == x) return x;
        return par[x] = root(par[x]);
    }

    void unite(ll x, ll y) { // xとyの木を併合
        ll rx = root(x); //xの根をrx
        ll ry = root(y); //yの根をry
        if (rx == ry) return; //xとyの根が同じ(=同じ木にある)時はそのまま
        par[rx] = ry; //xとyの根が同じでない(=同じ木にない)時：xの根rxをyの根ryにつける
    }

    bool same(ll x, ll y) { // 2つのデータx, yが属する木が同じならtrueを返す
        ll rx = root(x);
        ll ry = root(y);
        return rx == ry;
    }
};

ll H,W;
vector<vector<char>> map1(501, vector<char>(501,'#'));


bool solve(ll h, ll w){
	ll nexth=0;
	ll nextw=0;

	for(vector<ll> to:near4){
		nexth = h+to[0];
		nextw = w+to[1];
		if(nexth < 0 || nexth >=H || nextw < 0 || nextw >=W || map1[nexth][nextw] == '#'){
			continue;
		}
		if(map1[nexth][nextw] =='g'){
			return true;
		}
		map1[nexth][nextw]='#';
		if(solve(nexth, nextw)){
			return true;
		};
	}

	return false;
}


int main() {
	ll n;
	cin >> n;

	ll ans = 0;
	vector<vector<ld>> k;
	ld t, l, r;

	rep(i, n){
		cin >> t >> l >> r;
		if(t==2){
			r-=0.5;
		}
		if(t==3){
			l+=0.5;
		}
		if(t==4){
			l+=0.5;
			r-=0.5;
		}

		for(ll j = 0; j < i; j++){
			if((k[j][0] >=  l && k[j][0] <= r) || (k[j][1] >= l && k[j][1] <= r)
				||  (k[j][0] < l &&  k[j][1] >= r)){
				ans++;
			}
		}
		vector<ld> tmp = {l, r};
		k.push_back(tmp);
	}
	


	cout << ans << endl;

  return 0;
}