//线段树区间覆盖
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=100010;
int flag;
struct node{
int l,r;
//vis 是这块区域是否完全被覆盖
bool vis;
}tr[N<<2];
struct point
{
int id;
int x;
}post[N<<2];
int cmp1(point a,point b)
{
return a.x<b.x;
}
int cmp2(point a,point b)
{
if(a.id==b.id)
return a.x<b.x;
return a.id>b.id;
}
void pushup(int u)
{
tr[u].vis=tr[u<<1].vis&&tr[u<<1|1].vis;
}
void build(int u,int l,int r)
{
tr[u]={l,r,0};
if(l==r)
return ;
int mid=l+r>>1;
build(u<<1,l,mid);
build(u<<1|1,mid+1,r);
}
void query(int u,int l,int r)
{
if(tr[u].vis)
return ;
if(tr[u].l==l&&tr[u].r==r)
{
tr[u].vis=1;
flag=1;
return;
}
int mid=tr[u].l+tr[u].r>>1;
if(r<=mid)
query(u<<1,l,r);
else if(l>mid)
query(u<<1|1,l,r);
else
{
query(u<<1,l,mid);
query(u<<1|1,mid+1,r);
}
pushup(u);
}
int main()
{
int t,n;
cin>>t;
while(t--)
{
cin>>n;
//离散化之前的数据
for(int i=0;i<2*n;i+=2)
{
cin>>post[i].x>>post[i+1].x;
post[i].id=post[i+1].id=i;
}
//按照离散化之前的数据排序
sort(post,post+2*n,cmp1);
//离散化
int tot=0,pre=0;
for(int i=0;i<2*n;i++)
{
//如果和上一个一样
//那么排名也就一样
if(post[i].x==pre)
{
post[i].x=tot;
}
//如果不一样,记录当前值
//排名++
else
{
pre=post[i].x;
post[i].x=++tot;
}
}
build(1,1,2*n);
//排序,从后往前贴
//id大的在前
sort(post,post+2*n,cmp2);
int ans=0;
for(int i=0;i<2*n;i+=2)
{
int l=post[i].x;
int r=post[i+1].x;
flag=0;
query(1,l,r);
if(flag)
ans++;
}
cout<<ans<<endl;
}
return 0;
}