#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
inline ll read()
{
char ch=getchar();
ll x=0;
while(!isdigit(ch))
ch=getchar();
while(isdigit(ch))
{
x=x*10+ch-'0';
ch=getchar();
}
return x;
}
ll n,m,t;
struct edge
{
ll fr,to,nex,l;
}e[100010];
ll point[100010],cnt=0;
struct tmp_edge
{
ll fr,to,l;
}tmp_e[100010];
ll tmp_love[30010],fa[30010];
inline void add(ll x,ll y,ll l)
{
e[++cnt].to=y;
e[cnt].nex=point[x];
point[x]=cnt;
e[cnt].l=l;
e[cnt].fr=x;
}
inline bool cmp(tmp_edge x,tmp_edge y)
{
return x.l<y.l;
}
inline ll getf(ll x)
{
if(x!=fa[x]) fa[x]=getf(fa[x]);
return fa[x];
}
void kruskal()
{
ll i;
sort(tmp_e+1,tmp_e+m+1,cmp);
for(i=1;i<=n;i++)
fa[i]=i;
for(i=1;i<=m;i++)
{
ll f1=getf(tmp_e[i].fr);
ll f2=getf(tmp_e[i].to);
if(f1!=f2)
{
fa[f1]=f2;
add(tmp_e[i].fr,tmp_e[i].to,tmp_e[i].l);
add(tmp_e[i].to,tmp_e[i].fr,tmp_e[i].l);
}
}
}
ll son[30010],num[30010],top[30010],deep[30010];
ll leaf[30010],order=0,pos[30010];
bool vis[30010];
inline void dfs1(ll p)
{
vis[p]=true;
num[p]=1;
for(ll i=point[p];i;i=e[i].nex)
if(!vis[e[i].to])
{
fa[e[i].to]=p;
deep[e[i].to]=deep[p]+1;
dfs1(e[i].to);
num[p]+=num[e[i].to];
if(num[e[i].to]>num[son[p]])
son[p]=e[i].to;
}
}
inline void dfs2(ll p,ll t)
{
vis[p]=true;
top[p]=t;
leaf[++order]=p;
pos[p]=order;
if(son[p]&&!vis[son[p]])
dfs2(son[p],t);
for(ll i=point[p];i;i=e[i].nex)
if(!vis[e[i].to]&&e[i].to!=son[p])
dfs2(e[i].to,e[i].to);
}
void link_cut_tree()
{
memset(fa,0,sizeof(fa));
memset(vis,false,sizeof(vis));
dfs1(1);
memset(vis,false,sizeof(vis));
dfs2(1,1);
}
struct tree
{
ll l,r,love,lazy;
}a[30010<<2];
void build(ll x,ll y,ll i)
{
a[i].l=x,a[i].r=y;
if(x==y)
{
a[i].love=tmp_love[leaf[x]];
return ;
}
ll mid=(x+y)>>1;
build(x,mid,i<<1);
build(mid+1,y,i<<1|1);
a[i].love=max(a[i<<1].love,a[i<<1|1].love);
}
inline void pushdown(ll i)
{
if(a[i].lazy&&i<(n<<1))
{
a[i<<1].lazy+=a[i].lazy;
a[i<<1|1].lazy+=a[i].lazy;
a[i<<1].love+=a[i].lazy;
a[i<<1|1].love+=a[i].lazy;
a[i].lazy=0;
}
}
void update(ll x,ll y,ll mark,ll i)
{
if(a[i].l>y||a[i].r<x) return ;
pushdown(i);
if(x<=a[i].l&&a[i].r<=y)
{
a[i].lazy+=mark;
a[i].love+=mark;
return ;
}
ll mid=(x+y)>>1;
update(x,mid,mark,i<<1);
update(mid+1,y,mark,i<<1|1);
a[i].love=max(a[i<<1].love,a[i<<1|1].love);
}
inline ll query(ll x,ll y,ll i)
{
if(a[i].l>y||a[i].r<x) return 0;
if(x<=a[i].l&&a[i].r<=y)
return a[i].love;
pushdown(i);
ll mid=(x+y)>>1;
return max(query(x,mid,i<<1),query(mid+1,y,i<<1|1));
}
int main()
{
ll i,sum=0;
n=read(),m=read(),t=read();
for(i=1;i<=n;i++)
tmp_love[i]=read();
for(i=1;i<=m;i++)
{
tmp_e[i].fr=read();
tmp_e[i].to=read();
tmp_e[i].l=read();
}
kruskal();
link_cut_tree();
order=0;
build(1,n,1);
while(t--)
{
ll start,end,ans=-INT_MAX,change;
start=read();end=read();change=read();
while(top[start]!=top[end])
{
if(deep[top[start]]>deep[top[end]])
{
update(pos[top[start]],pos[start],change,1);
ans=max(ans,query(pos[top[start]],pos[start],1));
start=fa[top[start]];
}
else
{
update(pos[top[end]],pos[end],change,1);
ans=max(ans,query(pos[top[end]],pos[end],1));
end=fa[top[end]];
}
}
if(deep[start]>deep[end])
{
update(pos[end],pos[start],change,1);
ans=max(ans,query(pos[end],pos[start],1));
}
else
{
update(pos[start],pos[end],change,1);
ans=max(ans,query(pos[start],pos[end],1));
}
sum=(sum+ans)%mod;
}
cout<<sum<<endl;
cout<<query(1,n,1);
}