/*
题意:给横坐标轴染色,每次给一个区间内的染色,每染一次会把上一次的覆盖,经过n次染色只会,问你从最上面看,横坐标上总共有几种颜色
初步思路:区间染色问题,就是一个区间set问题,然后最后的查询的时候,记录一下就行了
#超内存:需要离散化
*/
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
int n,l[10005],r[10005];
int t;
bool color[10005];//用于记录颜色
int res=0;
int X[20010];
int k;
int kk;
/****************************线段树基础模板*********************************/
const int maxn=20010+5;
#define lson i*2, l, m
#define rson i*2+1, m+1, r
struct Segtree{
int setv[maxn<<2];
void PushDown(int i)
{
if(setv[i]>0){
setv[i*2]=setv[i*2+1]=setv[i];
setv[i]=-1;//向下更新完了就没有继续用的意义了
}
}
void build(int i,int l,int r)
{
// cout<<l<<" "<<r<<" "<<i<<endl;
setv[i]=0;
if(l==r)
return ;
int m=(l+r)>>1;
build(lson);
build(rson);
}
void query(int ql,int qr,int i,int l,int r)
{
if(ql<=l&&r<=qr){
if(setv[i]>0){
color[setv[i]]=true;
return ;
}
}
if(l==r) return ;
PushDown(i);
int m=(l+r)>>1;
if(ql<=m) query(ql,qr,lson);
if(m<qr) query(ql,qr,rson);
}
void update(int ql,int qr,int val,int i,int l,int r)
{
// cout<<l<<" "<<r<<endl;
if(ql<=l&&r<=qr)
{
setv[i]=val;
return ;
}
PushDown(i);
int m=(l+r)>>1;
if(ql<=m) update(ql,qr,val,lson);
if(m<qr) update(ql,qr,val,rson);
}
};
Segtree segtree;
/****************************线段树基础模板*********************************/
void init(){
memset(color,false,sizeof color);
res=0;
k=1;
kk=1;
}
int findx(int key){
int l=1,r=k,mid;
while(l<=r){
mid=(l+r)>>1;
if(X[mid]==key)
return mid;
else if(X[mid]>key)
r=mid-1;
else l=mid+1;
}
return 0;
}
int main(){
// freopen("in.txt","r",stdin);
scanf("%d",&t);
while(t--){
init();
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d%d",&l[i],&r[i]);
X[kk++]=l[i];
X[kk++]=r[i];
}
sort(X+1,X+kk+1);
for(int i=2;i<kk;i++){//离散化
if(X[i]!=X[i-1])
X[++k]=X[i];
}
segtree.build(1,1,k);
for(int i=1;i<=n;i++){
int L=findx(l[i]);
int R=findx(r[i]);
segtree.update(L,R,i,1,1,k);
}
segtree.query(1,k,1,1,k);
for(int i=1;i<=n;i++){
if(color[i]) res++;
}
printf("%d\n",res);
}
return 0;
}