1. #include <cstdio>
    2. #include <queue>
    3. #include <algorithm>
    4. #include <cstdlib>
    5. #include <vector>
    6. #include <cmath>
    7. #include <cstring>
    8. #include <map>
    9. #include <iostream>
    10. using namespace std;
    11. inline int gi(){
    12. char tmp=getchar();int ans=0;
    13. while(!isdigit(tmp)) tmp=getchar();
    14. while(isdigit(tmp)){
    15. ans=ans*10+tmp-'0';
    16. tmp=getchar();
    17. }
    18. return ans;
    19. }
    20. const int N = 2130000;
    21. #define M N
    22. struct Edg{int v,nxt;}Edge[M*1+(M>>1)];int Head[N];
    23. inline void Add(int u,int v){
    24. //printf("%d %d\n",u,v);
    25. static int cnt = 0;Edge[++cnt].v=v;Edge[cnt].nxt=Head[u];Head[u]=cnt;
    26. }
    27. #define pa pair<int,int>
    28. pa Pa;
    29. map<pa,int> Map;
    30. const int Mov[9][3]={{1,-1},{1,0},{1,1},{0,-1},{0,1},{-1,-1},{-1,0},{-1,1}};
    31. int Xx[N],Yy[N];
    32. int Dfn[N],Low[N],tim,Stack[N],Sccno[N],scc,top,Sv[M];
    33. int ans;
    34. int n,r,c;
    35. void Tarjan(int pos){
    36. Dfn[pos] = Low[pos] = ++tim ;Stack[++top]=pos;
    37. for(int i=Head[pos];i;i=Edge[i].nxt){
    38. int arr = Edge[i].v;
    39. if(!Dfn[arr]){
    40. Tarjan(arr);
    41. Low[pos] = min(Low[pos],Low[arr]);
    42. }
    43. else if (!Sccno[arr])
    44. Low[pos] = min(Low[pos],Dfn[arr]);
    45. }
    46. if(Low[pos] == Dfn[pos]){
    47. scc++;
    48. //printf("%d:",scc);
    49. while(1){
    50. int x = Stack[top--];
    51. //printf("%d ",x);
    52. Sccno[x] = scc;
    53. Sv[scc] += (x>(r+c));
    54. if(x==pos)
    55. //return void(puts(""));
    56. return;
    57. }
    58. }
    59. }
    60. vector<int> E[M];
    61. int Deg[N],Dp[M];
    62. signed main()
    63. {
    64. #ifdef TSUKIAKIOI
    65. freopen("data.in","r",stdin);
    66. #endif
    67. n=gi(),r=gi(),c=gi();
    68. for(int i=1;i<=n;++i){
    69. int t,x,y;
    70. x=gi(),y=gi(),t=gi();
    71. Add(x,r+c+i);Add(y+r,r+c+i);
    72. if(t==1) Add(r+c+i,x);
    73. if(t==2) Add(r+c+i,y+r);
    74. if(t==3) Xx[i]=x,Yy[i]=y;
    75. Map[pa(x,y)]=i; // 为每一个点分配编号
    76. }
    77. for(int i=1;i<=n;++i){
    78. if(!Xx[i])
    79. continue;
    80. for(int j=0;j<8;++j){
    81. int nx = Xx[i] + Mov[j][0];
    82. int ny = Yy[i] + Mov[j][1];
    83. if(!Map.count(pa(nx,ny))) continue;
    84. int p=Map[pa(nx,ny)];
    85. if(!p) continue;
    86. Add(r+c+i,p+r+c);
    87. }
    88. }
    89. for(int i=1;i<=r+c+n;++i)
    90. if(!Dfn[i])
    91. Tarjan(i);
    92. for(int i=1;i<=r+c+n;++i){
    93. for(int j=Head[i];j;j=Edge[j].nxt){
    94. int arr =Edge[j].v;
    95. int u = Sccno[i],v=Sccno[arr];
    96. if(u == v) continue;
    97. E[u].push_back(v);
    98. Deg[v]++;
    99. }
    100. // printf("%d %d\n",u,v);
    101. }
    102. queue<int> Q;
    103. // puts("")c
    104. for(int i=1;i<=scc;++i){
    105. // printf("%d ",Sv[i]);
    106. if(!Deg[i])
    107. Q.push(i);
    108. }
    109. int ans = 0;
    110. while(!Q.empty()){
    111. int pos = Q.front();Q.pop();
    112. Dp[pos] = max(Dp[pos],Sv[pos]);
    113. ans = max(Dp[pos],ans);
    114. for(int i = 0;i<E[pos].size();++i){
    115. int arr = E[pos][i];
    116. Dp[arr] = max(Dp[arr],Dp[pos] + Sv[arr]);
    117. Deg[arr]--;
    118. if(!Deg[arr])
    119. Q.push(arr);
    120. }
    121. }
    122. printf("%d",ans);
    123. return 0;
    124. }