#include<cstdio>
#include<vector>
#include<queue>
using namespace std;
#define INF 1000000000000000000ll
int n,m;
struct edge
{
int a,b;
};
struct node
{
long long w;
int pos;
friend bool operator < (node a,node b)
{
return a.w>b.w;
}
};
vector<edge>g[1001];
priority_queue<node>q;
long long dis[1001],cnt[1001];
bool vis[1001];
int a[1001];
void Dijkstra()
{
for(int i=0;i<=n-1;i++)
{
dis[i]=a[i];
cnt[i]=1;
q.push((node){dis[i],i});
}
while(!q.empty())
{
int u=q.top().pos;
q.pop();
if(vis[u])
{
continue;
}
vis[u]=true;
for(int i=0;i<g[u].size();i++)
{
int a=g[u][i].a,b=g[u][i].b;
if(dis[u]>dis[a]+dis[b])
{
dis[u]=dis[a]+dis[b];
cnt[u]=cnt[a]*cnt[b];
q.push((node){dis[u],u});
}
else if(dis[u]==dis[a]+dis[b])
{
cnt[u]+=cnt[a]*cnt[b];
}
}
}
}
int main()
{
scanf("%d",&n);
for(int i=0;i<=n-1;i++)
{
scanf("%d",&a[i]);
}
int a,b,c;
while(scanf("%d%d%d",&a,&b,&c)==3)
{
g[c].push_back((edge){a,b});
}
Dijkstra();
printf("%d %d",dis[0],cnt[0]);
return 0;
}