/*
分析:
哎呀,在用C提交ac的里面竟然排第一呀,so~吃惊呀~
最小路径覆盖,如果i可以放到j里面,那么就构建一条
i到j的有向边。
2012-07-14
*/
分析:
哎呀,在用C提交ac的里面竟然排第一呀,so~吃惊呀~
最小路径覆盖,如果i可以放到j里面,那么就构建一条
i到j的有向边。
2012-07-14
*/
#include"stdio.h"
#include"string.h"
struct A
{
int total;
int mem[555];
}E[555];
struct B
{
int x,y,z;
}coor[555];
int match[555];
int visit[555];
int DFS(int k)
{
int i;
for(i=0;i<E[k].total;i++)
{
if(visit[E[k].mem[i]]) continue;
visit[E[k].mem[i]]=1;
if(match[E[k].mem[i]]==0 || DFS(match[E[k].mem[i]]))
{
match[E[k].mem[i]]=k;
return 1;
}
}
return 0;
}
int main()
{
int n;
int i,l;
int ans;
while(scanf("%d",&n),n)
{
for(i=1;i<=n;i++)
{
E[i].total=0;
scanf("%d%d%d",&coor[i].x,&coor[i].y,&coor[i].z);
}
for(i=1;i<=n;i++)
for(l=1;l<=n;l++)
{
if(i==l) continue;
if(coor[l].x>coor[i].x&&coor[l].y>coor[i].y&&coor[l].z>coor[i].z)
E[i].mem[E[i].total++]=l;
}
ans=0;
memset(match,0,sizeof(match));
for(i=1;i<=n;i++)
{
if(E[i].total==0) continue;
memset(visit,0,sizeof(visit));
ans+=DFS(i);
}
ans=n-ans;
printf("%d\n",ans);
}
return 0;
}