Problem:
Description fetch failed. Please view: https://onlinejudge.u-aizu.ac.jp/problems/2511

Submitted solutions:

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

using pii = pair<int, int>;

struct edge {
    int from, to, cost;
    bool operator<(edge const& es) const {
        return cost < es.cost;
    }
};

using edges = vector<edge>;
using graph = vector<edges>;

class union_find {
public:
    union_find(int n)
        : par_(n, -1)
    {}
    void init(int n) {
        par_.assign(n, -1);
    }

    int root(int x) {
        return par_[x] < 0 ? x : par_[x] = root(par_[x]);
    }

    bool unite(int x, int y) {
        x = root(x); y = root(y);
        if(x == y) {
            return false;
        } else {
            if(par_[x] < par_[y]) {
                par_[x] += par_[y];
                par_[y] = x;
            } else {
                par_[y] += par_[x];
                par_[x] = y;
            }
            return true;
        }
    }

    bool same(int x, int y) {
        return root(x) == root(y);
    }

    int size(int x) {
        return -par_[root(x)];
    }

private:
    std::vector<int> par_;
};

constexpr int INF = 1e9;

int main() {
    int N, M;
    while(cin >> N >> M, N) {
        vector<pii> h(N);
        for(int i=0; i<N; ++i) {
            cin >> h[i].first;
            h[i].second = i;
        }
        sort(h.begin(), h.end());
        edges es(M);
        for(int i=0; i<M; ++i) {
            int a, b, c;
            cin >> a >> b >> c;
            a--; b--;
            es[i] = edge{a, b, c};
        }
        sort(es.begin(), es.end());
        {
            union_find uf(N);
            for(auto& e : es) {
                uf.unite(e.from, e.to);
            }
            if(uf.size(0) != N) {
                cout << 0 << endl;
                continue;
            }
        }
        int i = 0;
        int cnt = N;
        vector<bool> sink(N);
        vector<vector<int>> sinkv;
        while(i < N) {
            vector<int> v = {h[i].second};
            sink[h[i].second] = true;
            int j = i+1;
            for(; j<N && h[i].first == h[j].first; ++j) {
                v.push_back(h[j].second);
                sink[h[j].second] = true;
            }
            i = j;
            union_find uf(N);
            int sz = 1;
            for(auto& e : es) {
                if(!sink[e.from] && !sink[e.to]) {
                    uf.unite(e.from, e.to);
                    sz = max(sz, uf.size(e.from));
                }
            }
            if(sz != cnt - v.size()) {
                for(auto x : v) {
                    sink[x] = false;
                }
                break;
            }
            cnt -= v.size();
            sinkv.push_back(move(v));
        }

        int res = 0;
        union_find uf(N);
        for(auto& e : es) {
            if(!sink[e.from] && !sink[e.to] && !uf.same(e.from, e.to)) {
                res += e.cost;
                uf.unite(e.from, e.to);
            }
        }
        reverse(sinkv.begin(), sinkv.end());
        for(auto& vs : sinkv) {
            for(auto x : vs) {
                sink[x] = false;
            }
            for(auto& e : es) {
                if(!sink[e.from] && !sink[e.to] && !uf.same(e.from, e.to)) {
                    res += e.cost;
                    uf.unite(e.from, e.to);
                }
            }
        }
        cout << res << endl;
    }
}
accuracy: 1
time_ms: 130
memory_kb: 3616
final_rank: 10

code_snippet: // (⁠◕⁠ᴗ⁠◕⁠✿⁠)

// #pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
#define rep(i, n) for (ll i = 0; i < (n); i++)
#define srep(i, s, n) for (ll i = s; i < (n); i++)
#define len(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
using namespace std;
template<typename T> using vc = vector<T>;
template<typename T> using vv = vc<vc<T>>;
template<typename T> using vvv = vv<vc<T>>;
using vi = vc<int>;using vvi = vv<int>; using vvvi = vv<vi>;
using ll = long long;using vl = vc<ll>;using vvl = vv<ll>; using vvvl = vv<vl>;
using ld = long double; using vld = vc<ld>; using vvld = vc<vld>; using vvvld = vc<vvld>;
using uint = unsigned int;
using ull = unsigned long long;
const ld pi = acos(-1.0);
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
// const ll mod = 1000000007;
const ll mod = 998244353;
inline bool inside(ll y, ll x, ll H, ll W) {return 0 <= (y) and (y) < (H) and 0 <= (x) and (x) < (W); }

#define debug(var) do { cout << #var << " :\n"; view(var); } while(0)
template<typename T>void view(const T& e) {cout << e;}
template<typename T1, typename T2>void view(const pair<T1, T2>& p) {cout << "{" << p.first << ", " << p.second << "}";}
template<typename T>void view(const vc<T>& v) {for (const auto& e : v) {view(e);cout << " ";} cout << endl;}
template<typename T>void view(const vv<T>& vv) {for (const auto& v : vv) {view(v);cout << " ";} cout << endl;}
template<typename T>void view(const set<T>& s) {for (const auto& e : s) {view(e);cout << " ";} cout << endl;}
template<typename T>void view(const unordered_set<T>& s) {for (const auto& e : s) {view(e);cout << " ";} cout << endl;}
template<typename T1, typename T2>void view(const map<T1, T2>& mp){for (const auto& e : mp) {view(e);cout << " ";} cout << endl;}

struct UnionFind {
    public : 
        UnionFind(int n) : _n(n){
            root = vi(_n, -1);
        }

        int find(int x){
            if (root[x] < 0) return x;
            return root[x] = find(root[x]);
        }

        void unite(int a, int b){
            a = find(a); b = find(b);
            if (a == b) return;
            if (size(a) < size(b)) swap(a, b);
            root[a] += root[b];
            root[b] = a;
        }
        
        bool same(int a, int b){
            return find(a) == find(b);
        }

        int size(int a){
            return -root[find(a)];
        }

        int group(){
            int ret = 0;
            for (int i = 0; i < _n; i++) if (root[i] < 0) ret++;
            return ret;
        }

        vvi groups(){
            vi leader_buf(_n), group_size(_n);
            for (int i = 0; i < _n; i++) {
                leader_buf[i] = find(i);
                group_size[leader_buf[i]]++;
            }
            vvi result(_n);
            for (int i = 0; i < _n; i++) {
                result[i].reserve(group_size[i]);
            }
            for (int i = 0; i < _n; i++) {
                result[leader_buf[i]].push_back(i);
            }
            result.erase(
                remove_if(result.begin(), result.end(), [&](const vi& v) { return v.empty(); }), result.end());
            return result;
        }
    private :
        int _n;
        vi root;
};

int N, M;

void solve(){
    vl H(N); rep(i, N) cin >> H[i];
    vvl A(N, vl(N, INF));
    rep(i, M){
        int a, b; cin >> a >> b; a--; b--;
        ll c; cin >> c;
        A[a][b] = c;
        A[b][a] = c;
    }
    map<ll, vi> mp;
    rep(i, N) mp[-H[i]].push_back(i);
    ll ans = 0;
    vi vertex;
    UnionFind uf(N);
    for (auto [k, V] : mp){
        vc<tuple<ll, int, int>> edges;
        for (auto v : V) vertex.push_back(v);
        rep(j, len(vertex)) rep(i, j) if (A[vertex[i]][vertex[j]] < INF){
            edges.push_back({A[vertex[i]][vertex[j]], vertex[i], vertex[j]});
        }
        sort(all(edges));
        for (auto [d, u, v] : edges) if (!uf.same(u, v)){
            ans += d;
            uf.unite(u, v);
        }
        if (uf.size(vertex[0]) != len(vertex)){
            ans = 0;
            UnionFind nuf(N);
            uf = nuf;
        }
    }
    if (uf.size(0) == N) cout << ans << endl;
    else cout << 0 << endl;
}

int main(){
    while (true){
        cin >> N >> M;
        if (N == 0) break;
        solve();
    }
}
accuracy: 1
time_ms: 230
memory_kb: 4544
final_rank: 12

code_snippet: #pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")

// #ifndef ONLINE_JUDGE
// #define _GLIBCXX_DEBUG // 配列外参照のエラー
// #endif

// スタンダードライブラリ
#include <bits/stdc++.h>
using namespace std;

// 型関連
using ll = long long;
using lint = long long;
using pll = pair<ll, ll>;
using plll = tuple<ll, ll, ll>;
using pii = pair<int, int>;
using piii = tuple<ll, ll, ll>;
template <class T> using prique = priority_queue<T>;

// 型定数
constexpr ll mod = 998244353;
constexpr ll MOD = 1000000007;
int INF32 = 2e9;
ll INF64 = 9e18;
#define endl '\n';

int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};

/////////////////////////// print関連
template <typename T> void print(vector<T> A);
void print();
template <class Head, class... Tail> void print(Head &&head, Tail &&...tail);
void print(string S);
template <typename T> void print(vector<vector<T>> &F);

inline void Yes(bool f);


struct UnionFind {
  public:
    UnionFind(int n) : par(n, -1), rank(n, 0), siz(n, 1) {}

    int root(int a) {
        if(par[a] == -1) return a;
        else return par[a] = root(par[a]);
    }

    bool same(int a, int b) {
        return root(a) == root(b);
    }

    bool unite(int a, int b) {
        int ra = root(a), rb = root(b);
        if(ra == rb) return false;
        if(rank[ra] < rank[rb]) swap(ra, rb);
        par[rb] = ra;
        if(rank[ra] == rank[rb]) rank[ra]++;
        siz[ra] += siz[rb];
        return true;
    }

    int size(int a) {
        return siz[root(a)];
    }

  private:
    vector<int> par, rank, siz;
};

///////////////////ここから//////////////////////
bool solve() {
    int N, M;
    cin >> N >> M;
    if (N == 0) {
        return false;
    }
    vector<pii> H(N);
    for (int i = 0; i < N; i++) {
        int h;
        cin >> h;
        H[i] = {h, i};
    }
    sort(H.rbegin(), H.rend());
    

    vector<piii> Edge(M);
    for (int i = 0; i < M; i++) {
        int a, b, c;
        cin >> a >> b >> c;
        a--;
        b--;
        Edge.emplace_back(c, a, b);
    }
    sort(Edge.begin(), Edge.end());


    unordered_set<int> S;
    UnionFind unf(N);

    ll ans=0;
    for (int i = 0; i < N; i++) {
        auto [h, v] = H[i];
        S.insert(v);
        if (i < N - 1) {
            auto [nh, nv] = H[i + 1];
            if (h == nh) {
                continue;
            }
        }
        for (auto [w, a, b] : Edge) {
            if (S.count(a) == 0 || S.count(b) == 0) {
                continue;
            }
            if (unf.same(a, b)) {
                continue;
            }
            ans += (ll)w;
            unf.unite(a, b);
        }
        set<int> roots;
        for (auto v : S) {
            roots.insert(unf.root(v));
        }
        if (roots.size() > 1) {
            UnionFind unf2(N);
            swap(unf, unf2);
            ans=0;
        }
    }
    print(ans);
    

    return true;
}

int main() {
    ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    while (solve())
        ;
}

////////////////////print/////////////////////////
// 1次元ベクトルを出力する
template <typename T> void print(vector<T> A) {
    if (A.size() == 0) {
        return;
    }
    for (size_t i = 0; i < A.size() - 1; i++) {
        cout << A[i] << ' ';
    }
    cout << A[A.size() - 1] << endl;
    return;
}

// 2次元ベクトルを出力する
template <typename T> void print(vector<vector<T>> &F) {
    for (size_t i = 0; i < F.size(); i++) {
        for (size_t j = 0; j < F[i].size(); j++) {
            cout << F[i][j];
            if (j < F[i].size() - 1) {
                cout << ' ';
            }
        }
        cout << endl;
    }
}

