#include<bits/stdc++.h>
using namespace std;

#define int long long

#define rep(i,n) for(int i=0;i<(n);i++)
#define pb push_back
#define all(v) (v).begin(),(v).end()
#define fi first
#define se second
typedef vector<int>vint;
typedef pair<int,int>pint;
typedef vector<pint>vpint;

template<typename A,typename B>inline void chmin(A &a,B b){if(a>b)a=b;}
template<typename A,typename B>inline void chmax(A &a,B b){if(a<b)a=b;}

struct UnionFindTree{
    vector<int>par,sz,uku;
    UnionFindTree(int n){
        par.resize(n);
        sz.resize(n);
		uku.resize(n);
        for(int i=0;i<n;i++){
            par[i]=i;
            sz[i]=1;
			uku[i]=0;
        }
    }
    int find(int x){
        return x==par[x]?x:par[x]=find(par[x]);
    }
    void unite(int x,int y){
        x=find(x);y=find(y);
        if(x==y)return;
        if(sz[x]<sz[y])swap(x,y);
        sz[x]+=sz[y];
        par[y]=x;
		uku[x]|=uku[y];
    }
    bool areSame(int x,int y){
        return find(x)==find(y);
    }
    int size(int x){
        return sz[find(x)];
    }
};

int N,H,W;

signed main(){
	cin>>N>>H>>W;
	vector<tuple<int,int,int>>es;
	rep(i,N){
		int y,x,a;
		cin>>y>>x>>a;
		y--;x--;
		es.pb(make_tuple(a,y,x+H));
	}
	sort(all(es));reverse(all(es));

	int ans=0;
	UnionFindTree uf(H+W);
	for(auto &t:es){
		int a,y,x;
		tie(a,y,x)=t;
		if(uf.areSame(y,x)){
			if(uf.uku[uf.find(y)])continue;
			uf.uku[uf.find(y)]=1;
			ans+=a;	
		}
		else{
			if(uf.uku[uf.find(y)]&&uf.uku[uf.find(x)])continue;
			uf.unite(y,x);
			ans+=a;
		}
	}	
	cout<<ans<<endl;
	return 0;
}