// #define DEBUGGING
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define ALL(V) (V).begin(), (V).end()
#define ALLR(V) (V).rbegin(), (V).rend()

template <typename T> using V = vector<T>;
template <typename T> using VV = V<V<T>>;
using ll = int64_t;
using ull = uint64_t;
using PLL = pair<ll, ll>;

template <typename T> const T& var_min(const T &t) { return t; }
template <typename T> const T& var_max(const T &t) { return t; }
template <typename T, typename... Tail> const T& var_min(const T &t, const Tail&... tail) { return min(t, var_min(tail...)); }
template <typename T, typename... Tail> const T& var_max(const T &t, const Tail&... tail) { return max(t, var_max(tail...)); }
template <typename T, typename... Tail> void chmin(T &t, const Tail&... tail) { t = var_min(t, tail...); }
template <typename T, typename... Tail> void chmax(T &t, const Tail&... tail) { t = var_max(t, tail...); }
template <typename T> const T& clamp(const T &t, const T &low, const T &high) { return max(low, min(high, t)); }
template <typename T> void chclamp(T &t, const T &low, const T &high) { t = clamp(t, low, high); }

namespace init__ {

struct InitIO {
    InitIO() {
        cin.tie(nullptr);
        ios_base::sync_with_stdio(false);
        cout << fixed << setprecision(30);
    }
} init_io;

}

#ifdef DEBUGGING
// #include "../debug/debug.cpp"
#include "../../debug/debug.cpp"
#else
#define DEBUG(...) 0
#define DEBUG_SEPARATOR_LINE 0
#endif

template <typename T>
T make_v(T init) { return init; }

template <typename T, typename... Tail>
auto make_v(T init, size_t s, Tail... tail) {
#define rec make_v(init, tail...)
    return V<decltype(rec)>(s, rec);
#undef rec
}

struct UnionFind {
    V<ll> rank;
    V<ll> parent;
    V<bool> cycle;

    UnionFind(ll N) : rank(N, 0), parent(N), cycle(N) {
        iota(parent.begin(), parent.end(), 0ll);
    }

    ll find(ll child) {
        return (child == parent[child] ? child : parent[child] = find(parent[child]));
    }

    void unit(ll x, ll y) {
        ll px = find(x);
        ll py = find(y);
        if(px == py) {
            cycle[px] = true;
            return;
        }
        if(rank[px] < rank[py]) {
            swap(px, py);
        }
        parent[py] = px;
        rank[px] += (rank[px] == rank[py]);
        if(cycle[py]) cycle[px] = true;
    }

    bool is_cycle(ll x) { return cycle[find(x)]; }

    bool same(ll x, ll y) {
        return (find(x) == find(y));
    }
};

using TLL = tuple<ll, ll, ll>;

struct Solver {
    ll N, H, W;
    V<ll> scores;
    V<TLL> cards;
    UnionFind uf;

    Solver(ll arg_N, ll arg_H, ll arg_W)
        : N(arg_N), H(arg_H), W(arg_W), scores(arg_N), cards(arg_N), uf(arg_H + arg_W)
    {
        for(ll i = 0; i < N; i++) {
            ll h, w;
            cin >> h >> w;
            h--; w--;
            cards[i] = make_tuple(i, h, w);
            cin >> scores[i];
        }
    }

    ll solve() {
        sort(ALL(cards), 
             [&](TLL u, TLL v) {
                 ll a, b, c, d, e, f;
                 tie(a, b, c) = u;
                 tie(d, e, f) = v;
                 return scores[a] > scores[d];
             });
        ll ret = 0;
        for(auto &&ele : cards) {
            ll idx, h, w;
            tie(idx, h, w) = ele;
            ll id_h = h;
            ll id_w = w + H;
            if(uf.is_cycle(id_h) && uf.is_cycle(id_w)) continue;
            uf.unit(id_h, id_w);
            ret += scores[idx];
        }
        return ret;
    }
};

int main() {
    ll N, H, W;
    cin >> N >> H >> W;
    cout << Solver(N, H, W).solve() << endl;
    return 0;
}


Measured memory_bytes: 6528