#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cctype>
using namespace std;
const int NMAX = 3500;
char buf[1 << 17];
int crs = (1 << 17) , sz = (1 << 17);
void get_int(int &n)
{
for( ; crs < sz && !isdigit(buf[crs]) ; crs ++);
if(crs == sz)
{
fread(buf , sz , 1 , stdin);
crs = 0;
for( ; crs < sz && !isdigit(buf[crs]) ; crs ++);
}
n = 0;
for( ; crs < sz && isdigit(buf[crs]) ; crs ++)
n = n * 10 + buf[crs] - '0';
if(crs == sz)
{
fread(buf , sz , 1 , stdin);
crs = 0;
for( ; crs < sz && isdigit(buf[crs]) ; crs ++)
n = n * 10 + buf[crs] - '0';
}
}
struct cutii
{
int x , y , z;
cutii(int tx = 0 , int ty = 0 , int tz = 0)
{
x = tx;
y = ty;
z = tz;
}
};
cutii s[NMAX + 5];
int cmp(const cutii a , const cutii b)
{
return a.x < b.x;
}
int aib[NMAX + 5][NMAX + 5] , n;
int query(int x , int y)
{
int i , j , lg = 0;
for(i = x ; i > 0 ; i = i - (i & (-i)))
for(j = y ; j > 0 ; j = j - (j & (-j)))
lg = max(lg , aib[i][j]);
return lg;
}
void update(int x , int y , int val)
{
int i , j;
for(i = x ; i <= n ; i = i + (i & (-i)))
for(j = y ; j <= n; j = j + (j & (-j)))
aib[i][j] = max(aib[i][j] , val);
}
int main()
{
freopen("cutii.in" , "r" , stdin);
freopen("cutii.out" , "w" , stdout);
int t , i , k , aux , maxim , x , y , z , j , l;
get_int(n);
get_int(t);
for(k = 1 ; k <= t ; k ++)
{
for(i = 1 ; i <= n ; i ++)
{
get_int(x);
get_int(y);
get_int(z);
s[i] = cutii(x , y , z);
}
sort(s + 1 , s + n + 1 , cmp);
memset(aib , 0 , sizeof(aib));
maxim = 0;
for(i = 1 ; i <= n ; i ++)
{
aux = query(s[i].y , s[i].z) + 1;
maxim = max(maxim , aux);
update(s[i].y , s[i].z , aux);
}
printf("%d\n" , maxim);
}
return 0;
}