#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <numeric>

#define REP(i, a, b) for (int i = int(a); i < int(b); i++)
using namespace std;
typedef long long int ll;

// clang-format off
#ifdef _DEBUG_
#define dump(...) do{ cerr << __LINE__ << ":\t" << #__VA_ARGS__ << " = "; PPPPP(__VA_ARGS__); cerr << endl; } while(false)
template<typename T> void PPPPP(T t) { cerr << t; }
template<typename T, typename... S> void PPPPP(T t, S... s) { cerr << t << ", "; PPPPP(s...); }
#else
#define dump(...)
#endif
template<typename T> vector<T> make_v(size_t a, T b) { return vector<T>(a, b); }
template<typename... Ts> auto make_v(size_t a, Ts... ts) { return vector<decltype(make_v(ts...))>(a, make_v(ts...)); }
    // clang-format on

#include <tuple>
using Edge = tuple<ll, int, int>;

class UnionFind {
public:
    vector<int> par;
    int N;
    UnionFind(int n) {
        par.resize(n, -1);
        N = n;
    }
    int Find(int n) {
        return par[n] < 0 ? n : par[n] = Find(par[n]);
    }
    bool Union(int x, int y) {
        x = Find(x);
        y = Find(y);
        if (x == y) return false;
        if (-par[x] < -par[y]) swap(x, y);
        par[y] += par[x];
        par[x] = y;
        N--;
        return true;
    }
    bool Same(int x, int y) {
        return Find(x) == Find(y);
    }
    int size(int x) {
        return -par[Find(x)];
    }
    int size() {
        return N;
    }
};

#include <map>

int main() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    int n, m;
    while (cin >> n >> m, n + m) {
        vector<ll> h(n);
        REP(i, 0, n) {
            cin >> h[i];
        }
        map<ll, vector<Edge>> Graph;
        vector<Edge> All(m);
        REP(i, 0, m) {
            int a, b, c;
            cin >> a >> b >> c;
            a--;
            b--;
            Graph[min(h[a], h[b])].emplace_back(c, a, b);
            All[i] = make_tuple(c, a, b);
        }
        for (auto &e : Graph) {
            sort(e.second.begin(), e.second.end());
        }
        sort(All.begin(), All.end());

        {
            UnionFind uf(n);
            REP(i, 0, m) {
                ll cost;
                int a, b;
                tie(cost, a, b) = All[i];
                uf.Union(a, b);
            }
            if (uf.size() != 1) {
                cout << 0 << endl;
                continue;
            }
        }

        ll lastT = 1LL << 60;
        for (auto it = Graph.begin(); it != Graph.end(); it++) {
            UnionFind uf(n);
            vector<bool> used(n, false);
            REP(i, 0, n) {
                used[i] = h[i] > it->first;
            }
            REP(i, 0, m) {
                int a, b;
                tie(ignore, a, b) = All[i];
                if (used[a] && used[b]) {
                    uf.Union(a, b);
                }
            }
            vector<bool> check(n, false);
            REP(i, 0, n) {
                if (used[i]) {
                    check[uf.Find(i)] = true;
                }
            }
            int sz = 0;
            REP(i, 0, n) {
                sz += check[i];
            }
            if (sz != 1) {
                lastT = it->first;
                break;
            }
        }
        dump(lastT);

        UnionFind uf(n);
        ll ans = 0;
        for (auto &tp : All) {
            ll cost;
            int a, b;
            tie(cost, a, b) = tp;
            if (h[a] < lastT || h[b] < lastT) continue;
            if (uf.Union(a, b)) {
                ans += cost;
            }
        }

        for (auto it = Graph.rbegin(); it != Graph.rend(); it++) {
            if (it->first < lastT) {
                for (auto &tp : it->second) {
                    ll cost;
                    int a, b;
                    tie(cost, a, b) = tp;
                    if (uf.Union(a, b)) {
                        ans += cost;
                    }
                }
            }
        }
        cout << ans << endl;
    }

    return 0;
}



Measured memory_bytes: 3984