/*
nota:
Acest program nu rezolva problema, deoarece am citit prost:
- in schimb face altceva(cred, sper): numarul minim de cutii ce trebuie selectate astfel incat
sa putem baga restul cutiilor in ele
* va urma si solutia la problema adevarata...
*/
#include <iostream>
#include <fstream>
#include <algorithm>
#include <stack>
using namespace std;
ifstream fin("cutii.in");
ofstream fout("cutii.out");
const int N = 3500;
struct pp{
int x, y, z;
}v[N + 1];
bool cmp(pp a, pp b){
if(a.x == b.x && a.y == b.y)
return a.z > b.z;
if(a.x = b.x)
return a.y > b.y;
return a.x > b.x;
}
struct AIB2d{
int aib[N + 1][N + 1], n;
AIB2d(){
for(int i = 0; i <= N; i++)
for(int j = 0; j <= N; j++)
aib[i][j] = 0;
}
int lsb(int x){
return x & -x;
}
void update(int iU, int jU, int val){
for(int i = iU; i <= n; i += lsb(i))
for(int j = jU; j <= n; j += lsb(j))
aib[i][j] += val;
}
int query(int iQ, int jQ){
int ans = 0;
for(int i = iQ; i >= 1; i -= lsb(i))
for(int j = jQ; j >= 1; j -= lsb(i))
ans += aib[i][j];
return ans;
}
void clear(){
int val = query(1, 1);
update(1, 1, -val);
}
};
AIB2d myAib;
void solve(int n){
myAib.clear();
myAib.n = n;
for(int i = 1; i <= n; i++)
fin >> v[i].x >> v[i].y >> v[i].z;
sort(v + 1, v + n + 1, cmp);
int ans = 0;
for(int i = 1; i <= n; i++){
int val = myAib.query(n, n) + myAib.query(v[i].y, v[i].z)
- myAib.query(v[i].y, n) - myAib.query(n, v[i].z);
if(val > 0)
myAib.update(v[i].y + 1, v[i].z + 1, -1);
else
ans++;
myAib.update(v[i].y, v[i].z, 1);
}
fout << ans << '\n';
}
int main(){
int n, T;
fin >> n >> T;
while(T--)
solve(n);
return 0;
}