#include #include #include #include using namespace std; const long long INF = 1e18; struct Edge { int to; long long cost; }; int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); int N, M; if (!(cin >> N >> M)) return 0; vector P(N + 1); for (int i = 1; i <= N; ++i) { cin >> P[i]; } vector> adj(N + 1); for (int i = 0; i < M; ++i) { int u, v; long long t; cin >> u >> v >> t; adj[u].push_back({v, t}); } long long min_cost = INF; long long ways = 0; bool has_reachable = false; // 各頂点 A を始点として個別に SPFA を実行 for (int start = 1; start <= N; ++start) { vector dist(N + 1, INF); vector in_queue(N + 1, false); queue q; dist[start] = 0; q.push(start); in_queue[start] = true; while (!q.empty()) { int u = q.front(); q.pop(); in_queue[u] = false; for (auto& edge : adj[u]) { int v = edge.to; if (dist[u] + edge.cost < dist[v]) { dist[v] = dist[u] + edge.cost; if (!in_queue[v]) { q.push(v); in_queue[v] = true; } } } } // コストの更新 for (int target = 1; target <= N; ++target) { if (start == target || dist[target] >= INF) continue; has_reachable = true; long long current_cost = dist[target] + P[start] + P[target]; if (current_cost < min_cost) { min_cost = current_cost; ways = 1; } else if (current_cost == min_cost) { ways++; } } } if (!has_reachable) { cout << -1 << "\n"; } else { cout << min_cost << " " << ways << "\n"; } return 0; }