// 空白行を出力するprint
void print() { cout << endl; }

// 数値・文字列を空白区切りで出力する. print(a,b)など
template <class Head, class... Tail> void print(Head &&head, Tail &&...tail) {
    cout << head;
    if (sizeof...(tail) != 0)
        cout << " ";
    print(forward<Tail>(tail)...);
}

void print(string S) { cout << S << endl; }

//////////////出力関連

inline void Yes(bool f) {
    if (f) {
        cout << "Yes" << endl;
    } else {
        cout << "No" << endl;
    }
}
accuracy: 1
time_ms: 170
memory_kb: 5068
final_rank: 11

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

struct dsu {
    vector<int> p;
    dsu(int n) : p(n, -1) {}
    int leader(int u) {
        return p[u] < 0 ? u : leader(p[u]);
    }
    bool same(int u, int v) {
        return leader(u) == leader(v);
    }
    void merge(int u, int v) {
        u = leader(u), v = leader(v);
        if (u == v) return;
        if (p[u] > p[v]) swap(p[u], p[v]);
        p[u] += p[v];
        p[v] = u;
    }
};

bool solve() {
    int N, M;
    cin >> N >> M;
    if (N == 0 && M == 0) return false;
    vector<int> H(N);
    for (int i = 0; i < N; i++) {
        cin >> H[i];
    }
    vector<int> U(M), V(M), W(M);
    for (int i = 0; i < M; i++) {
        cin >> U[i] >> V[i] >> W[i];
        U[i]--, V[i]--;
    }
    {
        auto B = H;
        sort(B.begin(), B.end());
        B.erase(unique(B.begin(), B.end()), B.end());
        for (int &h : H) {
            h = lower_bound(B.begin(), B.end(), h) - B.begin();
        }
    }
    vector<vector<tuple<int, int, int>>> sink(N);
    for (int i = 0; i < M; i++) {
        int u = U[i], v = V[i], w = W[i];
        int h = min(H[u], H[v]);
        sink[h].emplace_back(u, v, w);
    }
    long long ans = 0;
    for (int h = 0; h < N; h++) {
        dsu uf(N);
        for (int i = h; i < N; i++) {
            for (auto [u, v, _] : sink[i]) {
                uf.merge(u, v);
            }
        }
        bool same = true;
        for (int u = 0; u < N; u++) {
            for (int v = u + 1; v < N; v++) {
                if (H[u] >= h && H[v] >= h && !uf.same(u, v)) same = false;
            }
        }
        if (h < N - 1 && same) continue;
        vector<tuple<int, int, int>> edges;
        edges.reserve(M);
        for (int i = h; i < N; i++) {
            for (auto [u, v, w] : sink[i]) {
                edges.emplace_back(w, u, v);
            }
        }
        dsu mst(N);
        while (h--) {
            for (auto [u, v, w] : sink[h]) {
                edges.emplace_back(w, u, v);
            }
            sort(edges.begin(), edges.end());
            for (auto [w, u, v] : edges) {
                if (mst.same(u, v)) continue;
                mst.merge(u, v);
                ans += w;
            }
            edges.clear();
        }
        break;
    }
    cout << ans << '\n';
    return true;
}

int main() {
    while (solve()) {}
}
accuracy: 1
time_ms: 770
memory_kb: 4380
final_rank: 16

code_snippet: #include <atcoder/dsu>
#include <bits/stdc++.h>
using namespace std;
using ll = long long;

constexpr int INF = 2e9;

int main() {
    while (true) {
        int N, M;
        cin >> N >> M;
        if (N == 0 && M == 0) {
            break;
        }

        vector<int> h(N);
        for (int i = 0; i < N; i++) {
            cin >> h[i];
        }

        vector<tuple<int, int, int>> E(M);
        for (int i = 0; i < M; i++) {
            int a, b, c;
            cin >> a >> b >> c;
            a--;
            b--;
            E[i] = {c, a, b};
        }
        ranges::sort(E);

        int mn            = INF;
        vector<int> check = h;
        check.push_back(-1);
        ranges::sort(check);
        check.erase(ranges::unique(check).begin(), check.end());
        for (auto cur_time : check) {
            atcoder::dsu uf(N);
            int active_cnt = 0;
            int active_v   = -1;
            for (int i = 0; i < N; i++) {
                if (h[i] > cur_time) {
                    active_cnt++;
                    active_v = i;
                }
            }

            if (active_cnt <= 1) {
                continue;
            }

            for (auto [w, u, v] : E) {
                if (h[u] > cur_time && h[v] > cur_time) {
                    uf.merge(u, v);
                }
            }

            if (uf.size(active_v) < active_cnt) {
                mn = min(mn, cur_time);
            }
        }

        if (mn == -1) {
            cout << 0 << endl;
            continue;
        }

        for (int i = 0; i < N; i++) {
            h[i] = min(mn, h[i]);
        }
        vector<tuple<int, int, int, int>> edge(M);
        for (int i = 0; i < M; i++) {
            auto [w, u, v] = E[i];
            edge[i]        = {-min(h[u], h[v]), w, u, v};
        }
        ranges::sort(edge);

        atcoder::dsu uf(N);
        ll ans = 0;
        for (auto [_, w, u, v] : edge) {
            if (!uf.same(u, v)) {
                uf.merge(u, v);
                ans += w;
            }
        }

        cout << ans << endl;
    }
}
accuracy: 1
time_ms: 90
memory_kb: 3968
final_rank: 7

code_snippet: #include <bits/stdc++.h>
using namespace std;
#include <atcoder/all>
using namespace atcoder;
#define all(...) std::begin(__VA_ARGS__), std::end(__VA_ARGS__)
#define rall(...) std::rbegin(__VA_ARGS__), std::rend(__VA_ARGS__)
#define OVERLOAD_REP(_1, _2, _3, _4, name, ...) name
#define REP1(n) for(ll i=0;i<n;i++)
#define REP2(i, n) for (ll i=0;i<n;i++)
#define REP3(i, a, n) for (ll i=a;i<n;i++)
#define REP4(i, a, b, n) for(ll i=a;i<n;i+=b)
#define rep(...) OVERLOAD_REP(__VA_ARGS__, REP4, REP3, REP2, REP1)(__VA_ARGS__)
#define OVERLOAD_RREP(_1, _2, _3, _4, name, ...) name
#define RREP1(n) for(ll i=n;i>=0;i--)
#define RREP2(i, n) for(ll i=n-1;i>=0;i--)
#define RREP3(i, a, n) for(ll i=n;i>=a;i--)
#define RREP4(i, a, b, n) for(ll i=n;i>=a;i-=b)
#define rrep(...) OVERLOAD_RREP(__VA_ARGS__, RREP4, RREP3, RREP2, RREP1)(__VA_ARGS__)
#define foa(a,v)  (auto& a : (v))
#define uniq(a) sort(all(a));a.erase(unique(all(a)),end(a))
#define len(n) (long long)(n).size()
#define pb push_back
using ll = long long;
using ld = long double;
using ull = unsigned long long;
using vi = vector<int>;
using vvi = vector<vi>;
using vvvi = vector<vvi>;
using vll = vector<ll>;
using vvll = vector<vll>;
using vvvll = vector<vvll>;
using vs = vector<string>;
using vvs = vector<vs>;
using vvvs = vector<vvs>;
using vld = vector<ld>;
using vvld = vector<vld>;
using vvvld = vector<vvld>;
using vc = vector<char>;
using vvc = vector<vc>;
using vvvc = vector<vvc>;
using pll = pair<ll,ll>;
using vpll = vector<pll>;
using vvpll = vector<vpll>;
template<class... T>
constexpr auto min(T... a){
    return min(initializer_list<common_type_t<T...>>{a...});
}
template<class... T>
constexpr auto max(T... a){
    return max(initializer_list<common_type_t<T...>>{a...});
}
template<class... T>
void input(T&... a){
    (cin >> ... >> a);
}
ll modpow(ll a,ll b,ll c){
    ll ans = 1;
    while (b){
        if (b & 1){
            ans *= a;
            ans %= c;
        }
        a *= a;
        a %= c;
        b /= 2;
    }
    return ans;
}
#define INT(...) int __VA_ARGS__; input(__VA_ARGS__)
#define LL(...) ll __VA_ARGS__; input(__VA_ARGS__)
#define ULL(...) ull __VA_ARGS__; input(__VA_ARGS__)
#define LD(...) ld __VA_ARGS__; input(__VA_ARGS__)
#define STR(...) string __VA_ARGS__; input(__VA_ARGS__)
#define CHA(...) char __VA_ARGS__; input(__VA_ARGS__)
#define VLL(name,length) vll name(length);rep(i,length){cin >> name[i];}
#define VVLL(name,h,w) vvll name(h,vll(w));rep(i,h)rep(j,w){cin >> name[i][j];}
#define VVVLL(name,a,b,c) vvvll name(a,vvll(b,vll(c)));rep(i,a)rep(j,b)rep(k,c){cin >> name[i][j][k];}
#define VI(name,length) vi name(length);rep(i,length){cin >> name[i];}
#define VVI(name,h,w) vvi name(h,vi(w));rep(i,h)rep(j,w){cin >> name[i][j];}
#define VVVI(name,a,b,c) vvvi name(a,vvll(b,vi(c)));rep(i,a)rep(j,b)rep(k,c){cin >> name[i][j][k];}
#define VLD(name,length) vld name(length);rep(i,length){cin >> name[i];}
#define VVLD(name,h,w) vvld name(h,vld(w));rep(i,h)rep(j,w){cin >> name[i][j];}
#define VVVLD(name,a,b,c) vvvld name(a,vvld(b,vld(c)));rep(i,a)rep(j,b)rep(k,c){cin >> name[i][j][k];}
#define VC(name,length) vc name(length);rep(i,length){cin >> name[i];}
#define VVC(name,h,w) vvc name(h,vc(w));rep(i,h)rep(j,w){cin >> name[i][j];}
#define VVVC(name,a,b,c) vvvc name(a,vvc(b,vc(c)));rep(i,a)rep(j,b)rep(k,c){cin >> name[i][j][k];}
#define VS(name,length) vs name(length);rep(i,length){cin >> name[i];}
#define VVS(name,h,w) vvs name(h,vs(w));rep(i,h)rep(j,w){cin >> name[i][j];}
#define VVVS(name,a,b,c) vvvs name(a,vvs(b,vs(c)));rep(i,a)rep(j,b)rep(k,c){cin >> name[i][j][k];}
#define PLL(name) pll name;cin>>name.first>>name.second;
#define VPLL(name,length) vpll name(length);rep(i,length){cin>>name[i].first>>name[i].second;}

void print(){cout << "\n";}
template<class T, class... Ts>
void print(const T& a, const Ts&... b){cout << a;(cout << ... << (cout << ' ', b));cout << '\n';}
void print(vll x){rep(i,len(x)){cout << x[i];if(i!=len(x)-1){cout << " ";}else{cout << '\n';}}}
void print(vvll x){rep(i,len(x))rep(j,len(x[i])){cout << x[i][j];if(j!=len(x[i])-1){cout << " ";}else{cout << '\n';}}}
void print(pll x){cout << x.first << ' ' << x.second << '\n';}

