#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;
}