#include <cstdio>#include <algorithm>#include <queue>#include <cstdlib>#include <cstring>#include <iostream>#define int long long using namespace std;inline int gi(){char tmp=getchar();int ans=0;while(!isdigit(tmp))tmp=getchar();while(isdigit(tmp)){ans=ans*10+tmp-'0';tmp=getchar();}return ans;}int n;const int N = 1020000;struct Edg{int v,w,nxt;}Edge[N<<1];int Head[N];inline void Add(int u,int v,int w){static int cnt=0;Edge[++cnt].v=v;Edge[cnt].nxt=Head[u];Head[u]=cnt;Edge[cnt].w=w;}struct Nod{ int pos,dis; bool operator > (const Nod &x)const{ return dis > x.dis; }};int Dis[N],Vis[N];priority_queue<Nod,vector<Nod>,greater<Nod> > Q;inline void Pu(int pos,int dis){ Nod p;p.pos=pos;p.dis=dis; Q.push(p);}int Ans[N];void Dij(){ while(!Q.empty()){ int pos=Q.top().pos;Q.pop(); if(Vis[pos]) continue; // Ans[pos] = Ans[pos] - (Ans[pos]>>1ll); Vis[pos] = 1; for(int i=Head[pos];i;i=Edge[i].nxt){ int arr = Edge[i].v,w=Edge[i].w; if(Vis[arr]==0)continue; if(Dis[pos] + Dis[arr] == Dis[w]){ Ans[w] += Ans[pos] * Ans[arr]; } if(Dis[pos] + Dis[arr] < Dis[w]){ Ans[w] = Ans[pos] * Ans[arr]; Dis[w] = Dis[pos] + Dis[arr]; Pu(w,Dis[w]); } } }}signed main(){#ifdef TSUKIAKIOI freopen("data.in","r",stdin);#endif int n=gi(); for(int i=1;i<=n;++i) {Dis[i]=gi();Pu(i,Dis[i]);Ans[i]=1;} int a,b,c; while(~scanf("%lld%lld%lld",&a,&b,&c)){ a++,b++,c++; Add(a,b,c); if(a==b) continue; Add(b,a,c); } Dij(); printf("%lld %lld",Dis[1],Ans[1]); return 0;}