using S = tuple<ll,ll,ll,ll>;
using F = tuple<ll,ll,ll>;
void solve(ll n,ll m,vll h,vector<S> edge){
    vvll g(1000000+10);
    rep(i,n){
        g[h[i]].push_back(i);
    }
    vector<vector<F>> edge2(1000000+10);
    for(auto [s,a,b,c]:edge){
        edge2[s].push_back({c,a,b});
    }
    ll z = -1;
    dsu uf(n);
    ll group_cnt = n;
    ll cnt = 0;
    rrep(i,1000000+10){
        cnt += len(g[i]);
        for(auto [c,a,b]:edge2[i]){
            if(uf.same(a,b)==false){
                group_cnt--;
            }
            uf.merge(a,b);
        }
        if(z == -1 && cnt != 1 && group_cnt == n - cnt + 1){
            z = i;
        }
        else if(!(cnt != 1 && group_cnt == n - cnt + 1)){
            z = -1;
        }
    }
    //print(z);
    if(z == -1){
        print(0);
        return;
    }
    ll ans = 0;
    vector<F> edge3;
    for(int i=1000000+10-1;i>=z;i--){
        for(auto [c,a,b]:edge2[i]){
            edge3.push_back({c,a,b});
        }
    }
    sort(all(edge3));
    dsu uf2(n);
    for(auto [c,a,b]:edge3){
        if(uf2.same(a,b)==false){
            ans += c;
            uf2.merge(a,b);
            //print(a+1,b+1,c);
        }
    }
    for(int i=z-1;i>=0;i--){
        sort(all(edge2[i]));
        for(auto [c,a,b]:edge2[i]){
            if(uf2.same(a,b)==false){
                ans += c;
                uf2.merge(a,b);
                //print(a+1,b+1,c,i);
            }
        }
    }
    print(ans);
    return;
}


int main(){
    while(1){
        LL(n,m);
        VLL(h,n);
        if(n == 0 && m == 0){break;}
        vector<S> edge;
        rep(i,m){
            LL(a,b,c);
            a--;
            b--;
            edge.push_back({min(h[a],h[b]),a,b,c});
            
        }
        solve(n,m,h,edge);
    }
}
accuracy: 1
time_ms: 870
memory_kb: 73860
final_rank: 20

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}

#include <unistd.h>

namespace fastio {
static constexpr uint32_t SZ = 1 << 17;
char ibuf[SZ];
char obuf[SZ];
char out[100];
// pointer of ibuf, obuf


uint32_t pil = 0, pir = 0, por = 0;

struct Pre {
    char num[10000][4];
    constexpr Pre() : num() {
        for (int i = 0; i < 10000; i++) {
            int n = i;
            for (int j = 3; j >= 0; j--) {
                num[i][j] = n % 10 | '0';
                n /= 10;
            }
        }
    }
} constexpr pre;

inline void load() {
    memmove(ibuf, ibuf + pil, pir - pil);
    pir = pir - pil + fread(ibuf + pir - pil, 1, SZ - pir + pil, stdin);
    pil = 0;
    if (pir < SZ)
        ibuf[pir++] = '\n';
}

inline void flush() {
    fwrite(obuf, 1, por, stdout);
    por = 0;
}

void rd(char &c) {
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
}

void rd(string &x) {
    x.clear();
    char c;
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
    do {
        x += c;
        if (pil == pir)
            load();
        c = ibuf[pil++];
    } while (!isspace(c));
}

template <typename T> void rd_real(T &x) {
    string s;
    rd(s);
    x = stod(s);
}

template <typename T> void rd_integer(T &x) {
    if (pil + 100 > pir)
        load();
    char c;
    do
        c = ibuf[pil++];
    while (c < '-');
    bool minus = 0;
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (c == '-') {
            minus = 1, c = ibuf[pil++];
        }
    }
    x = 0;
    while ('0' <= c) {
        x = x * 10 + (c & 15), c = ibuf[pil++];
    }
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (minus)
            x = -x;
    }
}

void rd(int &x) {
    rd_integer(x);
}
void rd(ll &x) {
    rd_integer(x);
}
void rd(i128 &x) {
    rd_integer(x);
}
void rd(uint &x) {
    rd_integer(x);
}
void rd(ull &x) {
    rd_integer(x);
}
void rd(u128 &x) {
    rd_integer(x);
}
void rd(double &x) {
    rd_real(x);
}
void rd(long double &x) {
    rd_real(x);
}

template <class T, class U> void rd(pair<T, U> &p) {
    return rd(p.first), rd(p.second);
}
template <size_t N = 0, typename T> void rd_tuple(T &t) {
    if constexpr (N < std::tuple_size<T>::value) {
        auto &x = std::get<N>(t);
        rd(x);
        rd_tuple<N + 1>(t);
    }
}
template <class... T> void rd(tuple<T...> &tpl) {
    rd_tuple(tpl);
}

template <size_t N = 0, typename T> void rd(array<T, N> &x) {
    for (auto &d : x)
        rd(d);
}
template <class T> void rd(vector<T> &x) {
    for (auto &d : x)
        rd(d);
}

void read() {}
template <class H, class... T> void read(H &h, T &...t) {
    rd(h), read(t...);
}

void wt(const char c) {
    if (por == SZ)
        flush();
    obuf[por++] = c;
}
void wt(const string s) {
    for (char c : s)
        wt(c);
}
void wt(const char *s) {
    size_t len = strlen(s);
    for (size_t i = 0; i < len; i++)
        wt(s[i]);
}

template <typename T> void wt_integer(T x) {
    if (por > SZ - 100)
        flush();
    if (x < 0) {
        obuf[por++] = '-', x = -x;
    }
    int outi;
    for (outi = 96; x >= 10000; outi -= 4) {
        memcpy(out + outi, pre.num[x % 10000], 4);
        x /= 10000;
    }
    if (x >= 1000) {
        memcpy(obuf + por, pre.num[x], 4);
        por += 4;
    } else if (x >= 100) {
        memcpy(obuf + por, pre.num[x] + 1, 3);
        por += 3;
    } else if (x >= 10) {
        int q = (x * 103) >> 10;
        obuf[por] = q | '0';
        obuf[por + 1] = (x - q * 10) | '0';
        por += 2;
    } else
        obuf[por++] = x | '0';
    memcpy(obuf + por, out + outi + 4, 96 - outi);
    por += 96 - outi;
}

template <typename T> void wt_real(T x) {
    ostringstream oss;
    oss << fixed << setprecision(15) << double(x);
    string s = oss.str();
    wt(s);
}

void wt(int x) {
    wt_integer(x);
}
void wt(ll x) {
    wt_integer(x);
}
void wt(i128 x) {
    wt_integer(x);
}
void wt(uint x) {
    wt_integer(x);
}
void wt(ull x) {
    wt_integer(x);
}
void wt(u128 x) {
    wt_integer(x);
}
void wt(double x) {
    wt_real(x);
}
void wt(long double x) {
    wt_real(x);
}

template <class T, class U> void wt(const pair<T, U> val) {
    wt(val.first);
    wt(' ');
    wt(val.second);
}
template <size_t N = 0, typename T> void wt_tuple(const T t) {
    if constexpr (N < std::tuple_size<T>::value) {
        if constexpr (N > 0) {
            wt(' ');
        }
        const auto x = std::get<N>(t);
        wt(x);
        wt_tuple<N + 1>(t);
    }
}
template <class... T> void wt(tuple<T...> tpl) {
    wt_tuple(tpl);
}
template <class T, size_t S> void wt(const array<T, S> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}
template <class T> void wt(const vector<T> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}

void print() {
    wt('\n');
}
template <class Head, class... Tail> void print(Head &&head, Tail &&...tail) {
    wt(head);
    if (sizeof...(Tail))
        wt(' ');
    print(forward<Tail>(tail)...);
}
void __attribute__((destructor)) _d() {
    flush();
}
} // namespace fastio


using fastio::flush;
using fastio::print;
using fastio::read;

inline void first(bool i = true) {
    print(i ? "first" : "second");
}
inline void Alice(bool i = true) {
    print(i ? "Alice" : "Bob");
}
inline void Takahashi(bool i = true) {
    print(i ? "Takahashi" : "Aoki");
}
inline void yes(bool i = true) {
    print(i ? "yes" : "no");
}
inline void Yes(bool i = true) {
    print(i ? "Yes" : "No");
}
inline void No() {
    print("No");
}
inline void YES(bool i = true) {
    print(i ? "YES" : "NO");
}
inline void NO() {
    print("NO");
}
inline void Yay(bool i = true) {
    print(i ? "Yay!" : ":(");
}
inline void Possible(bool i = true) {
    print(i ? "Possible" : "Impossible");
}
inline void POSSIBLE(bool i = true) {
    print(i ? "POSSIBLE" : "IMPOSSIBLE");
}

/**
 * @brief Fast IO
 */

struct dsu {
  public:
    dsu() : _n(0) {}
    dsu(int n) : _n(n), parent_or_size(n, -1) {}

    int merge(int a, int b) {
        assert(0 <= a && a < _n);
        assert(0 <= b && b < _n);
        int x = leader(a), y = leader(b);
        if (x == y) return x;
        if (-parent_or_size[x] < -parent_or_size[y]) std::swap(x, y);
        parent_or_size[x] += parent_or_size[y];
        parent_or_size[y] = x;
        return x;
    }

    bool same(int a, int b) {
        assert(0 <= a && a < _n);
        assert(0 <= b && b < _n);
        return leader(a) == leader(b);
    }

    int leader(int a) {
        assert(0 <= a && a < _n);
        if (parent_or_size[a] < 0) return a;
        return parent_or_size[a] = leader(parent_or_size[a]);
    }

    int size(int a) {
        assert(0 <= a && a < _n);
        return -parent_or_size[leader(a)];
    }

    std::vector<std::vector<int>> groups() {
        std::vector<int> leader_buf(_n), group_size(_n);
        for (int i = 0; i < _n; i++) {
            leader_buf[i] = leader(i);
            group_size[leader_buf[i]]++;
        }
        std::vector<std::vector<int>> result(_n);
        for (int i = 0; i < _n; i++) {
            result[i].reserve(group_size[i]);
        }
        for (int i = 0; i < _n; i++) {
            result[leader_buf[i]].push_back(i);
        }
        result.erase(
            std::remove_if(result.begin(), result.end(),
                           [&](const std::vector<int>& v) { return v.empty(); }),
            result.end());
        return result;
    }

  private:
    int _n;
    // root node: -1 * component size
    // otherwise: parent
    std::vector<int> parent_or_size;
};

int MAXS = 1000000;

