Cod sursa(job #253565)
#include <cstdio>
#include <algorithm>
using namespace std;
#define MAX_N 3505
#define lsb(x) (x & -x)
struct lx{int x, y, z;} A[MAX_N];
int N, T, Deg[MAX_N];
int AIB[MAX_N][MAX_N];
int Sol = 0;
struct cmp
{
bool operator () (const lx a, const lx b) const
{
if(a.x < b.x) return 1;
if(a.x == b.x && a.y > b.y) return 1;
if(a.x == b.x && a.y == b.y && a.z > b.z) return 1;
return 0;
}
};
void update(int x, int y, int val)
{
for(int i = x; i <= N; i += lsb(i))
for(int j = y; j <= N; j += lsb(j))
if(val == 0)
AIB[i][j] = 0;
else
AIB[i][j] = max(AIB[i][j], val);
}
int query(int x, int y)
{
int rez = 0;
if(x == 0 || y == 0) return 0;
for(int i = x; i <= N; i += lsb(i))
for(int j = y; j <= N; j += lsb(j))
rez = max(rez, AIB[i][j]);
return rez;
}
void solve()
{
for(int i = 0; i < N; ++i)
scanf("%d %d %d",&A[i].x, &A[i].y, &A[i].z);
sort(A, A+N, cmp());
Sol = 0;
for(int i = 0; i < N; ++i)
{
Deg[i] = query(A[i].y-1, A[i].z-1) + 1;
update(A[i].y, A[i].z, Deg[i]);
Sol = max(Sol, Deg[i]);
}
for(int i = 0; i < N; ++i)
update(A[i].y, A[i].z, 0);
printf("%d\n", Sol);
}
int main()
{
freopen("cutii.in","rt",stdin);
freopen("cutii.out","wt",stdout);
scanf("%d %d",&N, &T);
while(T--)
solve();
}