#include<bits/stdc++.h>
#define LL long long
const int maxn=1e6;
inline const void read(LL &a)
{
char c=getchar();LL b=1;a=0;
while(c<'0'||c>'9'){if(c=='-')b=-1;c=getchar();}
while(c>='0'&&c<='9')
{
a=(a<<1)+(a<<3)+c-'0';
c=getchar();
}
a*=b;
}
inline const void write(LL a)
{
if(a<0){putchar('-');a=-a;}
if(a>9)write(a/10);
putchar(a%10+'0');
}
inline const LL min(LL a,LL b)
{
if(a<b)return a;
return b;
}
inline const LL max(LL a,LL b)
{
if(a>b)return a;
return b;
}
LL n,m,t,d=0;
LL from[maxn],to[maxn],next[maxn],point[maxn];
inline const void add(LL a,LL b)
{
next[++d]=point[a];
to[d]=b;
point[a]=d;
}
struct side
{
LL from,to,next,height;
}s[maxn];
inline const bool comp(const side&a,const side&b)
{
if(a.height<b.height)return true;
return false;
}
struct LEAST_TREE
{
LL belong[maxn];
inline const LL check(LL a)
{
if(a==belong[a])return a;
return belong[a]=check(belong[a]);
}
void solve()
{
for(LL i=1;i<=n;i++)belong[i]=i;
memset(point,false,sizeof(point));
for(LL i=1;i<=m;i++){read(s[i].from);read(s[i].to);read(s[i].height);}
std::sort(s+1,s+1+m,comp);
LL k=n-1,t=1;
while(k)
{
if(check(s[t].from)==check(s[t].to)){t++;continue;}
belong[check(s[t].from)]=s[t].to;
add(s[t].from,s[t].to);
add(s[t].to,s[t].from);
k--;t++;
}
}
}least_tree;
LL father[maxn],top[maxn],deep[maxn];
LL leaf[maxn],order=0,pos[maxn],init[maxn];
struct LINK_CUT_TREE
{
LL son[maxn],num[maxn];
bool vis[maxn];
inline const void dfs1(LL p)
{
vis[p]=true;
LL side=point[p];
num[p]=1;
while(side)
{
if(!vis[to[side]])
{
father[to[side]]=p;
deep[to[side]]=deep[p]+1;
dfs1(to[side]);
num[p]+=num[to[side]];
if(num[to[side]]>num[son[p]])son[p]=to[side];
}
side=next[side];
}
}
inline const 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);
LL side=point[p];
while(side)
{
if(!vis[to[side]]&&to[side]!=son[p])dfs2(to[side],to[side]);
side=next[side];
}
}
void solve()
{
memset(father,0,sizeof(father));
memset(son,0,sizeof(son));
memset(deep,0,sizeof(deep));
memset(vis,false,sizeof(vis));
dfs1(1);
memset(vis,false,sizeof(vis));
dfs2(1,1);
}
}link_cut_tree;
struct SEGMENT_TREE
{
LL love[maxn<<2],col[maxn<<2];
inline const void update(LL p)
{
love[p]=max(love[p<<1],love[p<<1|1]);
}
inline const void build(LL p,LL l,LL r)
{
if(l==r){love[p]=init[leaf[++order]];return ;}
LL mid=(l+r)>>1;
build(p<<1,l,mid);
build(p<<1|1,mid+1,r);
update(p);
}
inline const void push_col(LL p)
{
if(col[p])
{
col[p<<1]+=col[p];col[p<<1|1]+=col[p];
love[p<<1]+=col[p];love[p<<1|1]+=col[p];
col[p]=0;
}
}
inline const LL query(LL p,LL l,LL r,LL ll,LL rr)
{
if(l>=ll&&r<=rr)return love[p];
push_col(p);
LL mid=(l+r)>>1,ans=-INT_MAX;
if(mid>=ll)ans=max(ans,query(p<<1,l,mid,ll,rr));
if(mid+1<=rr)ans=max(ans,query(p<<1|1,mid+1,r,ll,rr));
return ans;
}
inline const void modify(LL p,LL l,LL r,LL ll,LL rr,LL mark)
{
if(l>=ll&&r<=rr)
{
col[p]+=mark;love[p]+=mark;
return ;
}
push_col(p);
LL mid=(l+r)>>1;
if(mid>=ll)modify(p<<1,l,mid,ll,rr,mark);
if(mid+1<=rr)modify(p<<1|1,mid+1,r,ll,rr,mark);
update(p);
}
void solve()
{
order=0;
build(1,1,n);
memset(col,0,sizeof(col));
while(t)
{
t--;
LL start,end,ans=-INT_MAX,change;
read(start);read(end);read(change);
while(top[start]!=top[end])
{
if(deep[top[start]]>deep[top[end]])
{
modify(1,1,n,pos[top[start]],pos[start],change);
ans=max(ans,query(1,1,n,pos[top[start]],pos[start]));
start=father[top[start]];
}
else
{
modify(1,1,n,pos[top[end]],pos[end],change);
ans=max(ans,query(1,1,n,pos[top[end]],pos[end]));
end=father[top[end]];
}
}
if(deep[start]>deep[end])
{
modify(1,1,n,pos[end],pos[start],change);
ans=max(ans,query(1,1,n,pos[end],pos[start]));
}
else
{
modify(1,1,n,pos[start],pos[end],change);
ans=max(ans,query(1,1,n,pos[start],pos[end]));
}
write(ans);putchar(' ');
}
printf("\n");
for(LL i=1;i<=n;i++){write(query(1,1,n,pos[i],pos[i]));putchar(' ');}
}
}segment_tree;
int main()
{
read(n);read(m);read(t);
for(LL i=1;i<=n;i++)read(init[i]);
least_tree.solve();
link_cut_tree.solve();
segment_tree.solve();
return 0;
}