#include <bits/stdc++.h>
using namespace std;
const int maxn=3e5+10;
int fx[9]={0,1,1,1,0,0,-1,-1,-1};
int fy[9]={0,1,0,-1,1,-1,1,0,-1};
int n,r,c,cnt;
struct node{
int id,x,y,type;
};
vector <node> v1,v2,v3;
bool cmp1(node a,node b){
return a.y<=b.y;
}
bool cmp2(node a,node b){
return a.x<=b.x;
}
int a[maxn];
struct edge{
int to,nxt,fr;
}e[maxn<<2];
int head[maxn<<2];
int tot,in[maxn];
void add(int u,int v,int opt){
if(opt==1) a[u]=1;
else a[v]=1;
e[++tot].to=v;
e[tot].nxt=head[u];
e[tot].fr=u;
head[u]=tot;
}
map <pair<int,int>,int> mem;
void init(){
sort(v1.begin(),v1.end(),cmp1);
int p=++cnt;
add(p,0,-1);
for (int i=0;i<v1.size();i++){
int u=mem.find(make_pair(v1[i].x,v1[i].y))->second;
if(i==0){
if(v1[i].type!=1) add(p,u,0);
else add(u,p,1),add(p,u,0);
continue;
}
if(v1[i].y!=v1[i-1].y) p=++cnt,add(p,0,-1);
if(v1[i].type!=1) add(p,u,0);
else add(u,p,1),add(p,u,0);
}
sort(v2.begin(),v2.end(),cmp2);
p=++cnt;add(p,0,-1);
for (int i=0;i<v2.size();i++){
pair <int,int> tmp=make_pair(v2[i].x,v2[i].y);
int u=mem.find(tmp)->second;
if(i==0){
if(v2[i].type!=2) add(p,u,0);
else add(u,p,1),add(p,u,0);
continue;
}
if(v2[i].x!=v2[i-1].x) p=++cnt,add(p,0,-1);
if(v2[i].type!=2) add(p,u,0);
else add(u,p,1),add(p,u,0);
}
for (int i=0;i<v3.size();i++){
int x=v3[i].x,y=v3[i].y;
if(v3[i].type!=3) continue;
for (int i=1;i<=8;i++){
int xx=x+fx[i],yy=y+fy[i];
if(xx>r||xx<1||yy>c||yy<1) continue;
if(mem.find(make_pair(xx,yy))!=mem.end()){
int u,v;
v=mem.find(make_pair(xx,yy))->second;
u=mem.find(make_pair(x,y))->second;
add(u,v,1);
}
}
}
}
int dfn[maxn],low[maxn],tim,st[maxn],st_cnt,scc[maxn],scc_cnt,scc_val[maxn];
bool in_st[maxn];
void tarjan(int s){
dfn[s]=++tim;low[s]=tim;
st[++st_cnt]=s;in_st[s]=true;
for (int i=head[s];i;i=e[i].nxt){
int v=e[i].to;
if(dfn[v]==0) tarjan(v),low[s]=min(low[s],low[v]);
else if(in_st[v]) low[s]=min(low[s],dfn[v]);
}
if(low[s]==dfn[s]){
scc_cnt++;
while(st[st_cnt]!=s){
int nw=st[st_cnt];
scc[nw]=scc_cnt;
scc_val[scc_cnt]+=a[nw];
in_st[nw]=false;
st_cnt--;
}
scc[s]=scc_cnt;
scc_val[scc_cnt]+=a[s];
in_st[s]=false;
st_cnt--;
}
}
int dis[maxn];
vector <int> g[maxn];
void topo(){
queue <int> q;
for (int i=1;i<=scc_cnt;i++){
dis[i]=~0x3f3f3f3f;
if(in[i]==0)
q.push(i),dis[i]=scc_val[i];
}
while(!q.empty()){
int nw=q.front();
q.pop();
for (int i=0;i<g[nw].size();i++){
int v=g[nw][i];
in[v]--;
if(in[v]==0) q.push(v);
dis[v]=max(dis[v],dis[nw]+scc_val[v]);
}
}
}
int main(){
scanf("%d%d%d",&n,&r,&c);
for (int i=1;i<=n;i++){
node tmp;
tmp.id=i;
scanf("%d%d%d",&tmp.x,&tmp.y,&tmp.type);
cnt++;
mem.insert({make_pair(tmp.x,tmp.y),cnt});
v1.push_back(tmp);
v2.push_back(tmp);
v3.push_back(tmp);
}
init();
for (int i=0;i<=cnt;i++)
if(dfn[i]==0)
tarjan(i);
for (int i=0;i<=tot;i++){
int u=e[i].fr,v=e[i].to;
if(scc[u]!=scc[v]) in[scc[v]]++,g[scc[u]].push_back(scc[v]);
}
topo();
int ans=-1;
for (int i=1;i<=scc_cnt;i++)
ans=max(ans,dis[i]);
printf("%d",ans);
return 0;
}