#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 3502;
struct Cutie {
int x, y, z;
};
class MyComp {
public:
bool operator () (const Cutie &A, const Cutie &B) {
return A.x < B.x || (A.x == B.x && A.y < B.y);
}
};
int n, dp [N], aib [N][N];
Cutie C [N];
void read () {
int i;
for (i = 1; i <= n; i ++)
scanf ("%d%d%d", &C [i].x, &C [i].y, &C [i].z);
}
int lsb (int x) {
return x & (-x);
}
void resetz (int y, int z, int value) {
int i;
for (i = z; i <= n; i = i + lsb (i))
aib [y][i] = 0;
}
void resety (int y, int z, int value) {
int i;
for (i = y; i <= n; i = i + lsb (i))
resetz (i, z, value);
}
void updatez (int y, int z, int value) {
int i;
for (i = z; i <= n; i = i + lsb (i))
aib [y][i] = max (aib [y][i], value);
}
void updatey (int y, int z, int value) {
int i;
for (i = y; i <= n; i = i + lsb (i))
updatez (i, z, value);
}
int queryz (int y, int z) {
int ans = 0, i;
for (i = z; i > 0; i = i - lsb (i))
ans = max (ans, aib [y][i]);
return ans;
}
int queryy (int y, int z) {
int ans = 0, i;
for (i = y; i > 0; i = i - lsb (i))
ans = max (ans, queryz (i, z));
return ans;
}
void solve () {
int i, ans = 1;
sort (C + 1, C + 1 + n, MyComp ());
dp [1] = 1;
updatey (C [1].y, C [1].z, dp [1]);
for (i = 2; i <= n; i ++) {
dp [i] = queryy (C [i].y, C [i].z) + 1;
ans = max (ans, dp [i]);
updatey (C [i].y, C [i].z, dp [i]);
}
printf ("%d\n", ans);
for (i = 1; i <= n; i ++)
resety (C [i].y, C [i].z, 0);
}
int main () {
int t, T;
freopen ("cutii.in", "r", stdin);
freopen ("cutii.out", "w", stdout);
scanf ("%d%d", &n, &T);
for (t = 1; t <= T; t ++) {
read ();
solve ();
}
return 0;
}