#include <bits/stdc++.h>
using namespace std;
const int nmax = 8192;
uint8_t ai[nmax][nmax];
void update(int nod1, int nod2, int l1, int r1, int l2, int r2, int x, int y, uint8_t val)
{
if(l1 == r1 && l2 == r2)
{
ai[nod1][nod2] = max(ai[nod1][nod2], val);
return;
}
int m1 = (l1 + r1) / 2;
int m2 = (l2 + r2) / 2;
if(x <= m1)
{
if(y <= m2)
update(2 * nod1 + 1, 2 * nod2 + 1, l1, m1, l2, m2, x, y, val);
else
update(2 * nod1 + 1, 2 * nod2 + 2, l1, m1, m2 + 1, r2, x, y, val);
}
else
{
if(y <= m2)
update(2 * nod1 + 2, 2 * nod2 + 1, m1 + 1, r1, l2, m2, x, y, val);
else
update(2 * nod1 + 2, 2 * nod2 + 2, m1 + 1, r1, m2 + 1, r2, x, y, val);
}
for(int i = 1;i <= 2;++i)
for(int j = 1;j <= 2;++j)
ai[nod1][nod2] = max(ai[nod1][nod2], ai[2 * nod1 + i][2 * nod2 + j]);
}
int query(int nod1, int nod2, int l1, int r1, int l2, int r2, int lx, int rx, int ly, int ry)
{
if(lx <= l1 && r1 <= rx && ly <= l2 && r2 <= ry)
return ai[nod1][nod2];
int m1 = (l1 + r1) / 2;
int m2 = (l2 + r2) / 2;
int ans = 0;
if(lx <= m1)
{
if(ly <= m2)
ans = max(ans, query(2 * nod1 + 1, 2 * nod2 + 1, l1, m1, l2, m2, lx, rx, ly, ry));
if(ry > m2)
ans = max(ans, query(2 * nod1 + 1, 2 * nod2 + 2, l1, m1, m2 + 1, r2, lx, rx, ly, ry));
}
if(rx > m1)
{
if(ly <= m2)
ans = max(ans, query(2 * nod1 + 2, 2 * nod2 + 1, m1 + 1, r1, l2, m2, lx, rx, ly, ry));
if(ry > m2)
ans = max(ans, query(2 * nod1 + 2, 2 * nod2 + 2, m1 + 1, r1, m2 + 1, r2, lx, rx, ly, ry));
}
return ans;
}
int solve(vector<vector<int>>& v)
{
sort(v.begin(), v.end());
int n = v.size(), ans = 0;
ai.clear();
for(int i = 0;i < n;++i)
{
int ret = query(0, 0, 0, n, 0, n, 0, v[i][1] - 1, 0, v[i][2] - 1);
ans = max(ans, ret + 1);
update(0, 0, 0, n, 0, n, v[i][1], v[i][2], ret + 1);
}
return ans;
}
int main() {
freopen("cutii.in", "r", stdin);
freopen("cutii.out", "w", stdout);
int n, t;
cin >> n >> t;
for(int i = 0;i < t;++i)
{
vector<vector<int>> v(n, vector<int>(3));
for(int j = 0;j < n;++j)
cin >> v[j][0] >> v[j][1] >> v[j][2];
cout << solve(v) << "\n";
}
}