#include<fstream>
using namespace std;
const char iname[]="cutii.in";
const char oname[]="cutii.out";
const int maxn=3507;
ifstream f(iname);
ofstream g(oname);
struct box
{
int x,y,z;
}a[maxn];
bool operator<(const box& a,const box& b)
{
return a.x<b.x;
}
struct quad
{
quad *lu,*ld,*ru,*rd;
int v;
quad()
{
lu=ld=ru=rd=0;
v=0;
}
} *root;
void update(quad *nod,int x1,int y1,int x2,int y2,int posx,int posy,int value)
{
if(x1==x2&&y1==y2)
{
nod->v=value;
return;
}
int divx=(x1+x2)>>1,divy=(y1+y2)>>1;
if(posx<=divx)
if(posy<=divy)
{
if(nod->lu==0)
nod->lu=new quad();
update(nod->lu,x1,y1,divx,divy,posx,posy,value);
}
else
{
if(nod->ld==0)
nod->ld=new quad();
update(nod->ld,x1,divy+1,divx,y2,posx,posy,value);
}
else
if(posy<=divy)
{
if(nod->ru==0)
nod->ru=new quad();
update(nod->ru,divx+1,y1,x2,divy,posx,posy,value);
}
else
{
if(nod->rd==0)
nod->rd=new quad();
update(nod->rd,divx+1,divy+1,x2,y2,posx,posy,value);
}
nod->v=max(nod->v,value);
}
void drop(quad *nod)
{
if(nod->lu)
delete nod->lu;
if(nod->ld)
delete nod->ld;
if(nod->ru)
delete nod->ru;
if(nod->rd)
delete nod->rd;
nod->lu=nod->ld=nod->ru=nod->rd=0;
}
int query(quad *nod,int x1,int y1,int x2,int y2,int x,int y)
{
if(x2<=x&&y2<=y)
{
return nod->v;
}
int k=0,divx=(x1+x2)>>1,divy=(y1+y2)>>1;
if(nod->lu)
k=max(k,query(nod->lu,x1,y1,divx,divy,x,y));
if(divx<x)
if(divy<y&&nod->rd)
k=max(k,query(nod->rd,divx+1,divy+1,x2,y2,x,y));
if(divx<x&&nod->ru)
k=max(k,query(nod->ru,divx+1,y1,x2,divy,x,y));
if(divy<y&&nod->ld)
k=max(k,query(nod->ld,x1,divy+1,divx,y2,x,y));
return k;
}
int n,i,j,t,p,maxt;
int main()
{
f>>n>>t;
root=new quad();
for(p=1;p<=t;++p)
{
for(i=1;i<=n;++i)
f>>a[i].x>>a[i].y>>a[i].z;
sort(a+1,a+n+1);
maxt=-0x3f3f3f3f;
root->v=0;
for(i=1;i<=n;++i)
{
j=query(root,0,0,n,n,a[i].y-1,a[i].z-1);
if(j+1>maxt)
maxt=j+1;
update(root,0,0,n,n,a[i].y,a[i].z,j+1);
}
g<<maxt<<"\n";
drop(root);
}
f.close();
g.close();
return 0;
}