#include<bits/stdc++.h>
using namespace std;
ifstream fin("cutii.in");
ofstream fout("cutii.out");
#define N 3501
struct str {
int a, b, c;
};
int n, t, cnt, viz[N], L[N], R[N];
str cutii[N];
vector<vector<int> > g(N, vector<int>());
bool cuplaj(int nod);
void readAndEstablish();
void reset();
int main() {
fin >> n >> t;
while (t--) {
reset();
readAndEstablish();
bool ok = true;
while (ok == true) // cat timp se mai poate cupla un nod
{
ok = false;
memset(viz, 0, sizeof(viz));
for (int i = 1; i <= n; ++i)
if (!L[i] and cuplaj(i))
ok = true;
}
for (int i = 1; i <= n; ++i)
if (L[i] || R[i + n])
++cnt;
fout << cnt << "\n";
}
}
bool cuplaj(int nod) // daca nod se poate cupla cu cineva
{
if (viz[nod] == true)
return false;
viz[nod] = true;
for (auto y : g[nod])
if (!R[y] || cuplaj(R[y])) // y nu a fost cuplat pana acum, y se afla in partea dreapta
{
L[nod] = y;
R[y] = nod;
return true;
}
return false;
}
void readAndEstablish() {
for (int i = 1; i <= n; ++i)
fin >> cutii[i].a >> cutii[i].b >> cutii[i].c;
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= n; ++j)
if (i != j && cutii[i].a > cutii[j].a && cutii[i].b > cutii[j].b && cutii[i].c > cutii[j].c)
g[i].push_back(j + n);
}
void reset() {
for (int i = 1; i <= n; ++i) {
g[i].clear();
L[i] = R[i + n] = 0;
}
cnt = 0;
}