#include<iostream>
#include<cstdio>
#include<stack>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<map>
using namespace std;
inline void read(int &x){
int f=1;
x=0;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')
f=-1;
ch=getchar();
}
while(ch<='9'&&ch>='0'){
x=x*10+ch-'0';
ch=getchar();
}
x*=f;
}
int dx[]={0,1,0,-1,1,1,-1,-1};
int dy[]={1,0,-1,0,-1,1,-1,1};
int n,r,c;
struct Front_star{
int u,v,w,nxt;
}edge[5000000],e[5000000],ee[5000000];
int cnt=0;
int first[500000]={0};
int head[500000]={0};
struct Node{
int x,y,t;
}pre[2000007]/*first array*/,nxt[2000007],a[2000007];
void addedge(int u,int v,int w){
cnt++;
e[cnt].u=u;
e[cnt].v=v;
e[cnt].w=w;
e[cnt].nxt=first[u];
first[u]=cnt;
}
void adde(int u,int v,int w){
cnt++;
ee[cnt].u=u;
ee[cnt].v=v;
ee[cnt].w=w;
ee[cnt].nxt=head[u];
head[u]=cnt;
}
void add(){
for(int i=1;i<=n;i++){
if(a[i].t==1){
for(int j=pre[a[i].x].x;j;j=nxt[j].x){
if(i==j){
continue;
}
addedge(i,j,1);
}
}
if(a[i].t==2){
for(int j=pre[a[i].y].y;j;j=nxt[j].y){
if(i==j){
continue;
}
addedge(i,j,1);
}
}
if(a[i].t==3){
for(int k=0;k<8;k++){
int xx=a[i].x+dx[k];
for(int j=pre[xx].x;j;j=nxt[j].x){
if(i==j)
continue;
if(abs(a[j].y-a[i].y)<=1)
addedge(i,j,1);
}
}
}
}
}
int tot=0;
//--------------
int low[500000]={0};
int dfn[500000]={0};
int color[500000]={0};
int siz[500000]={0};
int inqueue[500000]={0};
int scc=0;
stack<int> S;
void tarjan(int u){
tot++;
low[u]=dfn[u]=tot;
S.push(u);
inqueue[u]=1;
for(int i=first[u];i;i=e[i].nxt){
int v=e[i].v;
if(!dfn[v]){
tarjan(v);
low[u]=min(low[u],low[v]);
}
else{
if(inqueue[v]){
low[u]=min(low[u],dfn[v]);
}
}
}
if(low[u]==dfn[u]){
int x;
scc++;
do{
x=S.top();
S.pop();
color[x]=scc;
siz[scc]++;
inqueue[x]=0;
}while(x!=u);
}
}
int rd[500001]={0};
int cd[500001]={0};
int dis[500001]={0};
void SPFA(){
queue<int>q;
for(int i=1;i<=scc;i++){
if(rd[i]==0){
q.push(i);
dis[i]=siz[i];
}
}
while(!q.empty()){
int x=q.front();
q.pop();
for(int i=head[x];i;i=ee[i].nxt){
int v=ee[i].v;
if(rd[v]==0)
continue;
rd[v]--;
if(dis[v]<dis[x]+siz[v]){
dis[v]=dis[x]+siz[v];
}
if(!rd[v]){
q.push(v);
}
}
}
}
int main(){
read(n);
read(r);
read(c);
for(int i=1;i<=n;i++){
int x,y,t;
read(x);
read(y);
read(t);
a[i].x=x;
a[i].y=y;
a[i].t=t;
nxt[i].x=pre[x].x;
pre[x].x=i;
nxt[i].y=pre[y].y;
pre[y].y=i;
}
add();
for(int i=1;i<=n;i++){
if(!dfn[i]){
tarjan(i);
}
}
// cnt=0;
// memset(first,0,sizeof(first));
for(int i=1;i<=n;i++){
for(int j=first[i];j;j=e[j].nxt){
int v=e[j].v;
int u=i;
if(color[u]!=color[v]){
adde(color[u],color[v],1);
rd[color[v]]++;
cd[color[u]]++;
}
}
}
// for(int i=1;i<=scc;i++)
// cout<<rd[i]<<" "<<siz[i]<<endl;
SPFA();
int ans=-1;
// cout<<"4q382436939486724389279834"<<endl;
for(int i=1;i<=scc;i++){
ans=max(ans,dis[i]);
// cout<<siz[i]<<" "<<cd[i]<<endl;
}
cout<<ans;
}