#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
#include <utility>
#include <map>
#include <iostream>
#define PI make_pair
#define ll long long
#define INF 0x3f3f3f3f
using namespace std;
ll rd() {
ll x = 0, w = 1;
char c = getchar();
while(c < '0' || c > '9') {
if(c == '-') w = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
x = x * 10 + c - '0';
c = getchar();
}
return x * w;
}
const int M = 1e6 + 5, N = 1e5 + 5;
int n, m;
map < pair <int, int> , ll> ds;
struct Graph {
int v, nxt, w;
}e[M << 1];
int lk[N], ltp;
int h[N];
void ins(int u, int v, int w) {
e[++ltp] = (Graph) {v, lk[u], w};
lk[u] = ltp;
}
struct Edge {
int u, v, w;
}a[M << 1];
bool vis[N];
int b[M << 1];
int cnt, num;
void bfs(int s) {
queue <int> q;
q.push(s);
while(!q.empty()) {
int u = q.front();
q.pop();
if(vis[u]) continue;
vis[u] = true;
for(int i = lk[u]; i; i = e[i].nxt) {
int v = e[i].v, w = e[i].w;
if(h[u] >= h[v]) {
q.push(v);
a[++cnt] = (Edge) {u, v, w};
++num;
}
}
}
}
int dad[N];
bool cmp(Edge x, Edge y) {
if(h[x.v] == h[x.v]) return x.w < y.w;
return h[x.v] < h[y.v];
}
int anc(int x) {
if(dad[x] != x) return dad[x] = anc(dad[x]);
return x;
}
bool ask(int x, int y) {
return anc(x) == anc(y);
}
void uni(int x, int y) {
x = anc(x), y = anc(y);
if(x != y)
dad[x] = y;
}
int main() {
n = rd(), m = rd();
for(int i = 1; i <= n; ++i) h[i] = rd();
for(int i = 1; i <= m; ++i) {
int u = rd(), v = rd(), w = rd();
ins(u, v, w);
ins(v, u, w);
}
bfs(1);
sort(a + 1, a + 1 + cnt, cmp);
for(int i = 1; i <= n; ++i) dad[i] = i;
ll tot = 0, ans = 0;
for(int i = 1; i <= cnt; ++i) {
if(tot == num - 1) break;
if(!ask(a[i].u, a[i].v)) {
uni(a[i].u, a[i].v);
ans += a[i].w;
++tot;
}
}
printf("%lld %lld", num, ans);
return 0;
}