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

typedef vector<int> VI;
typedef vector<VI> VVI;
typedef vector<string> VS;
typedef pair<int, int> PII;
typedef long long LL;
typedef pair<LL, LL> PLL;

#define ALL(a)  (a).begin(),(a).end()
#define RALL(a) (a).rbegin(), (a).rend()
#define PB push_back
#define EB emplace_back
#define MP make_pair
#define SZ(a) int((a).size())
#define EACH(i,c) for(typeof((c).begin()) i=(c).begin(); i!=(c).end(); ++i)
#define EXIST(s,e) ((s).find(e)!=(s).end())
#define SORT(c) sort((c).begin(),(c).end())

#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,n)  FOR(i,0,n)

#define FF first
#define SS second
template<class S, class T>
istream& operator>>(istream& is, pair<S,T>& p){
  return is >> p.FF >> p.SS;
}

const double EPS = 1e-10;
const double PI  = acos(-1.0);
const LL MOD = 1e9+7;

struct Edge{
  int from, to, cost;

  Edge(int f, int t, int c): from(f), to(t), cost(c)
  {}
  bool operator>(const Edge& rhs) const{
	return cost > rhs.cost;
  }
  bool operator<(const Edge& rhs) const{
	return cost < rhs.cost;
  }

};
typedef vector< vector<Edge> > Graph;
void add_edge(Graph& graph, int u, int v, int cost){
  graph[u].push_back(Edge(u,v,cost));
  graph[v].push_back(Edge(v,u,cost));
}

class UnionFind{
private:
  vector<int> par, rank;
public:
  UnionFind(int n){
	par.assign(n, 0);
	rank.assign(n, 0);
	for(int i=0;i<n;++i)
	  par[i] = i;
  }

  //find root of x
  int find(int x){
	if(par[x] == x)
	  return x;
	return (par[x] = find(par[x]));
  }

  void unite(int x, int y){
	x = find(x);
	y = find(y);
	if(x == y) return;

	if(rank[x] < rank[y])
	  par[x] = y;
	else{
	  par[y] = x;
	  if(rank[x] == rank[y])
		++rank[x];
	}
  }

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

int kruskal(const Graph& G){
  int N = SZ(G);
  UnionFind uf(N);
  vector<pair<Edge,int>> edges;
  REP(i,N) for(auto& e:G[i]){
	edges.push_back(MP(e, i));
  }
  sort(ALL(edges));

  int res = 0, i, n;
  for(i=0,n=1;n<N&&i<SZ(edges);++i){
	auto& e = edges[i].first;
	int v = edges[i].second;
	if(!uf.same(e.to,v)){
	  uf.unite(e.to, v);
	  res += e.cost;
	  ++n;
	}
  }
  return (n==N? res: -1);
}

int main(){
  cin.tie(0);
  ios_base::sync_with_stdio(false);

  int V, E;
  while(cin>>V>>E,V){
	vector<PII> days(V);
	REP(i,V){
	  cin >> days[i].FF;
	  days[i].SS = i;
	}
	SORT(days);
	Graph G(V);
	REP(i,E){
	  int a, b, c; cin >> a >> b >> c;
	  --a, --b;
	  add_edge(G, a, b, c);
	}

	UnionFind uf(V);
	vector<bool> use(V);
	priority_queue<Edge,vector<Edge>,greater<Edge>> pq;
	int ans = 0;
	for(int i=V-1;i>=0;){
	  int j;
	  VI buf;
	  for(j=i;j>=0;--j)
		if(days[j].FF == days[i].FF){
		  buf.PB(days[j].SS);
		  use[days[j].SS] = true;
		}
		else break;
	  i = j;

	  for(int u: buf){
		for(auto& e: G[u]){
		  if(use[e.to])
			pq.push(e);
		}
	  }

	  auto uf_ = uf;
	  auto pq_ = pq;
	  int sum = 0;
	  while(!pq_.empty()){
		auto e = pq_.top(); pq_.pop();
		if(uf_.same(e.from, e.to)) continue;
		else{
		  sum += e.cost;
		  uf_.unite(e.from, e.to);
		}
	  }

	  int id = uf_.find(buf[0]);
	  bool ok = true;
	  REP(j,V)
		if(use[j] && uf_.find(j) != id){
		  ok = false;
		  break;
		}
	  if(ok){
		uf = uf_;
		pq = pq_;
		ans += sum;
	  }
	  else{
		ans = 0;
		uf = UnionFind(V);
		pq = pq_;
		REP(u,V)
		  if(use[u])
			for(auto& e: G[u])
			  if(use[e.to])
				pq.push(e);
	  }
	}
	cout << ans << endl;
  }

  return 0;
}

Measured memory_bytes: 4872