int main() {
while(1) {
    int N, M;
    cin >> N >> M;
    if (N == 0 && M == 0) return 0;
    vector<int> H(N), A(M), B(M), C(M);
    rep(i,0,N) cin >> H[i], H[i]--;
    rep(i,0,M) cin >> A[i] >> B[i] >> C[i], A[i]--, B[i]--;
    vector<vector<pair<int,pair<int,int>>>> V(MAXS);
    vector<vector<int>> W(MAXS);
    rep(i,0,N) W[H[i]].push_back(i);
    rep(i,0,M) {
        V[min(H[A[i]],H[B[i]])].push_back({C[i],{A[i],B[i]}});
    }
    rep(i,0,MAXS) sort(ALL(V[i]));
    int NG = MAXS, COUNT = 0;
    dsu UF(N);
    rrep(i,0,MAXS) {
        if (W[i].empty()) {
            if (NG == i + 1) NG = i;
            continue;
        }
        COUNT += W[i].size();
        for (pair<int,pair<int,int>> P : V[i]) {
            int a = P.second.first, b = P.second.second;
            UF.merge(a,b);
        }
        if (UF.size(W[i][0]) != COUNT) NG = i;
    }
    if (NG == 0) {
        cout << 0 << endl;
        continue;
    }
    int OK = NG - 1;
    vector<pair<int,pair<int,int>>> Over;
    rep(i,OK,MAXS) {
        for (pair<int,pair<int,int>> P : V[i]) Over.push_back(P);
    }
    sort(ALL(Over));
    dsu UF2(N);
    int ANS = 0;
    for (auto [c,p] : Over) {
        int a = p.first, b = p.second;
        if (!UF2.same(a,b)) ANS += c, UF2.merge(a,b);
    }
    rrep(i,0,OK) {
        for (auto [c,p] : V[i]) {
            int a = p.first, b = p.second;
            if (!UF2.same(a,b)) ANS += c, UF2.merge(a,b);
        }
    }
    cout << ANS << endl;
}
}
accuracy: 1
time_ms: 790
memory_kb: 73576
final_rank: 19

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (long long i = 0; i < (long long)(n); i++)
#define rrep(i,start,end) for (long long i = start;i >= (long long)(end);i--)
#define repn(i,end) for(long long i = 0; i <= (long long)(end); i++)
#define reps(i,start,end) for(long long i = start; i < (long long)(end); i++)
#define repsn(i,start,end) for(long long i = start; i <= (long long)(end); i++)
#define each(p,a) for(auto &p:a)
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef vector<long long> vll;
typedef vector<pair<long long ,long long>> vpll;
typedef vector<vector<long long>> vvll;
typedef set<ll> sll;
typedef map<long long , long long> mpll;
typedef pair<long long ,long long> pll;
typedef tuple<long long , long long , long long> tpl3;
#define LL(...) ll __VA_ARGS__; input(__VA_ARGS__)
#define LD(...) ld __VA_ARGS__; input(__VA_ARGS__)
#define Str(...) string __VA_ARGS__; input(__VA_ARGS__)
#define Ch(...) char __VA_ARGS__; input(__VA_ARGS__)
#define all(a)  (a).begin(),(a).end()
#define UNIQUE(v) v.erase( unique(v.begin(), v.end()), v.end() );
#define sz(x) (int)x.size()
// << std::fixed << std::setprecision(10)
const ll INF = 1LL << 60;
const ld EPS = 1e-9;
 
inline ll lfloor(ll x,ll m){return (x - ((x % m+ m)%m))/m;}
inline ll positive_mod(ll a,ll m){return (a % m + m)%m;}
inline ll popcnt(ull a){ return __builtin_popcountll(a);}
template<class T> bool chmin(T& a, T b){if(a > b){a = b;return true;}return false;}
template<class T> bool chmax(T& a, T b){if(a < b){a = b;return true;}return false;}
template<typename T> std::istream &operator>>(std::istream&is,std::vector<T>&v){for(T &in:v){is>>in;}return is;}
template<typename T> std::ostream &operator<<(std::ostream&os,const std::vector<T>&v){for(auto it=std::begin(v);it!=std::end(v);){os<<*it<<((++it)!=std::end(v)?" ":"");}return os;}
template<typename T1, typename T2>std::ostream &operator<< (std::ostream &os, std::pair<T1,T2> p){os << "{" << p.first << "," << p.second << "}";return os;}
template<class... T>void input(T&... a){(cin >> ... >> a);}
void print(){cout << endl;}
template<class T, class... Ts>void print(const T& a, const Ts&... b){cout << a;((cout << ' ' << b), ...);cout << endl;}
template<class T> void pspace(const T& a){ cout << a << ' ';}
void perr(){cerr << endl;}
template<class T, class... Ts>void perr(const T& a, const Ts&... b){cerr << a;((cerr << ' ' << b), ...);cerr << endl;}
void yes(bool i = true){ return print(i?"yes":"no"); }
void Yes(bool i = true){ return print(i?"Yes":"No"); }
void YES(bool i = true){ return print(i?"YES":"NO"); }
template <class T> vector<T> &operator++(vector<T> &v) {for(auto &e : v) e++;return v;}
template <class T> vector<T> operator++(vector<T> &v, signed) {auto res = v;for(auto &e : v) e++;return res;}
template <class T> vector<T> &operator--(vector<T> &v) {for(auto &e : v) e--;return v;}
template <class T> vector<T> operator--(vector<T> &v, signed) {auto res = v;for(auto &e : v) e--;return res;}
//grid探索用
vector<ll> _ta = {0,0,1,-1,1,1,-1,-1};
vector<ll> _yo = {1,-1,0,0,1,-1,1,-1};
bool isin(ll now_i,ll now_j,ll h,ll w){return (0<=now_i && now_i < h && 0 <= now_j && now_j < w);}
  
ll lpow(ll x,ll n){ll ans = 1;while(n >0){if(n & 1)ans *= x;x *= x;n >>= 1;}return ans;}
ll Modlpow(ll x,ll n,ll m){ll ans = 1;ll a = x%m;while(n >0){if(n & 1){ans *= a;ans%= m;}a *= a;a %= m;n >>= 1;}return ans;} 
const ll MOD9 = 998244353LL;
const ll MOD10 = 1000000007LL;

// for AOJ or ICPC or etc..
// 全部が0だったらtrueを返す
template<class Tp> bool zero (const Tp &x) {return x == 0;}
template<class Tp, class... Args> bool zero (const Tp &x, const Args& ...args) {return zero(x) and zero(args...);}


class UnionFind{
  public:
  vector<ll> par;
  vector<ll> siz;
 
  UnionFind(ll n) {
    par.resize(n,-1);
    siz.resize(n,1);
    _n = n;
  }
 
  ll leader(ll a){
    assert(0 <= a && a < _n);
    while(par[a] != -1){
      a = par[a];
    }
    return a;
  }
 
  ll size(ll a){
    assert(0 <= a && a < _n);
    return siz[leader(a)];
  }
 
  ll merge(ll a,ll b){
    assert(0 <= a && a < _n);
    assert(0 <= b && b < _n);
    ll u = leader(a);
    ll v = leader(b);
    if( u == v )return u;
    if(siz[u] >= siz[v]){
      par[v] = u;
      siz[u] += siz[v];
      return u;
    }else{
      par[u] = v;
      siz[v] += siz[u];
      return v;
    }
  }
 
  bool same(ll a,ll b){
    assert(0 <= a && a < _n);
    assert(0 <= b && b < _n);
    if(leader(a) == leader(b)){
      return true;
    }else{
      return false;
    }
  }
 
  vector<vector<ll>> groups(){
    map<ll,vector<ll>> mp;
    for(ll i = 0;i < _n;i++){
      mp[leader(i)].push_back(i);
    }
    vector<vector<ll>> ans;
    for(auto &p:mp){
      vector<ll> now = p.second;
      ans.push_back(now);
    }
    return ans;
  }
 
  private:
  ll _n;
};

// 変数をちゃんと全部受け取る！
void solve(ll n,ll m){
  vll h(n);cin >> h;
  UnionFind hantei(n);

  multiset<pair<ll,pair<ll,ll>>> cab;
  rep(i,m){
    LL(a,b,c);
    a--;b--;
    hantei.merge(a,b);
    cab.insert({c,{a,b}});
  }
  multiset<pair<ll,pair<ll,ll>>> cabcp = cab;
  if(hantei.size(0) != n){
    cout << 0 << endl;
    return ;
  }

  vpll ord(n);
  rep(i,n){
    ord[i] = {h[i],i};
  }
  sort(all(ord));
  reverse(all(ord));

  ll ans = 0;
  set<ll> used;
  UnionFind uf(n);
  ll lastcut = -1;//ここまでは絶対つなぐ
  for(ll i = 0;i < n;){
    ll time = ord[i].first;
    used.insert(ord[i].second);
    i++;
    while(i < n && ord[i].first == time){
      used.insert(ord[i].second);
      i++;
    }
    //つなぐ
    for(auto it = cab.begin();it != cab.end();){
      auto &[c,np] = *it;
      auto &[a,b] = np;
      if(used.count(a) && used.count(b) && !uf.same(a,b)){
        ans += c;
        uf.merge(a,b);
        it = cab.erase(it);
      }else{
        it++;
      }
    }
    if(uf.size(*used.begin()) != (ll)used.size()){
      chmax(lastcut,i);
    }
    
  }
  if(lastcut == -1){
    cout << ans << endl;
    return ;
  }

  //[0,lastcut)は無しでいい
  //その後はしっかりつなげる
  set<ll> se;
  UnionFind uf2(n);
  rep(i,lastcut){
    se.insert(ord[i].second);
  }
  ll nans = 0;
  for(ll i = lastcut;i < n;){
    ll time = ord[i].first;
    se.insert(ord[i].second);
    i++;
    while(i < n && ord[i].first == time){
      se.insert(ord[i].second);
      i++;
    }
    //つなぐ
    for(auto it = cabcp.begin();it != cabcp.end();){
      auto &[c,np] = *it;
      auto &[a,b] = np;
      if(se.count(a) && se.count(b) && !uf2.same(a,b)){
        nans += c;
        uf2.merge(a,b);
        it = cabcp.erase(it);
      }else{
        it++;
      }
    }
    if(uf2.size(*se.begin()) != (ll)se.size()){
      cerr << "false" << endl;
    }
  }
  cout << nans << endl;




  
}
 
int main(){
  ios::sync_with_stdio(false);cin.tie(nullptr);
  while(true){
    LL(n,m);//変数数調整
    if(zero(n,m))break;
    solve(n,m);
  }
}
accuracy: 1
time_ms: 550
memory_kb: 5824
final_rank: 15

code_snippet: #include<bits/stdc++.h>

using namespace std;
using ll = long long;
using vll = vector<ll>;
using vvll = vector<vll>;
using vvvll = vector<vvll>;
#define rep(i,n) for(ll i=0;i<ll(n);i++)
#define all(A) A.begin(),A.end()

void chmax(ll& p, ll q) { p = max(p, q); };
void chmin(ll& p, ll q) { p = min(p, q); };

struct dsu {
    
    ll n;
    vll SZ;
    dsu(int n) : n(n), SZ(n, -1) {}

    int merge(int a, int b) {
        int x = leader(a), y = leader(b);
        if (x == y) return x;
        if (-SZ[x] < -SZ[y]) std::swap(x, y);
        SZ[x] += SZ[y];
        SZ[y] = x;
        return x;
    }
    bool same(int a, int b) {
        return leader(a) == leader(b);
    }
    int leader(int a) {
        if (SZ[a] < 0) return a;
        return SZ[a] = leader(SZ[a]);
    }
    int size(int a) {
        return -SZ[leader(a)];
    }
};

void solve(ll N,ll M) {
    map<ll,ll> MH;
    vll H(N);
    rep(i,N){
        cin>>H[i];
        MH[H[i]]=1;
    }
    ll cnt=0;
    for(auto m:MH)MH[m.first]=cnt,cnt++;
    vvll HH(N);
    rep(i,N){
        H[i]=MH[H[i]];
        HH[H[i]].push_back(i);
    }
    vector<vector<pair<ll,pair<ll,ll>>>> E(N+1);
    rep(i,M){
        ll A,B,C;
        cin>>A>>B>>C;
        A--;B--;
        E[min(H[A],H[B])].push_back({C,{A,B}});
    }
    ll V=0,NG=N,FV=-1;
    dsu ds(N);
    for(ll d=N-1;d>=0;d--){
        if(HH[d].size()==0)continue;
        V+=HH[d].size();
        FV=HH[d][0];
        for(auto cuv:E[d])ds.merge(cuv.second.first,cuv.second.second);
        if(ds.size(FV)!=V)NG=d;
    }
    if(NG==0){
        cout<<0<<endl;
        return;
    }
    dsu ND(N);
    ll an=0;
    for(ll d=N-1;d>=NG;d--)for(auto u:E[d+1])E[d].push_back(u);
    for(ll d=NG-1;d>=0;d--){
        for(auto u:E[d+1])E[d].push_back(u);
        sort(all(E[d]));
        for(auto cuv:E[d]){
            if(ND.same(cuv.second.first,cuv.second.second))continue;
            ND.merge(cuv.second.first,cuv.second.second);
            an+=cuv.first;
        }
    }
    cout<<an<<endl;
    return;
    
}

