#include <bits/stdc++.h>
 
using namespace std;
 
template <class T>inline T updmax(T& a, T b) {return a = max(a, b);}
template <class T>inline T updmin(T& a, T b) {return a = min(a, b);}

class UnionFind {
	vector<int> data, data2;
	public:
	UnionFind(int size) : data(size, -1), data2(size, 0) { }
	bool unionSet(int x, int y) {
		x = root(x); y = root(y);
		if (x != y) {
			if (data[y] < data[x]) swap(x, y);
			data[x] += data[y]; data[y] = x;
			data2[x] += data2[y]; data2[y] = 0;
		}
		return x != y;
	}
	bool findSet(int x, int y) {
		return root(x) == root(y);
	}
	int root(int x) {
		return data[x] < 0 ? x : data[x] = root(data[x]);
	}
	int size(int x) {
		return -data[root(x)];
	}
	bool add(int x){
		if(-data[root(x)] > data2[root(x)]){
			data2[root(x)]++;
			return true;
		}
		return false;
	}
};

class Solution {
public:
	void solve() {
		int n, h, w;
		cin >> n >> h >> w;
		using cd = tuple<int, int, int>;
		vector<cd> cds(n);
		for(int i=0; i < n; i++){
			int r, c, a;
			cin >> r >> c >> a;
			cds[i] = make_tuple(a, r-1, c-1);
		}
		sort(cds.begin(), cds.end(), greater<tuple<int, int, int>>());
		long long ret = 0;
		UnionFind uf(h + w);
		for(int i=0; i < n; i++){
			int a,r,c;
			tie(a,r,c) = cds[i];
			uf.unionSet(r, h+c);
			if(uf.add(r))ret += a;
		}
		cout << ret << "\n";
		return;
	};
};
 
int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(nullptr);
	Solution solution;
	solution.solve();
	return 0;
}