//http://blog.csdn.net/keshuai19940722/article/details/47843837
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<string>
#include<stack>
#include<vector>
#include<queue>
#include<map>
#include<sstream>
using namespace std;
typedef long long LL;
inline void fre1()
{
freopen("C:\\Users\\Administrator\\Desktop\\input.txt","r",stdin);/*freopen("output.txt","w",stdout);*/
}
inline void fre2()
{
fclose(stdin);/*fclose(stdout);*/
}
#define lowbit(x) (x&-x)//取x二进制数最小的1
#define MS(x,y) memset(x,y,sizeof(x))
#define maxn 1000+50
#define maxm 50000+50
#define INF (int)(1e8+7)
#define PI acos(-1)
#define EPS 1e-7
#define mod (LL)1e9+7
int idx[maxn],num;
int dp[maxn][maxn];//dp[i][j]表示第一个子序列最后一位为第二个子序列最后一位为j的最大值
struct treepoint
{
int h,val;
bool operator<(const treepoint&t)const
{
return h==t.h?val<t.val:h>t.h;
}
} k[maxn];
void add(int x,int d,int *c)
{
while(x<maxn)
{
c[x]=max(c[x],d);
x+=lowbit(x);
}
}
int get(int x,int *c)
{
int ans=0;
while(x>0)
{
ans=max(ans,c[x]);
x-=lowbit(x);
}
return ans;
}
int solve()
{
int n,i,j;
scanf("%d",&n);
for(i=1; i<=n; ++i)
{
scanf("%d%d",&k[i].h,&k[i].val);
idx[i]=k[i].val;
}
sort(idx+1,idx+n+1);
sort(k+1,k+n+1);
num=1;
for(i=2; i<=n; ++i)if(idx[i]!=idx[num])idx[++num]=idx[i];
for(i=1; i<=n; ++i)
{
k[i].val=lower_bound(idx+1,idx+num+1,k[i].val)-idx;
}
//到这里为止是将书上的果子进行排序,并将美味值进行离散化
int ans=0,tmp[maxn];
MS(dp,0);
for(i=1; i<=n; ++i)//枚举每一个k[i].val,每次其实把dp[1~n][1~n]都更新了
{ //dp[v][i]=dp[i][v]=max(dp[i][1~v])+1;
int v=k[i].val;
for(j=1; j<=n; ++j)
{
tmp[j]=get(v,dp[j])+1;//这里的get(v,dp[j])将相当于max(dp[i][1~v])
ans=max(ans,tmp[j]);
}
for(j=1; j<=n; ++j)
{
add(v,tmp[j],dp[j]);//新的tmp[j]放到树状数组里对树状数组进行维护
add(j,tmp[j],dp[v]);//这一步就是dp[v][i]=dp[i][v]
}
}
return ans;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int ans=solve();
printf("%d\n",ans);
}
return 0;
}