int main() {

    cin.tie(nullptr);
    ios::sync_with_stdio(false);

    ll N,M;
    while (cin >> N>>M) {
        if (N+M == 0)return 0;
        solve(N,M);
    }
}
accuracy: 1
time_ms: 170
memory_kb: 36712
final_rank: 13

code_snippet: #include<bits/stdc++.h>

#include <algorithm>
#include <cassert>
#include <vector>

namespace atcoder {

// Implement (union by size) + (path compression)
// Reference:
// Zvi Galil and Giuseppe F. Italiano,
// Data structures and algorithms for disjoint set union problems
struct dsu {
  public:
    dsu() : _n(0) {}
    dsu(int n) : _n(n), parent_or_size(n, -1) {}

    int merge(int a, int b) {
        assert(0 <= a && a < _n);
        assert(0 <= b && b < _n);
        int x = leader(a), y = leader(b);
        if (x == y) return x;
        if (-parent_or_size[x] < -parent_or_size[y]) std::swap(x, y);
        parent_or_size[x] += parent_or_size[y];
        parent_or_size[y] = x;
        return x;
    }

    bool same(int a, int b) {
        assert(0 <= a && a < _n);
        assert(0 <= b && b < _n);
        return leader(a) == leader(b);
    }

    int leader(int a) {
        assert(0 <= a && a < _n);
        if (parent_or_size[a] < 0) return a;
        return parent_or_size[a] = leader(parent_or_size[a]);
    }

    int size(int a) {
        assert(0 <= a && a < _n);
        return -parent_or_size[leader(a)];
    }

    std::vector<std::vector<int>> groups() {
        std::vector<int> leader_buf(_n), group_size(_n);
        for (int i = 0; i < _n; i++) {
            leader_buf[i] = leader(i);
            group_size[leader_buf[i]]++;
        }
        std::vector<std::vector<int>> result(_n);
        for (int i = 0; i < _n; i++) {
            result[i].reserve(group_size[i]);
        }
        for (int i = 0; i < _n; i++) {
            result[leader_buf[i]].push_back(i);
        }
        result.erase(
            std::remove_if(result.begin(), result.end(),
                           [&](const std::vector<int>& v) { return v.empty(); }),
            result.end());
        return result;
    }

  private:
    int _n;
    // root node: -1 * component size
    // otherwise: parent
    std::vector<int> parent_or_size;
};

}  // namespace atcoder

using namespace atcoder;
using namespace std;
using ll = long long;
using vll = vector<ll>;
using vvll = vector<vll>;
using vvvll = vector<vvll>;
#define rep(i,n) for(ll i=0;i<ll(n);i++)
#define all(A) A.begin(),A.end()

void chmax(ll& p, ll q) { p = max(p, q); };
void chmin(ll& p, ll q) { p = min(p, q); };

void solve(ll N,ll M) {
    map<ll,ll> MH;
    vll H(N);

    rep(i,N){
        cin>>H[i];
        MH[H[i]]=1;
    }
    ll cnt=0;
    for(auto m:MH)MH[m.first]=cnt,cnt++;
    vvll HH(N);
    rep(i,N){
        H[i]=MH[H[i]];
        HH[H[i]].push_back(i);
    }
    vector<vector<pair<ll,pair<ll,ll>>>> E(N+1);
    rep(i,M){
        ll A,B,C;
        cin>>A>>B>>C;
        A--;B--;
        ll D=min(H[A],H[B]);
        E[D].push_back({C,{A,B}});
    }
    ll V=0;
    ll NG=N;
    ll FV=-1;
    dsu ds(N);
    for(ll d=N-1;d>=0;d--){
        if(HH[d].size()==0)continue;
        V+=HH[d].size();
        FV=HH[d][0];
        for(auto cuv:E[d]){
            ds.merge(cuv.second.first,cuv.second.second);
        }
        if(ds.size(FV)!=V){
            NG=d;
        }
    }
    //cout<<NG<<endl;
    if(NG==0){
        cout<<0<<endl;
        return;
    }
    dsu ND(N);
    ll an=0;
    for(ll d=N-1;d>=NG;d--){
        for(auto u:E[d+1])E[d].push_back(u);
    }
    for(ll d=NG-1;d>=0;d--){
        for(auto u:E[d+1])E[d].push_back(u);
        sort(all(E[d]));
        for(auto cuv:E[d]){
            if(ND.same(cuv.second.first,cuv.second.second))continue;
            ND.merge(cuv.second.first,cuv.second.second);
            an+=cuv.first;
        }
    }
    cout<<an<<endl;
    return;
    
    cout<<"MADA"<<endl;
}

int main() {

    cin.tie(nullptr);
    ios::sync_with_stdio(false);

    ll N,M;
    while (cin >> N>>M) {
        if (N+M == 0)return 0;
        solve(N,M);
    }
}
accuracy: 1
time_ms: 180
memory_kb: 36708
final_rank: 14

code_snippet: #include <bits/stdc++.h>

struct UnionFind {
    int n;
    std::vector<int> data;
    UnionFind(int n): n(n), data(n, -1) {}
    int leader(int x) {
        if (data[x] < 0) return x;
        return data[x] = leader(data[x]);
    }
    bool merge(int lhs, int rhs) {
        lhs = leader(lhs);
        rhs = leader(rhs);
        if (lhs == rhs) return false;
        if (-data[lhs] < -data[rhs]) std::swap(lhs, rhs);
        data[lhs] += data[rhs];
        data[rhs] = lhs;
        return true;
    }
    int size(int i) {
        return -data[leader(i)];
    }
    bool same(int lhs, int rhs) {
        return leader(lhs) == leader(rhs);
    }
};

int solve() {
    int n, m;
    std::cin >> n >> m;
    if (n == 0) return 1;
    std::vector<int> h(n);
    for (int i = 0; i < n; i++) std::cin >> h[i];
    std::vector<int> ord(n);
    std::iota(ord.begin(), ord.end(), 0);
    std::sort(ord.begin(), ord.end(), [&](int i, int j) { return h[i] < h[j]; });
    int g_n = 0;
    std::vector<int> gid(n);
    std::vector<std::vector<int>> vs;
    // w, u, v
    std::vector<std::vector<std::tuple<int, int, int>>> es;
    for (int l = 0, r = 0; l < n; l = r) {
        while (r < n && h[ord[l]] == h[ord[r]]) r++;
        vs.resize(g_n + 1);
        es.resize(g_n + 1);
        for (int i = l; i < r; i++) {
            vs.back().push_back(ord[i]);
            gid[ord[i]] = g_n;
        }
        g_n++;
    }
    for (int i = 0; i < m; i++) {
        int u, v, w;
        std::cin >> u >> v >> w;
        u--; v--;
        es[std::min(gid[u], gid[v])].emplace_back(w, u, v);
    }
    int ng = 0;
    while (ng < g_n) {
        UnionFind uf(n);
        int x = -1;
        int sum = 0;
        for (int i = ng; i < g_n; i++) {
            assert(!vs[i].empty());
            x = vs[i].front();
            sum += vs[i].size();
            for (auto [w, u, v]: es[i]) {
                uf.merge(u, v);
            }
        }
        assert(x != -1);
        if (uf.size(x) != sum) {
            break;
        }
        ng++;
    }
    if (ng == 0) {
        std::cout << 0 << '\n';
        return 0;
    }
    std::vector<std::tuple<int, int, int>> cur_es;
    std::vector<int> cur_vs;
    for (int i = ng - 1; i < g_n; i++) {
        for (auto e: es[i]) cur_es.push_back(e);
        for (auto v: vs[i]) cur_vs.push_back(v);
    }
    int cost = 0;
    UnionFind uf(n);
    std::sort(cur_es.begin(), cur_es.end());
    for (auto [w, u, v]: cur_es) {
        if (uf.merge(u, v)) cost += w;
    }
    for (int i = ng - 1; i--; ) {
        std::sort(es[i].begin(), es[i].end());
        for (auto [w, u, v]: es[i]) {
            if (uf.merge(u, v)) {
                cost += w;
            }
        }
        for (auto v: vs[i]) {
            cur_vs.push_back(v);
        }
        for (int j = 0; j + 1 < (int)cur_vs.size(); j++) {
            assert(uf.same(cur_vs[j], cur_vs[j + 1]));
        }
    }
    std::cout << cost << '\n';
    return 0;
}

int main() {
    while (!solve());
}
accuracy: 1
time_ms: 70
memory_kb: 4020
final_rank: 5

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

using ll = long long;

template<class T>
bool chmin(T &a, const T b) {if (a > b) {a = b; return 1;} return 0;}

template<class T>
bool chmax(T &a, const T b) {if (a < b) {a = b; return 1;} return 0;}

using pll = pair<ll, ll>;
bool is_end = false;

struct edge
{
	ll weight, from, to;
	
	edge() = default;
	edge(ll w, ll f, ll t) : weight(w), from(f), to(t) { }
};

struct UnionFind
{
	int n;
	vector<int> par;
	
	UnionFind() = default;
	UnionFind(int nn) : n(nn), par(nn)
	{
		for (int i = 0; i < nn; ++i) {par[i] = i;}
	}
	
	int root(int v)
	{
		if (par[v] == v) {return v;}
		else {return par[v] = root(par[v]);}
	}
	
	bool same(int a, int b)
	{
		return root(a) == root(b);
	}
	
	void unite(int a, int b)
	{
		// a <- b
		par[root(b)] = root(a);
		return;
	}
	
};


void calc()
{
	ll N, M; cin >> N >> M;
	if (N == 0)
	{
		is_end = true;
		return;
	}
	
	vector<ll> H(N);
	vector<pair<ll, ll>> H_id(N);
	for (int i = 0; i < N; ++i)
	{
		ll h; cin >> h;
		H[i] = h;
		H_id[i] = make_pair(h, i);
	}
	sort(H_id.begin(), H_id.end());
	// reverse(H_id.begin(), H_id.end());
	
	ll leaf = H_id[0].second;
	ll root = H_id[N-1].second;
	
	vector<vector<edge>> graph(N);
	vector<vector<edge>> usable_edge(N);
	for (int i = 0; i < M; ++i)
	{
		ll a, b, c; cin >> a >> b >> c;
		a--, b--;
		graph[a].emplace_back(edge(c, a, b));
		graph[b].emplace_back(edge(c, b, a));
		
		if (H[a] <= H[b]) {usable_edge[a].emplace_back(edge(c, a, b));}
		if (H[a] >= H[b]) {usable_edge[b].emplace_back(edge(c, b, a));}
	}
	
	int day = -1;
	{
		for (int i = 0; i < N; ++i)
		{
			if (i > 0 && H_id[i].first == H_id[i-1].first) {continue;}
			
			UnionFind uf(N);
			vector<ll> vec;
			for (int j = i; j < N; ++j)
			{
				auto [h, v] = H_id[j];
				vec.emplace_back(v);
				for (auto [w, a, b] : usable_edge[v])
				{
					uf.unite(a, b);
				}
			}
			bool flg_con = true;
			for (auto v : vec) {flg_con &= uf.same(v, root);}
			
			if (flg_con)
			{
				day = H_id[i].first;
			}
			else
			{
				break;
			}			
		}
	}
	
	reverse(H_id.begin(), H_id.end());
	H_id.emplace_back(0, N);
	ll res = 0;
	UnionFind uf(N);
	vector<ll> vec;
	
	// cout << day << endl;
	// for (auto [h, v] : H_id)
	// {
	// 	cout << h << " " << v << endl;
	// }
	
	for (auto [h, v] : H_id)
	{
		if (h < day)
		{
			vector<edge> list;
			for (auto u : vec)
			{
				for (auto &e : usable_edge[u])
				{
					list.emplace_back(e);
				}
			}
			
			sort(list.begin(), list.end(), [&](auto lhs, auto rhs){
				return lhs.weight < rhs.weight;
			});
			
			for (auto [w, a, b] : list)
			{
				if (!uf.same(a, b))
				{
					uf.unite(a, b);
					res += w;
				}
			}
			
			vec.clear();
			day = h;
		}
		vec.emplace_back(v);		
	}
	
	bool flg_con = true;
	for (int i = 0; i < N; ++i)
	{
		flg_con &= uf.same(i, 0);
	}
	
	cout << (flg_con ? res : 0) << endl;
	
	return;
}

