#include <cstdio>
#include <queue>
#include <algorithm>
#include <cstdlib>
#include <vector>
#include <cmath>
#include <cstring>
#include <map>
#include <iostream>
using namespace std;
inline int gi(){
char tmp=getchar();int ans=0;
while(!isdigit(tmp)) tmp=getchar();
while(isdigit(tmp)){
ans=ans*10+tmp-'0';
tmp=getchar();
}
return ans;
}
const int N = 2130000;
#define M N
struct Edg{int v,nxt;}Edge[M*1+(M>>1)];int Head[N];
inline void Add(int u,int v){
//printf("%d %d\n",u,v);
static int cnt = 0;Edge[++cnt].v=v;Edge[cnt].nxt=Head[u];Head[u]=cnt;
}
#define pa pair<int,int>
pa Pa;
map<pa,int> Map;
const int Mov[9][3]={{1,-1},{1,0},{1,1},{0,-1},{0,1},{-1,-1},{-1,0},{-1,1}};
int Xx[N],Yy[N];
int Dfn[N],Low[N],tim,Stack[N],Sccno[N],scc,top,Sv[M];
int ans;
int n,r,c;
void Tarjan(int pos){
Dfn[pos] = Low[pos] = ++tim ;Stack[++top]=pos;
for(int i=Head[pos];i;i=Edge[i].nxt){
int arr = Edge[i].v;
if(!Dfn[arr]){
Tarjan(arr);
Low[pos] = min(Low[pos],Low[arr]);
}
else if (!Sccno[arr])
Low[pos] = min(Low[pos],Dfn[arr]);
}
if(Low[pos] == Dfn[pos]){
scc++;
//printf("%d:",scc);
while(1){
int x = Stack[top--];
//printf("%d ",x);
Sccno[x] = scc;
Sv[scc] += (x>(r+c));
if(x==pos)
//return void(puts(""));
return;
}
}
}
vector<int> E[M];
int Deg[N],Dp[M];
signed main()
{
#ifdef TSUKIAKIOI
freopen("data.in","r",stdin);
#endif
n=gi(),r=gi(),c=gi();
for(int i=1;i<=n;++i){
int t,x,y;
x=gi(),y=gi(),t=gi();
Add(x,r+c+i);Add(y+r,r+c+i);
if(t==1) Add(r+c+i,x);
if(t==2) Add(r+c+i,y+r);
if(t==3) Xx[i]=x,Yy[i]=y;
Map[pa(x,y)]=i; // 为每一个点分配编号
}
for(int i=1;i<=n;++i){
if(!Xx[i])
continue;
for(int j=0;j<8;++j){
int nx = Xx[i] + Mov[j][0];
int ny = Yy[i] + Mov[j][1];
if(!Map.count(pa(nx,ny))) continue;
int p=Map[pa(nx,ny)];
if(!p) continue;
Add(r+c+i,p+r+c);
}
}
for(int i=1;i<=r+c+n;++i)
if(!Dfn[i])
Tarjan(i);
for(int i=1;i<=r+c+n;++i){
for(int j=Head[i];j;j=Edge[j].nxt){
int arr =Edge[j].v;
int u = Sccno[i],v=Sccno[arr];
if(u == v) continue;
E[u].push_back(v);
Deg[v]++;
}
// printf("%d %d\n",u,v);
}
queue<int> Q;
// puts("")c
for(int i=1;i<=scc;++i){
// printf("%d ",Sv[i]);
if(!Deg[i])
Q.push(i);
}
int ans = 0;
while(!Q.empty()){
int pos = Q.front();Q.pop();
Dp[pos] = max(Dp[pos],Sv[pos]);
ans = max(Dp[pos],ans);
for(int i = 0;i<E[pos].size();++i){
int arr = E[pos][i];
Dp[arr] = max(Dp[arr],Dp[pos] + Sv[arr]);
Deg[arr]--;
if(!Deg[arr])
Q.push(arr);
}
}
printf("%d",ans);
return 0;
}