#include <bits/stdc++.h>
using namespace std;
#define il inline
const int N=1e5+5,inf=1e9+1;
int n,m,a[N],w[N];
int dep[N],siz[N],h[N],top[N],id[N],son[N],fa[N];
struct edge
{
int v,nxt;
}e[N<<1];
struct node
{
int lmx,mx,rmx,sum,lz;
}t[N<<2];
int head[N],et=0,idx=0;
il void add(int u,int v)
{
e[++et].v=v;
e[et].nxt=head[u];
head[u]=et;
}
namespace init
{
il void dfs1(int u,int f)
{
siz[u]=1;dep[u]=dep[f]+1;fa[u]=f;
int hs=-1;
for(int i=head[u];i;i=e[i].nxt)
{
int v=e[i].v;
if(v==f)continue;
dfs1(v,u);
siz[u]+=siz[v];
if(hs<siz[v])hs=siz[v],son[u]=v;
}
}
il void dfs2(int u,int h)
{
id[u]=++idx;a[idx]=w[u];top[u]=h;
if(!son[u])return;
dfs2(son[u],h);
for(int i=head[u];i;i=e[i].nxt)
{
int v=e[i].v;
if(v==fa[u]||v==son[u])continue;
dfs2(v,v);
}
}
}
namespace seg
{
#define ls (p<<1)
#define rs ((p<<1)|1)
#define mid ((l+r)>>1)
il void pushup(int p)
{
t[p].sum=t[ls].sum+t[rs].sum;
t[p].lmx=max(t[ls].lmx,t[ls].sum+t[rs].lmx);
t[p].rmx=max(t[rs].rmx,t[rs].sum+t[ls].rmx);
t[p].mx=max(max(t[ls].mx,t[rs].mx),t[ls].rmx+t[rs].lmx);
return;
}
il void pushdown(int p,int l,int r)
{
if(!t[p].lz)return;
t[ls].lmx=t[ls].rmx=t[ls].mx=t[p].lz;
t[ls].sum=(mid-l+1)*t[p].lz;
t[rs].lmx=t[rs].rmx=t[rs].mx=t[p].lz;
t[rs].sum=(r-mid)*t[p].lz;
t[ls].lz=t[rs].lz=t[p].lz;
t[p].lz=0;
return;
}
il node get(node a,node b)
{
if(a.mx==-inf)return b;
if(b.mx==-inf)return a;
node t;
t.sum=a.sum+b.sum;
t.lmx=max(a.lmx,a.sum+b.lmx);
t.rmx=max(b.rmx,b.sum+a.rmx);
t.mx=max(max(a.mx,b.mx),a.rmx+b.lmx);
return t;
}
il void build(int p,int l,int r)
{
if(l==r)
{
t[p].mx=t[p].lmx=t[p].sum=t[p].rmx=a[l];
return;
}
build(ls,l,mid);
build(rs,mid+1,r);
pushup(p);
}
il void upd(int p,int l,int r,int ql,int qr,int c)
{
if(r<ql||qr<l)return;
if(ql<=l&&r<=qr)
{
t[p].lmx=t[p].rmx=t[p].mx=c;
t[p].sum=c*(r-l+1);
t[p].lz=c;
return;
}
pushdown(p,l,r);
upd(ls,l,mid,ql,qr,c);
upd(rs,mid+1,r,ql,qr,c);
pushup(p);
}
il node query(int p,int l,int r,int ql,int qr)
{
if(r<ql||qr<l)return (node){-inf,-inf,-inf,-inf,0};
if(ql<=l&&r<=qr)return t[p];
pushdown(p,l,r);
return get(query(ls,l,mid,ql,qr),query(rs,mid+1,r,ql,qr));
}
}
vector<node>q[3];
il void ask(int a,int b)
{
while(!q[1].empty())q[1].pop_back();
while(!q[2].empty())q[2].pop_back();
node ans,ans1,ans2,tt;
ans1=ans2=(node){-inf,-inf,-inf,-inf,0};int num1=1,num2=2;
while(top[a]!=top[b])
{
if(dep[top[a]]<dep[top[b]]){swap(a,b);swap(num1,num2);}
tt=seg::query(1,1,n,id[top[a]],id[a]);
q[num1].push_back(tt);
a=fa[top[a]];
}
if(dep[a]>dep[b]){swap(a,b);swap(num1,num2);}
tt=seg::query(1,1,n,id[a],id[b]);
q[num2].push_back(tt);
for(int i=0;i<q[1].size();i++)
{
ans1=seg::get(ans1,q[1][i]);
}
for(int i=0;i<q[2].size();i++)
{
ans2=seg::get(ans2,q[2][i]);
}
ans=seg::get(ans1,ans2);
cout<<max(0,max(max(ans.lmx,ans.rmx),ans.mx))<<'\n';
}
il void change(int a,int b,int c)
{
while(top[a]!=top[b])
{
if(dep[top[a]]<dep[top[b]])swap(a,b);
seg::upd(1,1,n,id[top[a]],id[a],c);
a=fa[top[a]];
}
if(dep[a]>dep[b])swap(a,b);
seg::upd(1,1,n,id[a],id[b],c);
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>w[i];
}
for(int i=1,v,u;i<n;i++)
{
cin>>u>>v;
add(u,v);add(v,u);
}
cin>>m;
int op,a,b,c;
init::dfs1(1,0);
init::dfs2(1,1);
seg::build(1,1,n);
while(m--)
{
cin>>op>>a>>b;
if(op==1) ask(a,b);
else {cin>>c;change(a,b,c);}
}
return 0;
}