int main()
{
	while (!is_end)
	{
		calc();
	}
	
	return 0;
}
accuracy: 1
time_ms: 70
memory_kb: 8176
final_rank: 9

code_snippet: #include<iostream>
#include<vector>
#include<set>
#include<numeric>
#include<queue>
#include<stdio.h>

#define INF 1e9

using namespace std;

class UnionFind
{
private:
    std::vector<int> m_parents;
    std::vector<int> m_sizes;

public:
    UnionFind() = default;

    explicit UnionFind(size_t n)
        : m_parents(n)
        , m_sizes(n, 1)
        {
            std::iota(m_parents.begin(), m_parents.end(), 0);
        }

    int find(int i)
    {
        if (m_parents[i] == i)
        {
            return i;
        }

        return (m_parents[i] = find(m_parents[i]));
    }

    void merge(int a, int b)
    {
        a = find(a);
        b = find(b);

        if (a != b)
        {
            m_sizes[a] += m_sizes[b];
            m_parents[b] = a;
        }
    }

    bool connected(int a, int b)
    {
        return (find(a) == find(b));
    }
    
    int size(int i)
    {
        return m_sizes[find(i)];
    }
};

struct Island
{
    int id;
    int sinking_day;
    int cost;
} IslandsData[201];

void sortIsland( int left, int right )
{
    if( left < right )
    {
        int mid = IslandsData[( left + right ) / 2].sinking_day;
        int l = left, r = right;
        struct Island tmp;
        while( 1 )
        {
            while( IslandsData[l].sinking_day > mid ) l++;
            while( IslandsData[r].sinking_day < mid ) r--;
            if( l >= r ) break;
            tmp = IslandsData[l], IslandsData[l] = IslandsData[r], IslandsData[r] = tmp;
            l++;
            r--;
        }
        sortIsland( left, l - 1 );
        sortIsland( r + 1, right );
    }
}

