#include<bits/stdc++.h>
using namespace std;
const int maxn=3e5+10;
int pa[maxn],sz[maxn],val[maxn];
struct edge{
    int u,v,w;
    bool operator <(const edge &x)const {
        return w>x.w;
    }
    void read(){
        scanf("%d%d%d",&u,&v,&w);
    }
}e[maxn];
int fi(int x){
    return pa[x]==x?x:pa[x]=fi(pa[x]);
}
bool Merge(int x,int y){
    x=fi(x);
    y=fi(y);
    if(x==y){
        if(val[x]<sz[x]){
            val[x]++;
            return true;
        }
        return false;
    }
    else{
        if(val[x]+val[y]+1>sz[x]+sz[y])return false;
        if(sz[x]<sz[y])swap(x,y);
        sz[x]+=sz[y];
        val[x]+=(val[y]+1);
        pa[y]=x;
    }
    return true;
}

/*
Note:
    At first, Turning grid into bipartite graph
    Notice that we must assign each number from both sides to each row and column
    Claim 1: There are no triple multiple loops
    Claim 2: If the number of node is not greater than the number of edges we can assign such thing
*/
int n,r,c;

int main(){
    scanf("%d%d%d",&n,&r,&c);
    for(int i=1;i<=n;i++){
        e[i].read();
        e[i].v+=r;
        pa[e[i].u]=e[i].u;
        pa[e[i].v]=e[i].v;
        sz[e[i].u]=1;
        sz[e[i].v]=1;
    }
    sort(e+1,e+1+n);
    //for(int i=1;i<=n;i++)
       // e[i].print();
    long long ans=0;
    for(int i=1;i<=n;i++){
        if(Merge(e[i].u,e[i].v)){
            ans+=e[i].w;
        }
    }
    printf("%lld\n",ans);
}
/*
    Good Luck
        -Lucina
*/
