#include <cstdio>
#include <cmath>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
#include <map>
#include <unordered_map>
#include <set>
#include <bitset>
#include <stack>
#include <tuple>
#include <bitset>
#define ll long long
#define ull unsigned long long
#define ld long double
#define fp(a,b,c) for(ll a=b;a<=c;a++)
#define fd(a,b,c) for(ll a=b;a>=c;a--)
#define pii pair<int,int>
#define pll pair<ll,ll>
#define inf 0x3f3f3f3f
#define base 127
#define mod 1000000007
#define eb emplace_back
#define pb pop_back
#define y1 y114
#define y0 y514
#define x1 x114
#define x0 x514
#define fill(x,y) memset(x,y,sizeof(x))
#define mpr make_pair
#define met(x,t) memset(x,t,sizeof(x))
#define l(x) son[x][0]
#define r(x) son[x][1]
#define int ll
using namespace std;
inline int rd(){
int x = 0, f = 1;char ch = getchar();
while(ch < '0' || ch > '9'){if(ch == '-')f = -1;ch = getchar();}
while(ch >= '0' && ch <= '9')x = (x<<1) + (x<<3) + (ch^48),ch = getchar();
return x * f;}
const int maxN=2*1e5+10;
int n,q,idx,root;
int dfn[maxN],id[maxN],top[maxN],mson[maxN],siz[maxN],dep[maxN],fa[maxN];
int a[maxN];
vector<int> g[maxN];
struct node {
int lmax,rmax,lmin,rmin;
int sum,ans,siz;
node operator + (node x)const{
node z;
z.sum=sum+x.sum;
z.lmax=max(lmax,x.lmax+sum);
z.rmax=max(rmax+x.sum,x.rmax);
z.lmin=min(lmin,x.lmin+sum);
z.rmin=min(rmin+x.sum,x.rmin);
z.ans=max(rmax+x.lmax,max(ans,x.ans));
z.siz=siz+x.siz;
return z;
}
node operator + (int x)const{
node z;
z.siz=siz,z.sum=x*z.siz;
z.rmax=z.lmax=max(z.siz*x,0ll);
z.rmin=z.lmin=min(z.siz*x,0ll);
z.ans=max(0ll,z.siz*x);
return z;
}
void cs(){
siz=lmax=rmax=lmin=rmin=ans=sum=0;
}
};
struct node2{
node data[maxN<<2];
int son[maxN<<2][2],tag[maxN<<2],idx;
void pushdown(int now){
if(tag[now]!=inf){
data[l(now)]=data[l(now)]+tag[now];
data[r(now)]=data[r(now)]+tag[now];
tag[l(now)]=tag[now];
tag[r(now)]=tag[now];
tag[now]=inf;
}
}
void build(int &now,int l,int r){
now=++idx;
tag[now]=inf;
if(l==r){
data[now].cs();
data[now].siz=1;
data[now]=data[now]+a[id[l]];
return ;
}
int mid=(l+r)>>1;
build(l(now),l,mid);
build(r(now),mid+1,r);
data[now]=data[l(now)]+data[r(now)];
}
void modify(int now,int l,int r,int ql,int qr,int x){
if(ql<=l&&r<=qr){
tag[now]=x;
data[now]=data[now]+x;
return ;
}
int mid=(l+r)>>1;
pushdown(now);
if(ql<=mid) modify(l(now),l,mid,ql,qr,x);
if(qr>mid) modify(r(now),mid+1,r,ql,qr,x);
data[now]=data[l(now)]+data[r(now)];
}
node query(int now,int l,int r,int ql,int qr){
if(ql<=l&&r<=qr) return data[now];
int mid=(l+r)>>1;
pushdown(now);
if(qr<=mid) return query(l(now),l,mid,ql,qr);
else if(ql>mid) return query(r(now),mid+1,r,ql,qr);
else return query(l(now),l,mid,ql,qr)+query(r(now),mid+1,r,ql,qr);
}
}seg;
void dfs(int now,int f){
fa[now]=f,siz[now]=1,dep[now]=dep[f]+1;
for(int x:g[now]){
if(x==f) continue ;
dfs(x,now);
siz[now]+=siz[x];
mson[now]=(siz[mson[now]]>siz[x])?mson[now]:x;
}
}
void redfs(int now,int tp){
top[now]=tp,dfn[now]=++idx,id[idx]=now;
if(mson[now]) redfs(mson[now],tp);
for(int x:g[now])
if(x!=mson[now]&&x!=fa[now]) redfs(x,x);
}
node query(int u,int v){
node x,y;
x.cs(),y.cs();
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]])
y=seg.query(1,1,n,dfn[top[v]],dfn[v])+y,v=fa[top[v]];
else x=x+seg.query(1,1,n,dfn[top[u]],dfn[u]),u=fa[top[u]];
}
if(dep[u]<dep[v]) x=x+seg.query(1,1,n,dfn[u],dfn[v]);
else y=seg.query(1,1,n,dfn[v],dfn[u])+y;
return x+y;
}
void modify(int u,int v,int x){
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]]) swap(u,v);
seg.modify(1,1,n,dfn[top[u]],dfn[u],x),u=fa[top[u]];
}
if(dep[u]<dep[v]) swap(u,v);
seg.modify(1,1,n,dfn[v],dfn[u],x);
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
n=rd();
fp(i,1,n) a[i]=rd();
fp(i,1,n-1){
int u=rd(),v=rd();
g[u].push_back(v),g[v].push_back(u);
}
dfs(1,0),redfs(1,1);
seg.build(root,1,n);
q=rd();
while(q--){
int op=rd(),u=rd(),v=rd(),x;
if(op==1) cout << query(u,v).ans << endl;
else x=rd(),modify(u,v,x);
}
return 0;
}