#include<bits/stdc++.h>
#define SIZE 200005
 
using namespace std;
typedef long long int ll;
typedef pair <int,int> P;
typedef pair <int,P> PP;
 
struct UF
{
	int par[SIZE],rank[SIZE];
	int sz[SIZE];
	
	void init(int n)
	{
		for(int i=0;i<n;i++)
		{
			par[i]=i;
			rank[i]=1;
			sz[i]=-1;
		}
	}
	int find(int x)
	{
		if(x==par[x]) return x;
		return par[x]=find(par[x]);
	}
	int get(int v)
	{
		return sz[find(v)];
	}
	void unite(int x,int y)
	{
		x=find(x);
		y=find(y);
		if(x==y)
		{
			sz[x]++;
			return;
		}
		if(rank[x]<rank[y])
		{
			par[x]=y;
			sz[y]+=sz[x];
			sz[y]++;
		}
		else
		{
			par[y]=x;
			sz[x]+=sz[y];
			sz[x]++;
			if(rank[x]==rank[y]) rank[x]++;
		}
	}
	bool same(int x,int y)
	{
		return find(x)==find(y);
	}
}uf;
vector <PP> edge;
bool use[SIZE];
 
int main()
{
	int n,h,w;
	scanf("%d %d %d",&n,&h,&w);
	for(int i=0;i<n;i++)
	{
		int r,c,a;
		scanf("%d %d %d",&r,&c,&a);r--,c--;
		edge.push_back(PP(a,P(r,c+h)));
	}
	sort(edge.begin(),edge.end(),greater<PP>());
	uf.init(h+w+2);
	ll ret=0;
	for(int i=0;i<edge.size();i++)
	{
		P p=edge[i].second;
		int a=uf.get(p.first),b=uf.get(p.second);
		if(a+b+1<=0)
		{
			uf.unite(p.first,p.second);
			ret+=edge[i].first;
			use[i]=true;
			//printf("* %d %d : %d\n",p.first,p.second,edge[i].first);
		}
	}
	printf("%lld\n",ret);
	return 0;
}