#include<bits/stdc++.h>
#define int long long
#define il inline
#define hor(i,l,r) for(int i=l;i<=r;i++)
#define lor(i,l,r) for(int i=l;i>=r;i--)
#define pb push_back
using namespace std;
template<typename T> inline void rd(T &x){
x=0;char c=getchar();bool flag=false;
while(!isdigit(c)){if(c=='-')flag=true;c=getchar();}
while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
if(flag)x=-x;
}
template<typename T> inline void wr(T x){
short st[30],tp=0;
if(x<0) putchar('-'),x=-x;
do st[++tp]=x%10,x/=10; while(x);
while(tp) putchar('0'|st[tp--]);
}
#define pk putchar(' ')
#define ed puts("")
#define ls(x) x<<1
#define rs(x) x<<1|1
const int maxn=1e5+10,inf=LONG_LONG_MAX;
int aa[maxn],head[maxn],tot,dep[maxn],top[maxn],fa[maxn],size[maxn],dfn[maxn],son[maxn],cnt,c[maxn];
struct sgt{int lsum,rsum,sum,ans,l,r,tag;}t[maxn*8];
struct edge{int nxt,to;}e[2*maxn];
void bl(){
freopen("in.txt","r",stdin);
freopen("正解.txt","w",stdout);
}
il void add(int u,int v){
e[++tot].to=v;
e[tot].nxt=head[u];
head[u]=tot;
}
il void dfs1(int x,int f){
fa[x]=f;size[x]=1;
dep[x]=dep[f]+1;
for(int i=head[x];i;i=e[i].nxt){
int v=e[i].to;
if(v==f) continue;
dfs1(v,x);
size[x]+=size[v];
if(size[v]>size[son[x]]) son[x]=v;
}
}
void dfs2(int x,int tp){
dfn[x]=++cnt;c[cnt]=aa[x];top[x]=tp;
if(!son[x]) return;
dfs2(son[x],tp);
for(int i=head[x];i;i=e[i].nxt){
int v=e[i].to;
if(v==fa[x]||v==son[x]) continue;
dfs2(v,v);
}
}
il void merge(sgt &rts,sgt lt,sgt rt){
rts.sum=lt.sum+rt.sum;
rts.lsum=max(lt.lsum,lt.sum+rt.lsum);
rts.rsum=max(rt.rsum,rt.sum+lt.rsum);
rts.ans=max(max(lt.ans,rt.ans),lt.rsum+rt.lsum);
}
il void cv(int p,int num){
t[p].sum=(t[p].r-t[p].l+1)*num;
if(num>=0) t[p].lsum=t[p].rsum=t[p].ans=t[p].sum;
else t[p].lsum=t[p].rsum=t[p].ans=0;
t[p].tag=num;
}
il void push_down(int p){
if(t[p].tag!=inf){
cv(ls(p),t[p].tag);cv(rs(p),t[p].tag);
t[p].tag=inf;
}
}
il void build(int p,int l,int r){
t[p].l=l;t[p].r=r;
t[p].tag=inf;
if(l==r){
t[p].sum=c[l];
t[p].ans=t[p].lsum=t[p].rsum=max(c[l],0*1ll);
return;
}
int mid=(l+r)>>1;
build(ls(p),l,mid);
build(rs(p),mid+1,r);
merge(t[p],t[ls(p)],t[rs(p)]);
}
il void change(int p,int l,int r,int num){
if(l<=t[p].l&&t[p].r<=r){cv(p,num);return;}
push_down(p);
int mid=(t[p].l+t[p].r)>>1;
if(l<=mid) change(ls(p),l,r,num);
if(r>mid) change(rs(p),l,r,num);
merge(t[p],t[ls(p)],t[rs(p)]);
}
il sgt query(int p,int l,int r){
if(t[p].l>=l&&t[p].r<=r) return t[p];
push_down(p);
int mid=(t[p].l+t[p].r)>>1;
sgt L={},R={},_={};
if(l<=mid) L=query(ls(p),l,r);
if(r>mid) R=query(rs(p),l,r);
merge(_,L,R);
return _;
}
il sgt edge_query(int x,int y){
sgt ans_x={},ans_y={};
while(top[x]!=top[y]){
if(dep[top[x]<dep[top[y]]]) swap(x,y),swap(ans_x,ans_y);
merge(ans_x,query(1,dfn[top[x]],dfn[x]),ans_x);
x=fa[top[x]];
}
if(dep[x]>dep[y]) swap(x,y),swap(ans_x,ans_y);
sgt res=query(1,dfn[x],dfn[y]);
swap(ans_x.lsum,ans_x.rsum);
merge(ans_x,ans_x,res);
merge(ans_y,ans_x,ans_y);
return ans_y;
}
il void edge_change(int x,int y,int z){
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
change(1,dfn[top[x]],dfn[x],z);x=fa[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
change(1,dfn[x],dfn[y],z);
}
signed main(){
int n,m,opt,a,b,c;
rd(n);
hor(i,1,n) rd(aa[i]);
hor(i,1,n-1){
rd(a),rd(b);
add(a,b);add(b,a);
}
dfs1(1,0);
dfs2(1,1);
build(1,1,n);
rd(m);
while(m--){
rd(opt),rd(a),rd(b);
if(opt==1) wr(edge_query(a,b).ans),ed;
else rd(c),edge_change(a,b,c);
}
}