#include <bits/stdc++.h>
using namespace std;
ifstream fin("cutii.in");
ofstream fout("cutii.out");
const int MOD = 9917;
const int NMax = 3550;
struct var {
int a, b, c;
} v[NMax];
int aib[NMax][NMax];
var update[NMax];
bool cmp(const var &a, const var &b) {
return a.c < b.c;
}
int Query(int x, int y) {
int ret = 0;
for(int i = x; i > 0; i -= ((-i) & i)) {
for(int j = y; j > 0; j -= ((-j) & j)) {
ret = max(ret, aib[i][j]);
}
}
return ret;
}
void Update(int x, int y, int val, int n) {
for(int i = x; i <= n; i += ((-i) & i)) {
for(int j = y; j <= n; j += ((-j) & j)) {
aib[i][j] = max(aib[i][j], val);
}
}
}
void Free(int x, int y, int n) {
for(int i = x; i <= n; i += ((-i) & i)) {
for(int j = y; j <= n; j += ((-j) & j)) {
aib[i][j] = 0;
}
}
}
int main() {
int n, t;
fin >> n >> t;
while(t--) {
for(int i = 1; i <= n; ++i) {
int a, b, c;
fin >> a >> b >> c;
v[i] = {a, b, c};
}
v[n + 1] = {-1, -1, -1};
sort(v + 1, v + n + 1, cmp);
int pos = 0;
for(int i = 1; i <= n; ++i) {
if(v[i].c == v[i + 1].c) {
update[++pos] = v[i];
update[pos].c = Query(v[i].a - 1, v[i].b - 1);
} else {
update[++pos] = v[i];
update[pos].c = Query(v[i].a - 1, v[i].b - 1);
for(int j = 1; j <= pos; ++j) {
Update(update[j].a, update[j].b, update[j].c + 1, n);
}
pos = 0;
}
}
fout << Query(n, n) << "\n";
for(int i = 1; i <= n; ++i) {
Free(v[i].a, v[i].b, n);
}
}
return 0;
}