#include <iostream>
#include <iomanip>
#include <cstdio>
#include <string>
#include <cstring>
#include <deque>
#include <list>
#include <queue>
#include <stack>
#include <vector>
#include <utility>
#include <algorithm>
#include <map>
#include <set>
#include <complex>
#include <cmath>
#include <limits>
#include <climits>
#include <ctime>
#include <cassert>
using namespace std;

#define rep(i,a,n) for(int (i)=(a); (i)<(n); (i)++)
#define repq(i,a,n) for(int (i)=(a); (i)<=(n); (i)++)
#define repr(i,a,n) for(int (i)=(a); (i)>=(n); (i)--)
#define all(v) begin(v), end(v)
#define pb(a) push_back(a)
#define fr first
#define sc second
#define INF 2000000000
#define int long long int

#define X real()
#define Y imag()
#define EPS (1e-10)
#define EQ(a,b) (abs((a) - (b)) < EPS)
#define EQV(a,b) ( EQ((a).X, (b).X) && EQ((a).Y, (b).Y) )
#define LE(n, m) ((n) < (m) + EPS)
#define LEQ(n, m) ((n) <= (m) + EPS)
#define GE(n, m) ((n) + EPS > (m))
#define GEQ(n, m) ((n) + EPS >= (m))

typedef vector<int> VI;
typedef vector<VI> MAT;
typedef pair<int, int> pii;
typedef long long ll;

typedef complex<double> P;
typedef pair<P, P> L;
typedef pair<P, double> C;

int dy[]={0, 0, 1, -1};
int dx[]={1, -1, 0, 0};
int const MOD = 1000000007;

namespace std {
    bool operator<(const P& a, const P& b) {
        return a.X != b.X ? a.X < b.X : a.Y < b.Y;
    }
}

// ?§?????????¨????????¨???????????????????¨???????????§???????
template <typename T>
struct Edge {
    int from, to;
    T cost;
    Edge(int s, T d) : to(s), cost(d) {}
    Edge(int f, int s, T d) : from(f), to(s), cost(d) {}

    bool operator<(const Edge &e) const {
        return cost < e.cost;
    }
    bool operator>(const Edge &e) const {
        return cost > e.cost;
    }
};
#define Graph(type) vector< vector< Edge<type> > >

// Union-Find ??¨ (Verified: AtCoder Typical Contest 001 B)
struct UnionFind {
private:
    const int n;
    int __size;
    vector<int> uf;
public:
    // ????????? UnionFind uni(n) ??????????????£?¨?????????°??????
    UnionFind(int _n) : n(_n), __size(_n), uf(_n, -1) {}
    // find (??¨??????????±???????)
    int find(int x) {return (uf[x] < 0) ? x : uf[x] = find(uf[x]);}
    // x ??¨ y ???????????????????±???????????????????
    bool same(int x, int y) {return find(x) == find(y);}
    // x ????±????????????????????´???°
    int size(int x) {return -uf[find(x)];}
    // ???????????????????????????
    int size()      {return __size;}
    // x ??¨ y ????±??????????????????????
    void unite(int x, int y) {
        x = find(x); y = find(y);
        if(x == y) return;
        __size--;
        if(uf[y] < uf[x]) swap(x, y);
        uf[x] += uf[y]; uf[y] = x;
    }
    // ???????????°??¨ (???????????????)
    void debug() {for(auto e : uf) printf("UnionFind_debug: %lld\n", e);}
};

int N, M;
// time, index
pii H[210];
bool points[210];

signed main() {
    while(cin >> N >> M, N || M) {
        memset(points, false, sizeof(points));
        rep(i,0,N) {
            int p; cin >> p;
            H[i] = pii(p, i);
        }
        sort(H, H+N, greater<pii>());

        priority_queue< Edge<int>, vector< Edge<int> >, greater< Edge<int> > > es;
        rep(i,0,M) {
            int a, b, c; cin >> a >> b >> c; a--; b--;
            es.push(Edge<int>(a, b, c));
        }

        UnionFind uf(N), uff(N);
        int k = 0, ans = 0, MAXT = INF;
        while(k < N) {
            // val ??¨??????????????????????????????????????????
            int val = H[k].first;
            while(H[k].first == val && k < N) points[H[k++].second] = true;

            priority_queue< Edge<int>, vector< Edge<int> >, greater< Edge<int> > > fs = es;
            while(!fs.empty()) {
                Edge<int> cur = fs.top(); fs.pop();
                int a = cur.from, b = cur.to;
                bool ng = false;
                if(!points[a] || !points[b]) ng = true;
                if(uf.same(a, b)) ng = true;
                if(!ng) {
                    uf.unite(a, b);
                    // ans += cur.cost;
                }
            }
            set<int> sz;
            rep(i,0,N) if(points[i]) sz.insert(uf.find(i));
            if(sz.size() != 1) MAXT = (k == N ? 0 : H[k].first);
        }

        // printf("MAXT = %lld\n", MAXT);
        k = 0;
        memset(points, false, sizeof(points));
        bool init = true;
        while(k < N) {
            if(init) {
                // MAXT ??\?????????????????????????????????
                init = false;
                while(H[k].first >= MAXT && k < N) points[H[k++].second] = true;
            }
            else {
                int val = H[k].first;
                while(H[k].first == val && k < N) points[H[k++].second] = true;
            }

            priority_queue< Edge<int>, vector< Edge<int> >, greater< Edge<int> > > fs = es;
            while(!fs.empty()) {
                Edge<int> cur = fs.top(); fs.pop();
                int a = cur.from, b = cur.to;
                bool ng = false;
                if(!points[a] || !points[b]) ng = true;
                if(uff.same(a, b)) ng = true;
                if(!ng) {
                    uff.unite(a, b);
                    ans += cur.cost;
                }
            }
        }
        cout << (uff.size() == 1 ? ans : 0) << endl;
    }
    return 0;
}

Measured memory_bytes: 4112