#include<algorithm>
#include<iostream>
#include<cstring>
#include<vector>
#include<queue>
#include<stack>
#include<map>
using namespace std;
const int N=3e6+5e5;
int tx[10]={-1,-1,0,1,1,1,0,-1};
int ty[10]={0,1,1,1,0,-1,-1,-1};
struct node{
int to,nxt;
}e1[N],e2[N],xx[N],yy[N];
int h1[N],h2[N];
int cnt1,cnt2;
void add1(int u,int v){
e1[++cnt1]={v,h1[u]};
h1[u]=cnt1;
}
void add2(int u,int v){
e2[++cnt2]={v,h2[u]};
h2[u]=cnt2;
}
int qlt;
int qlcnt[N],trans[N];
int t,dfn[N],low[N];
bool vst[N];
stack<int> stk;
void dfs(int x){
dfn[x]=++t;
low[x]=dfn[x];
stk.push(x);
vst[x]=true;
for(int i=h1[x];i!=-1;i=e1[i].nxt){
if(!dfn[e1[i].to]){
dfs(e1[i].to);
low[x]=min(low[x],low[e1[i].to]);
}else if(vst[e1[i].to]){
low[x]=min(low[x],dfn[e1[i].to]);
}
}
if(low[x]==dfn[x]){
qlt++;
while(stk.top()!=x){
int tmp=stk.top();
stk.pop();
vst[tmp]=false;
qlcnt[qlt]++;
trans[tmp]=qlt;
}
stk.pop();
vst[x]=false;
trans[x]=qlt;
qlcnt[qlt]++;
}
}
queue<int> q;
int f[N],in[N];
int n,r,c,ans;
long long hassh(long long xxx,long long yyy){
return xxx*(r-1)+yyy;
}
struct dor{
int x,y,t;
}dl[N];
bool cmp(dor pre,dor nxt){
if(pre.x!=nxt.x) return pre.x<nxt.x;
else return pre.y<nxt.y;
}
int xxcnt,yycnt;
int xxv[N],yyv[N];
map<long long,int> app;
signed main(){
ios::sync_with_stdio(false);
memset(h1,-1,sizeof(h1));
memset(h2,-1,sizeof(h2));
memset(xxv,-1,sizeof(xxv));
memset(yyv,-1,sizeof(yyv));
cin>>n>>r>>c;
for(int i=1;i<=n;i++){
cin>>dl[i].x>>dl[i].y>>dl[i].t;
xx[++xxcnt]={i,xxv[dl[i].x]};
xxv[dl[i].x]=xxcnt;
yy[++yycnt]={i,yyv[dl[i].y]};
yyv[dl[i].y]=yycnt;
app[hassh(dl[i].x,dl[i].y)]=i;
}
for(int i=1;i<=n;i++){
if(dl[i].t==1){
for(int j=xxv[dl[i].x];j!=-1;j=xx[j].nxt){
if(xx[j].to==i) continue;
add1(i,xx[j].to);
}
}else if(dl[i].t==2){
for(int j=yyv[dl[i].y];j!=-1;j=yy[j].nxt){
if(yy[j].to==i) continue;
add1(i,yy[j].to);
}
}else{
for(int j=0;j<8;j++){
int nx=dl[i].x+tx[j],ny=dl[i].y+ty[j];
if(nx<0||nx>r||ny<0||ny>c) continue;
if(app[hassh(nx,ny)]) add1(i,app[hassh(nx,ny)]);
}
}
}
for(int i=1;i<=n;i++){
if(!dfn[i]){
dfs(i);
}
}
for(int i=1;i<=n;i++){
for(int j=h1[i];j!=-1;j=e1[j].nxt){
if(trans[i]!=trans[e1[j].to]){
add2(trans[i],trans[e1[j].to]);
in[trans[e1[j].to]]++;
}
}
}
for(int i=1;i<=qlt;i++){
if(!in[i]){
q.push(i);
f[i]=qlcnt[i];
}
}
while(!q.empty()){
int x=q.front();
q.pop();
for(int i=h2[x];i!=-1;i=e2[i].nxt){
f[e2[i].to]=max(f[e2[i].to],f[x]+qlcnt[e2[i].to]);
in[e2[i].to]--;
if(!in[e2[i].to]) q.push(e2[i].to);
}
}
for(int i=1;i<=qlt;i++){
ans=max(ans,f[i]);
}
cout<<ans;
return 0;
}