#include<bits/stdc++.h>
using namespace std;
template <typename T>inline void read(T &x){
x=0;char c=getchar();bool f=0;
for(;c<'0'||c>'9';c=getchar()) f|=(c=='-');
for(;c>='0'&&c<='9';c=getchar())
x=(x<<1)+(x<<3)+(c^48);
x=(f?-x:x);
}
const int N = 2e5+7;
typedef long long LL;
#define PII pair<LL,int>
#define mk(x,y) make_pair(x,y)
#define X(x) x.first
#define Y(x) x.second
struct node
{
PII val;
LL sum,w,mn;
int l,r,key,siz;
#define siz(x) tr[x].siz
#define l(x) tr[x].l
#define r(x) tr[x].r
#define key(x) tr[x].key
#define sum(x) tr[x].sum
#define w(x) tr[x].w
#define mn(x) tr[x].mn
#define val(x) tr[x].val
}tr[N];
int namestk[N],top=0,idx=0;
int getname()
{
if(top)return namestk[top--];
return ++idx;
}
void pushup(int k)
{
sum(k)=sum(l(k))+sum(r(k))+w(k);
siz(k)=siz(l(k))+siz(r(k))+1;
mn(k)=val(k).first+sum(l(k));
if(l(k))mn(k)=min(mn(k),mn(l(k)));
if(r(k))mn(k)=min(mn(k),sum(l(k))+w(k)+mn(r(k)));
}
int Merge(int x,int y)
{
if(!x||!y)return x+y;
if(key(x)<key(y))
{
r(x)=Merge(r(x),y);
pushup(x);
return x;
}
l(y)=Merge(x,l(y));
pushup(y);
return y;
}
void Split(int k,PII v,int &x,int &y)
{
if(!k)
{
x=y=0;
return;
}
if(val(k)>=v)
{
x=k;
Split(r(k),v,r(k),y);
}
else
{
y=k;
Split(l(k),v,x,l(k));
}
pushup(k);
}
LL Locate(int k,LL lim,LL pre,PII &H)
{
if(!k)return 0;
if(l(k)&&lim>mn(l(k))+pre)return Locate(l(k),lim,pre);
if(lim>val(k).first+sum(l(k))+pre) return sum(l(k));
return Locate(r(k),lim,pre+sum(l(k))+w(k))+sum(l(k))+w(k);
}
int n,m,fa[N];
LL a[N],b[N];
LL dp[N];
vector<int> G[N];
int rot[N];
void ins(int x,int y)
{
int u=getname();
siz(u)=1;
l(u)=r(u)=0;
sum(u)=w(u)=b[y];
val(u)=mk(dp[y],y);
mn(u)=dp[y];
key(u)=rand();
int A,B;
Split(rot[x],val(u),A,B);
rot[x]=Merge(Merge(A,u),B);
}
void del(int x,int y)
{
PII v=mk(dp[y],y);
int A,B,C;
Split(rot[x],v,A,B);
v.second++;
Split(A,v,A,C);
namestk[++top]=C;
rot[x]=Merge(A,B);
}
LL S[N];
void dfs(int x)
{
if(G[x].empty())
{
dp[x]=a[x];
return;
}
for(int y:G[x])
{
dfs(y);
ins(x,y);
}
LL val=Locate(rot[x],a[x]+S[x],0);
dp[x]=a[x]+S[x]-val;
}
int siz[N],son[N],top[N],dfn[N],seq[N],bot[N],tot=0;
void dfs(int x)
{
siz[x]=1;son[x]=0;
for(int y:G[x])
{
dfs(y);
siz[x]+=siz[y];
if(siz[y]>siz[son[x]])son[x]=y;
}
}
void dfs2(int x,int topth)
{
top[x]=topth;
bot[topth]=x;
seq[dfn[x]=++tot]=x;
if(!son[x])return;
dfs2(son[x],topth);
for(int y:G[x])if(y^son[x])dfs2(y,x);
}
struct Info
{
PII lim,A,B;
}tree[N*4];
inline Info operator +(Info x,Info y)
{
PII A,B;
if(y.A<x.lim) A=x.A;else A=x.B;
if(y.B<x.lim) B=x.A;else B=x.B;
return (Info){y.lim,A,B};
}
Info query(int k,int l,int r,int L,int R)
{
if(L<=l&&r<=R)return tree[k];
int mid=(l+r)>>1;
if(R<=mid)return query(k<<1,l,mid,L,R);
if(L>mid)return query(k<<1|1,mid+1,r,L,R);
return query(k<<1,l,mid,L,mid)+query(k<<1|1,mid+1,r,L,R);
}
void upd(int k,int l,int r,int x,PII v)
{
if(l==r)
{
tree[k]=v;
return;
}
int mid=(l+r)>>1;
if(x<=mid)upd(k<<1,l,mid,x,v);
else upd(k<<1|1,mid+1,r,x,v);
tree[k]=tree[k<<1]+tree[k<<1|1];
}
void maintain(int x)
{
if(!son[x])
{
upd(1,1,n,dfn[x],(Info){mk(0,0),mk(dp[x],x),mk(dp[x],x)});
return;
}
LL v=b[son[x]];
LL
}
int main()
{
read(n);read(m);
for(int i=2;i<=n;i++)read(fa[i]),G[fa[i]].push_back(i);
for(int i=1;i<=n;i++)read(a[i]);
for(int i=1;i<=n;i++)read(b[i]),S[fa[i]]+=b[i];
dfs(1);dfs1
while(m--)
{
int op,x,A,B;
read(op);
if(op==1)
{
read(x);read(A);read(B);
S[fa[x]]-=b[x];
a[x]=A;b[x]=B;
S[fa[x]]+=b[x];
while(x)
{
if(fa[x])del(fa[x],x);
LL val=Locate(rot[x],a[x]+S[x],0);
dp[x]=a[x]+S[x]-val;
if(fa[x])ins(fa[x],x);
x=fa[x];
}
}
else
{
read(A);read(B);
if(mk(dp[A],A)>mk(dp[B],B))printf("0\n");
else printf("1\n");
}
}
return 0;
}