int main( void )
{
    int N, M;
    while( 1 )
    {
        cin >> N >> M;
        if( N == 0 && M == 0 ) break;

        int h;
        for( int i = 1; i <= N; i++ )
        {
            scanf( "%d", &h );
            IslandsData[i].id = i;
            IslandsData[i].sinking_day = h;
            IslandsData[i].cost = INF;
        }

        vector<int> pos( 201 );
        sortIsland( 1, N );
        for( int i = 1; i <= N; i++ )
        {
            pos[IslandsData[i].id] = i;
        }

        vector<vector<pair<int, int>>> Graph( 201 );
        int a, b, c;
        for( int i = 0; i < M; i++ )
        {
            scanf( "%d %d %d", &a, &b, &c );
            Graph[a].push_back( make_pair( c, b ) );
            Graph[b].push_back( make_pair( c, a ) );
        }

        int ans = 0;
        set<int> candidates;
        priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> q;
        set<int> seen;
        UnionFind u( N + 1 );
        IslandsData[1].cost = 0;
        int island_p = 1, pre = 1, island_p_max = 1;
        seen.insert( IslandsData[1].id );
        while( island_p <= N )
        {
            while( island_p <= N && IslandsData[pre].sinking_day == IslandsData[island_p].sinking_day )
            {
                for( pair<int, int> v : Graph[IslandsData[island_p].id] )
                {
                    if( seen.count( v.second ) )
                    {
                        u.merge( IslandsData[island_p].id, v.second );
                    }
                }
                seen.insert( IslandsData[island_p].id );
                island_p++;
            }
            if( u.size( IslandsData[1].id ) != island_p - 1 ) island_p_max = island_p;
            pre = island_p;
        }
        seen.clear();
        if( island_p_max - 1 == N ) 
        {
            cout << 0 << endl;
            continue;
        }
        island_p = pre = 1;
        while( island_p <= N )
        {
            while( island_p <= N && ( IslandsData[pre].sinking_day == IslandsData[island_p].sinking_day || island_p < island_p_max || IslandsData[island_p_max].sinking_day == IslandsData[island_p].sinking_day ) )
            {
                for( pair<int, int> v : Graph[IslandsData[island_p].id] )
                {
                    if( seen.count( v.second ) )
                    {
                        IslandsData[island_p].cost = min( IslandsData[island_p].cost, v.first );
                    }
                }
                candidates.insert( IslandsData[island_p].id );
                if( IslandsData[island_p].cost == INF )
                {
                    island_p++;
                    continue;
                }
                q.push( make_pair( IslandsData[island_p].cost, IslandsData[island_p].id ) );
                island_p++;
            }

            pair<int, int> current;
            while( !q.empty() )
            {
                current = q.top(), q.pop();
                if( IslandsData[pos[current.second]].cost == INF ) break;
                if( seen.count( current.second ) ) continue;
                seen.insert( current.second );
                candidates.erase( current.second );
                ans += IslandsData[pos[current.second]].cost;
                for( pair<int, int> v : Graph[current.second] )
                {
                    if( candidates.count( v.second ) )
                    {
                        IslandsData[pos[v.second]].cost = min( IslandsData[pos[v.second]].cost, v.first );
                        q.push( make_pair( IslandsData[pos[v.second]].cost, v.second ) );
                    }
                }
            }
            pre = island_p;
        }

        cout << ans << endl;
    }

    return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 4028
final_rank: 1

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vi = vector<int>;
using pii = pair<int, int>;
#define rep(i, x) for(int i = 0; i < (x); i++)
#define rng(i, l, r) for(int i = (l); i < (r); i++)
#define all(v) (v).begin(), (v).end()
#define sz(v) (int)(v).size()

struct dsu {
	vi e;
	dsu(int n) : e(n, -1) {}
	int root(int x) { return e[x] < 0 ? x : e[x] = root(e[x]); }
	bool same(int u, int v) { return root(u) == root(v); }
	int size(int x) { return -e[root(x)]; }
	bool unite(int u, int v) {
		u = root(u), v = root(v);
		if(u == v) return false;
		if(e[u] < e[v]) swap(u, v);
		e[u] += e[v], e[v] = u;
		return true;
	}
};

void solve(int n, int m);
int main() {
	int n, m;
	while(cin >> n >> m, n + m) solve(n, m);
}

void solve(int n, int m) {
	vector<int> h(n);
	rep(i, n) cin >> h[i], --h[i];
	vector<vi> id(1000000);
	rep(i, n) id[h[i]].push_back(i);
	using T = tuple<int, int, int>;
	vector<vector<T>> es(1000000);
	rep(i, m) {
		int u, v, c;
		cin >> u >> v >> c, --u, --v;
		es[min(h[u], h[v])].push_back({c, u, v});
	}

	ll res = 0;
	dsu uf(n);
	int now = 0;
	int dame = -1;
	for(int i = 1000000 - 1; i >= 0; --i) {
		sort(all(es[i]));
		for(auto [c, u, v] : es[i]) {
			if(uf.unite(u, v)) res += c;
		}
		now += sz(id[i]);
		if(sz(id[i]) and uf.size(id[i][0]) != now) {
			dame = i;
		}
	}
	if(dame == -1)
		cout << res << endl;
	else {
		res = 0;
		uf = dsu(n);
		vector<T> ex;
		rng(i, dame, 1000000) {
			for(auto t : es[i]) ex.push_back(t);
		}
		sort(all(ex));
		for(int i = dame - 1; i >= 0; --i) {
			if(sz(es[i])) {
				for(auto t : ex) es[i].push_back(t);
				ex.clear();
			}
			sort(all(es[i]));
			for(auto [c, u, v] : es[i]) {
				if(uf.unite(u, v)) res += c;
			}
		}
		cout << res << endl;
	}
}
accuracy: 1
time_ms: 710
memory_kb: 73512
final_rank: 18

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef pair<int, int> PI;
typedef pair<int, PI> PPI;
struct UF{
    int root[220];
    int cnt[220];
    UF(){
        for(int i=0;i<220;i++){
            root[i] = i;
            cnt[i] = 1;
        }
    }
    int find(int a){
        if(root[a] == a) return a;
        return root[a] = find(root[a]);
    }
    void unite(int a, int b){
        a = find(a);
        b = find(b);
        root[b] = a;
        cnt[a] += cnt[b];
    }
    bool same(int a, int b){
        return find(a)==find(b);
    }
    int count(int a){
        return cnt[find(a)];
    }
};
int main(){
    int n, m, h[220], a, b, c, ans;
    while(cin >> n >> m, n!=0){
        vector<int> pres;
        for(int i=1;i<=n;i++){
            cin >> h[i];
            pres.push_back(h[i]);
        }
        sort(pres.begin(), pres.end());
        reverse(pres.begin(), pres.end());
        pres.erase(unique(pres.begin(), pres.end()), pres.end());
        vector<PPI> hvec[220];
        for(int i=0;i<m;i++){
            cin >> a >> b >> c;
            if(a > b) swap(a, b);
            if(h[a] > h[b]) swap(a, b);
            for(int j=0;j<pres.size();j++){
                if(pres[j] == h[a]) hvec[j].push_back(PPI(c, PI(a, b))); 
            }
        }
        for(int i=0;i<pres.size();i++) sort(hvec[i].begin(), hvec[i].end());
        UF uf;
        int sum = 0, node_sum=0, yame=-1;
        for(int i=0;i<pres.size();i++){
            for(int j=0;j<hvec[i].size();j++){
                int cost = hvec[i][j].first;
                PI pi = hvec[i][j].second;
                int u = pi.first;
                int v = pi.second;
                if(!uf.same(u, v)){
                    if(yame == -1 || yame < i) sum += cost;
                    uf.unite(v, u);
                }
            }
            for(int j=1;j<=n;j++){
                if(h[j] == pres[i]) node_sum++;
            }
            for(int j=1;j<=n;j++){
                if(h[j] >= pres[i] && uf.count(j) < node_sum){
                    sum = 0;
                    yame = i+1;
                }
            }
        }
        priority_queue<PPI, vector<PPI>, greater<PPI> > pq;
        for(int i=0;i<=yame;i++){
            for(int j=0;j<hvec[i].size();j++){
                pq.push(hvec[i][j]);
            }
        }
        UF uf2;
        while(!pq.empty()){
            PPI ppi = pq.top();
            pq.pop();
            int cost = ppi.first;
            PI pi = ppi.second;
            int u = pi.first;
            int v = pi.second;
            if(!uf2.same(u, v)){
                sum += cost;
                uf2.unite(v, u);
            }
        }
        for(int i=1;i<=n;i++){
            if(!uf.same(i, 1)) sum = 0;
        }
        cout << sum << endl;
    }
    return(0);
}
accuracy: 1
time_ms: 90
memory_kb: 3668
final_rank: 6

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
#include <deque>
#include <queue>
#include <string>
#include <iomanip>
#include <set>
#include <unordered_set>
#include <map>
#include <unordered_map>
#include <utility>
#include <stack>
#include <random>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include <assert.h>
// #if __has_include(<atcoder/all>)
// #include <atcoder/all>
// using namespace atcoder;
// #endif
using namespace std;
using ll=long long;
#define read(x) cin>>(x);
#define readll(x) ll (x);cin>>(x);
#define readS(x) string (x);cin>>(x);
#define readvll(x,N) vector<ll> (x)((N));for(int i=0;i<(N);i++){cin>>(x)[i];}
#define rep(i,N) for(ll (i)=0;(i)<(N);(i)++)
#define rep2d(i,j,H,W) for(ll (i)=0;(i)<(H);(i)++)for(ll (j)=0;(j)<(W);j++)
#define is_in(x,y) (0<=(x) && (x)<H && 0<=(y) && (y)<W)
#define yn {cout<<"Yes"<<endl;}else{cout<<"No"<<endl;}
inline ll powll(ll x,ll n){ll r=1;while(n>0){if(n&1){r*=x;};x*=x;n>>=1;};return r;}

struct dsu {
  public:
    dsu() : _n(0) {}
    explicit dsu(int n) : _n(n), parent_or_size(n, -1) {}

    int merge(int a, int b) {
        assert(0 <= a && a < _n);
        assert(0 <= b && b < _n);
        int x = leader(a), y = leader(b);
        if (x == y) return x;
        if (-parent_or_size[x] < -parent_or_size[y]) std::swap(x, y);
        parent_or_size[x] += parent_or_size[y];
        parent_or_size[y] = x;
        return x;
    }

    bool same(int a, int b) {
        assert(0 <= a && a < _n);
        assert(0 <= b && b < _n);
        return leader(a) == leader(b);
    }

    int leader(int a) {
        assert(0 <= a && a < _n);
        if (parent_or_size[a] < 0) return a;
        return parent_or_size[a] = leader(parent_or_size[a]);
    }

    int size(int a) {
        assert(0 <= a && a < _n);
        return -parent_or_size[leader(a)];
    }

    std::vector<std::vector<int>> groups() {
        std::vector<int> leader_buf(_n), group_size(_n);
        for (int i = 0; i < _n; i++) {
            leader_buf[i] = leader(i);
            group_size[leader_buf[i]]++;
        }
        std::vector<std::vector<int>> result(_n);
        for (int i = 0; i < _n; i++) {
            result[i].reserve(group_size[i]);
        }
        for (int i = 0; i < _n; i++) {
            result[leader_buf[i]].push_back(i);
        }
        result.erase(
            std::remove_if(result.begin(), result.end(),
                           [&](const std::vector<int>& v) { return v.empty(); }),
            result.end());
        return result;
    }

  private:
    int _n;
    // root node: -1 * component size
    // otherwise: parent
    std::vector<int> parent_or_size;
};

void solve(ll N,ll M){
  ll K=1000000;
  vector<vector<ll>> A(K);
  for(ll i=0;i<N;i++){
    ll h;
    cin>>h;
    A[h-1].push_back(i);
  }
  vector<vector<ll>> d(N,vector<ll>(N,-1));
  for(ll i=0;i<M;i++){
    ll a,b,c;
    cin>>a>>b>>c;
    a--;b--;
    d[a][b]=c;
    d[b][a]=c;
  }
  ll ans=0;
  dsu uf(N);
  vector<ll> ps;
  ps.reserve(N);
  vector<pair<ll,ll>> used;
  used.reserve(M);
  ll f2=1;
  for(ll i=K-1;i>=0;i--){
    if(A[i].empty()){
      continue;
    }
    // if(f2==1){
    //   for(ll j:A[i]){
    //     ps.push_back(j);
    //   }
    //   f2=0;
    //   continue;
    // }
    vector<pair<ll,pair<ll,ll>>> edge;
    dsu tuf(N);
    for(pair<ll,ll> j:used){
      tuf.merge(j.first,j.second);
    }
    for(ll j:A[i]){
      ps.push_back(j);
    }
    for(ll j:ps){
      for(ll l:ps){
        if(d[j][l]!=-1){
          tuf.merge(j,l);
          edge.push_back(make_pair(d[j][l],make_pair(j,l)));
        }
      }
    }
    ll led=tuf.leader(ps[0]);
    ll f=1;
    for(ll j:ps){
      if(led!=tuf.leader(j)){
        f=0;
        break;
      }
    }
    if(f==1){
      sort(edge.begin(),edge.end());
      for(pair<ll,pair<ll,ll>> j:edge){
        if(!uf.same(j.second.first,j.second.second)){
          uf.merge(j.second.first,j.second.second);
          used.push_back(j.second);
          ans+=j.first;
        }
      }
      //cerr<<i+1<<" "<<ans<<endl;
    }else{
      //cerr<<i+1<<" continue"<<endl;
      ans=0;
      used.clear();
      uf=dsu(N);
    }
  }
  cout<<ans<<endl;
  return;
}

int main(){
  ll N,M;
  while(1){
    cin>>N>>M;
    if(N==0 && M==0){
      break;
    }
    solve(N,M);
  }
}
accuracy: 1
time_ms: 780
memory_kb: 29800
final_rank: 17

code_snippet: #include <bits/stdc++.h>
#define rep(i,n) for(int i = 0; i < (n); i++)
using namespace std;
typedef long long ll;

class union_find {
  private:
    vector<int> parent;

  public:
    union_find(int n) : parent(n, -1) {}
    int unite(int x, int y) {
        x = root(x), y = root(y);
        if(x != y) {
            if(size(x) < size(y)) swap(x, y);
            parent[x] += parent[y];
            parent[y] = x;
            return x;
        }
        return -1;
    }
    int root(int x) { return parent[x] < 0 ? x : parent[x] = root(parent[x]); }
    int size(int x) { return -parent[root(x)]; }
    bool same(int x, int y) { return root(x) == root(y); }
};

int main(){
    cin.tie(0);
    ios::sync_with_stdio(0);
    
    while(true) {
        int n,m; cin >> n >> m; if(n == 0 && m == 0) break;
        vector<int> h(n);
        rep(i,n) cin >> h[i];

        vector<tuple<int,int,int>> edges(m);
        for(auto &[u, v, c] : edges) cin >> u >> v >> c, u--, v--;

        int mi = 1e9;
        {
            vector<int> h2 = h;
            h2.push_back(-1);
            for(int target : h2) {
                union_find uf(n);
                for(auto [u, v, c] : edges)
                    if(h[u] > target && h[v] > target) uf.unite(u, v);

                vector<int> vs; // 生き残り
                rep(i,n) if(h[i] > target) vs.push_back(i);
                if(!vs.empty() && uf.size(vs[0]) != (int)vs.size()) mi = min(mi, target);
            }
        }

        if(mi == -1){ cout << 0 << endl; continue; }

        for(int &x : h) x = min(x, mi);
        vector<tuple<int,int,int,int>> new_edges;
        for(auto [u, v, c] : edges) new_edges.push_back({min(h[u], h[v]), -c, u, v});
        sort(new_edges.rbegin(), new_edges.rend());

        union_find uf(n);
        ll cost = 0;
        for(auto [_, c, u, v] : new_edges) {
            c = -c;
            if(uf.unite(u, v) != -1) cost += c;
        }
        cout << cost << endl;
    }
}
accuracy: 1
time_ms: 110
memory_kb: 4080
final_rank: 8

code_snippet: #include <bits/extc++.h>

using namespace std;

#define rep(i,n) for(int i=0;i<(n);++i)
#define reps(i,s,n) for(int i=(s);i<=(n);++i)
#define all(x) begin(x), end(x)
#define Fixed fixed << setprecision(12)
constexpr int32_t INF  = 0x3f3f3f3f;
constexpr int64_t LINF = 0x3f3f3f3f3f3f3f3fLL;
constexpr int mod = 1e9+7;
// constexpr int mod = 998244353;

template <class Func>
class FixPoint : Func {
public:
    explicit constexpr FixPoint(Func&& f) noexcept : Func(forward<Func>(f)) {}

    template <class... Args>
    constexpr decltype(auto) operator()(Args&&... args) const {
        return Func::operator()(*this, std::forward<Args>(args)...);
    }
};

template <class Func>
static inline constexpr decltype(auto) makeFixPoint(Func&& f) noexcept {
    return FixPoint<Func>{forward<Func>(f)};
}

template <class A, class B> inline bool chmax(A &a, const B &b) { return b > a && (a = b, true); }
template <class A, class B> inline bool chmin(A &a, const B &b) { return b < a && (a = b, true); }

template <class T> using max_heap = priority_queue<T>;
template <class T> using min_heap = priority_queue<T,vector<T>,greater<T> >;
template <class A, class B> using umap = unordered_map<A,B>;
template <class A, class B> using uset = unordered_set<A,B>;

template <class T> using Set = __gnu_pbds::tree<T, __gnu_pbds::null_type, less<T>, __gnu_pbds::rb_tree_tag, __gnu_pbds::tree_order_statistics_node_update>;

template <class T> inline void bye(T x) { cout << x << '\n'; exit(0); }

inline int updiv(int a,int b){ return (a + b - 1) / b; }

constexpr int dx[] = {1, 0, -1, 0, 1, 1, -1, -1};
constexpr int dy[] = {0, -1, 0, 1, 1, -1, -1, 1};

struct UnionFind{
    int n;
    vector<int> data;

    UnionFind(int sz) : n(sz), data(sz, -1){}

    bool unite(int x, int y){
        x = find(x), y = find(y);
        if(x == y) return (false);
        if(data[x] > data[y]) swap(x, y);
        data[x] += data[y];
        data[y] = x;
        return (true);
    }

    int find(int k){
        if(data[k] < 0) return (k);
        return (data[k] = find(data[k]));
    }

    int size(int k){
        return (-data[find(k)]);
    }

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

    vector<vector<int> > groups(){
        vector<int> leader_buf(n), group_size(n);
        for(int i = 0; i < n; ++i){
            leader_buf[i] = find(i);
            group_size[leader_buf[i]]++;
        }
        vector<vector<int> > res(n);
        for(int i = 0; i < n; ++i){
            res[i].reserve(group_size[i]);
        }
        for(int i = 0; i < n; ++i){
            res[leader_buf[i]].emplace_back(i);
        }
        res.erase(
            remove_if(res.begin(), res.end(),
                      [&](const vector<int>& v){ return (v.empty()); }),
            res.end());
        return (res);
    }
};

signed main() {
    cin.tie(nullptr);
    ios_base::sync_with_stdio(false);

    int n, m;
    while (cin >> n >> m, n) {
        vector<int> h(n), v;
        for (int i = 0; i < n; ++i) {
            cin >> h[i];
            v.emplace_back(h[i]);
        }

        sort(all(v));

        v.erase(unique(all(v)), v.end());
        int sz = v.size();

        for (int i = 0; i < n; ++i) {
            h[i] = (sz - (lower_bound(all(v), h[i]) - v.begin())) - 1;
        }

        vector<vector<int> > sink(sz);

        for (int i = 0; i < n; ++i) {
            sink[h[i]].emplace_back(i);
        }

        vector<vector<pair<int, int> > > edge(n);
        vector<vector<tuple<int, int, int> > > edge_tp(sz);

        for (int i = 0; i < m; ++i) {
            int a, b, c;
            cin >> a >> b >> c;
            --a, --b;
            // tie(a, b) = minmax({a, b});
            edge[a].emplace_back(b, c);
            edge[b].emplace_back(a, c);
            edge_tp[max(h[a], h[b])].emplace_back(a, b, c);
        }

        for (int i = 0; i < n; ++i) {
            sort(all(edge[i]));
        }

        int fs = min_element(all(h)) - h.begin();
        UnionFind uf(n);
        int disconnected = -1;
        vector<bool> ng(n);

        for (int i = 0; i < sz; ++i) {
            for (auto [a, b, c] : edge_tp[i]) {
                uf.unite(a, b);
            }
            bool ok = true;
            for (int j = 0; j <= i; ++j) {
                for (auto il : sink[j]) {
                    ok &= uf.same(fs, il);
                }
            }
            if (!ok) disconnected = i;
        }

        uf = UnionFind(n);
        int64_t res = 0;
        min_heap<tuple<int, int, int> > pq;

        int cnt = 0;
        for (int i = 0; i <= disconnected; ++i) {
            for (auto [a, b, c] : edge_tp[i]) {
                pq.emplace(c, a, b);
            }
        }
        for (int i = disconnected + 1; i < sz; ++i) {
            for (auto [a, b, c] : edge_tp[i]) {
                pq.emplace(c, a, b);
            }
            while (!pq.empty()) {
                auto [c, a, b] = pq.top();
                if (uf.unite(a, b)) res += c;
                pq.pop();
            }
        } 

        cout << res << '\n';
    }

    return(0);
}
accuracy: 1
time_ms: 40
memory_kb: 4444
final_rank: 3

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

// template {{{
using i32 = int;
using u32 = unsigned int;
using i64 = long long;
using u64 = unsigned long long;

#define  range(i, l, r) for (i64 i = (i64)(l); i < (i64)(r); (i) += 1)
#define rrange(i, l, r) for (i64 i = (i64)(r) - 1; i >= (i64)(l); (i) -= 1)

#define  whole(f, x, ...) ([&](decltype((x)) container) { return (f)(  begin(container),  end(container), ## __VA_ARGS__); })(x)
#define rwhole(f, x, ...) ([&](decltype((x)) container) { return (f)( rbegin(container), rend(container), ## __VA_ARGS__); })(x)

#define debug(x) cerr << "(" << __LINE__ << ")" << #x << ": " << (x) << endl

constexpr i32 inf   = 1001001001;
constexpr i64 infll = 1001001001001001001ll;

constexpr i32 dx[] = {0, -1, 1, 0, -1, 1, -1, 1}; 
constexpr i32 dy[] = {-1, 0, 0, 1, -1, -1, 1, 1};

struct IoSetup { IoSetup(i32 x = 15){ cin.tie(0); ios::sync_with_stdio(0); cout << fixed << setprecision(x); cerr << fixed << setprecision(x); } } iosetup;

template <typename T = i64> T input() { T x; cin >> x; return x; }

template <typename T> ostream &operator<<(ostream &os, vector<T> &v) { range(i, 0, v.size()) { os << v[i] << (i + 1 != (int)v.size() ? " " : ""); } return os; } 
template <typename T> istream &operator>>(istream &is, vector<T> &v) { for (T &in : v) is >> in; return is; }

template <typename T1, typename T2> ostream &operator<<(ostream &os, pair<T1, T2> p) { os << "(" << p.first << ", " << p.second << ")"; return os; }
template <typename T1, typename T2> istream &operator>>(istream &is, pair<T1, T2> &p) { is >> p.first >> p.second; return is; }

template <typename T> vector<T> make_vector(size_t a, T b) { return vector<T>(a, b); }
template <typename... Ts> auto make_vector(size_t a, Ts... ts) { return vector<decltype(make_vector(ts...))>(a, make_vector(ts...)); }

template <typename T1, typename T2> inline bool chmax(T1 &a, T2 b) { return a < b && (a = b, true); }
template <typename T1, typename T2> inline bool chmin(T1 &a, T2 b) { return a > b && (a = b, true); }
// }}}

struct UnionFind {
  vector< int > data;

  UnionFind() = default;

  explicit UnionFind(size_t sz) : data(sz, -1) {}

  bool unite(int x, int y) {
    x = find(x), y = find(y);
    if(x == y) return false;
    if(data[x] > data[y]) swap(x, y);
    data[x] += data[y];
    data[y] = x;
    return true;
  }

  int find(int k) {
    if(data[k] < 0) return (k);
    return data[k] = find(data[k]);
  }

  int size(int k) {
    return -data[find(k)];
  }

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

  vector< vector< int > > groups() {
    int n = (int) data.size();
    vector< vector< int > > ret(n);
    for(int i = 0; i < n; i++) {
      ret[find(i)].emplace_back(i);
    }
    ret.erase(remove_if(begin(ret), end(ret), [&](const vector< int > &v) {
      return v.empty();
    }), end(ret));
    return ret;
  }
};

void solve(int n, int m) {
  vector< int > hs(n);
  cin >> hs;

  {
    auto tmp = hs;
    whole(sort, tmp);
    tmp.erase(whole(unique, tmp), tmp.end());
    for (auto &h: hs) h = whole(lower_bound, tmp, h) - tmp.begin();
  }

  vector< vector<int> > vs(n);
  range(v, 0, n) {
    vs[hs[v]].emplace_back(v);
  }

  auto G = make_vector(n, 0, pair<int, int>());
  range(i, 0, m) {
    int u = input() - 1, v = input() - 1;
    int c = input();
    G[u].emplace_back(v, c);
    G[v].emplace_back(u, c);
  }

  int mxh = n;
  {
    UnionFind uf(n);
    int m = n;
    int r = n;
    rrange(h, 0, n) {
      for (auto &v: vs[h]) {
        m--;
        for (auto &[u, _]: G[v]) {
          if (hs[v] > hs[u]) continue;
          if (not uf.same(u, v)) r--;
          uf.unite(u, v);
        }
      }

      if (m + 1 != r) mxh = h - 1;
    }
  }

  i64 ans = 0;
  UnionFind uf(n);
  using pii = pair<int, int>;
  vector< pair<int, pii> > es;
  rrange(h, 0, n) {
    for (auto &v: vs[h]) {
      for (auto &[u, cost]: G[v]) {
        if (hs[v] > hs[u]) continue;
        es.emplace_back(cost, pii(u, v));
      }
    }

    if (mxh < h) continue;
    whole(sort, es);
    for (auto &[cost, p]: es) {
      auto [u, v] = p;
      if (uf.same(u, v)) continue;
      uf.unite(u, v);
      ans += cost;
    }
    es.clear();
  }
  
  cout << ans << endl;
}

signed main() {
  int n, m;

  while (cin >> n >> m, n) {
    solve(n, m);
  }
}
accuracy: 1
time_ms: 30
memory_kb: 4960
final_rank: 2

code_snippet: #include <bits/extc++.h>

using namespace std;

#define rep(i,n) for(int i=0;i<(n);++i)
#define reps(i,s,n) for(int i=(s);i<=(n);++i)
#define all(x) begin(x), end(x)
#define Fixed fixed << setprecision(12)
constexpr int32_t INF  = 0x3f3f3f3f;
constexpr int64_t LINF = 0x3f3f3f3f3f3f3f3fLL;
constexpr int mod = 1e9+7;
// constexpr int mod = 998244353;

template <class Func>
class FixPoint : Func {
public:
    explicit constexpr FixPoint(Func&& f) noexcept : Func(forward<Func>(f)) {}

    template <class... Args>
    constexpr decltype(auto) operator()(Args&&... args) const {
        return Func::operator()(*this, std::forward<Args>(args)...);
    }
};

template <class Func>
static inline constexpr decltype(auto) makeFixPoint(Func&& f) noexcept {
    return FixPoint<Func>{forward<Func>(f)};
}

template <class A, class B> inline bool chmax(A &a, const B &b) { return b > a && (a = b, true); }
template <class A, class B> inline bool chmin(A &a, const B &b) { return b < a && (a = b, true); }

template <class T> using max_heap = priority_queue<T>;
template <class T> using min_heap = priority_queue<T,vector<T>,greater<T> >;
template <class A, class B> using umap = unordered_map<A,B>;
template <class A, class B> using uset = unordered_set<A,B>;

template <class T> using Set = __gnu_pbds::tree<T, __gnu_pbds::null_type, less<T>, __gnu_pbds::rb_tree_tag, __gnu_pbds::tree_order_statistics_node_update>;

template <class T> inline void bye(T x) { cout << x << '\n'; exit(0); }

inline int updiv(int a,int b){ return (a + b - 1) / b; }

constexpr int dx[] = {1, 0, -1, 0, 1, 1, -1, -1};
constexpr int dy[] = {0, -1, 0, 1, 1, -1, -1, 1};

struct UnionFind{
    int n;
    vector<int> data;

    UnionFind(int sz) : n(sz), data(sz, -1){}

    bool unite(int x, int y){
        x = find(x), y = find(y);
        if(x == y) return (false);
        if(data[x] > data[y]) swap(x, y);
        data[x] += data[y];
        data[y] = x;
        return (true);
    }

    int find(int k){
        if(data[k] < 0) return (k);
        return (data[k] = find(data[k]));
    }

    int size(int k){
        return (-data[find(k)]);
    }

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

    vector<vector<int> > groups(){
        vector<int> leader_buf(n), group_size(n);
        for(int i = 0; i < n; ++i){
            leader_buf[i] = find(i);
            group_size[leader_buf[i]]++;
        }
        vector<vector<int> > res(n);
        for(int i = 0; i < n; ++i){
            res[i].reserve(group_size[i]);
        }
        for(int i = 0; i < n; ++i){
            res[leader_buf[i]].emplace_back(i);
        }
        res.erase(
            remove_if(res.begin(), res.end(),
                      [&](const vector<int>& v){ return (v.empty()); }),
            res.end());
        return (res);
    }
};

signed main() {
    cin.tie(nullptr);
    ios_base::sync_with_stdio(false);

    int n, m;
    while (cin >> n >> m, n) {
        vector<int> h(n), v;
        for (int i = 0; i < n; ++i) {
            cin >> h[i];
            v.emplace_back(h[i]);
        }

        sort(all(v));

        v.erase(unique(all(v)), v.end());
        int sz = v.size();

        for (int i = 0; i < n; ++i) {
            h[i] = (sz - (lower_bound(all(v), h[i]) - v.begin())) - 1;
        }

        vector<vector<int> > sink(sz);

        for (int i = 0; i < n; ++i) {
            sink[h[i]].emplace_back(i);
        }

        vector<vector<pair<int, int> > > edge(n);
        vector<vector<tuple<int, int, int> > > edge_tp(sz);

        for (int i = 0; i < m; ++i) {
            int a, b, c;
            cin >> a >> b >> c;
            --a, --b;
            // tie(a, b) = minmax({a, b});
            edge[a].emplace_back(b, c);
            edge[b].emplace_back(a, c);
            edge_tp[max(h[a], h[b])].emplace_back(a, b, c);
        }

        for (int i = 0; i < n; ++i) {
            sort(all(edge[i]));
        }

        int fs = min_element(all(h)) - h.begin();
        UnionFind uf(n);
        int disconnected = -1;
        vector<bool> ng(n);

        for (int i = 0; i < sz; ++i) {
            for (auto [a, b, c] : edge_tp[i]) {
                uf.unite(a, b);
            }
            bool ok = true;
            for (int j = 0; j <= i; ++j) {
                for (auto il : sink[j]) {
                    ok &= uf.same(fs, il);
                }
            }
            if (!ok) disconnected = i;
        }

        uf = UnionFind(n);
        int64_t res = 0;
        min_heap<tuple<int, int, int> > pq;

        int cnt = 0;
        for (int i = 0; i <= disconnected; ++i) {
            for (auto [a, b, c] : edge_tp[i]) {
                pq.emplace(c, a, b);
            }
        }
        for (int i = disconnected + 1; i < sz; ++i) {
            for (auto [a, b, c] : edge_tp[i]) {
                pq.emplace(c, a, b);
            }
            while (!pq.empty()) {
                auto [c, a, b] = pq.top();
                if (uf.unite(a, b)) res += c;
                pq.pop();
            }
        } 

        cout << res << '\n';
    }

    return(0);
}
accuracy: 1
time_ms: 40
memory_kb: 4520
final_rank: 4