#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
int read()
{
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*10+ch-‘0‘; ch=getchar();}
return x*f;
}
#define MAXN 500010
int N,Q,val[MAXN*3],fa[MAXN*3],V[MAXN];
struct EdgeNode{int next,to;}edge[MAXN<<1];
int head[MAXN],cnt=1;
void AddEdge(int u,int v) {cnt++; edge[cnt].next=head[u]; head[u]=cnt; edge[cnt].to=v;}
void InsertEdge(int u,int v) {fa[v]=u; if (v>N) return; AddEdge(u,v); AddEdge(v,u);}
int size[MAXN],deep[MAXN],pl[MAXN],dfn,pr[MAXN],pre[MAXN],top[MAXN],son[MAXN];
namespace SegmentTree
{
//len[1]left[1]表示连续val=1,len[2]left[2]表示连续val=2
struct SegmentTreeNode{int l,r,size,val,tag,len[3];}tree[MAXN<<2];
#define ls now<<1
#define rs now<<1|1
inline void Merge(SegmentTreeNode &rt,SegmentTreeNode lson,SegmentTreeNode rson)
{
for (int i=1; i<=2; i++)
if (rson.len[i]==rson.size) rt.len[i]=lson.len[i]+rson.len[i];
else rt.len[i]=rson.len[i];
}
inline void Update(int now) {Merge(tree[now],tree[ls],tree[rs]);}
inline void cover(int now,int D)
{
tree[now].val=D; tree[now].tag=D; tree[now].len[1]=tree[now].len[2]=0;
if (D==1) tree[now].len[1]=tree[now].size;
if (D==2) tree[now].len[2]=tree[now].size;
}
inline void PushDown(int now)
{
if (tree[now].l==tree[now].r || tree[now].tag==-1) return;
int delta=tree[now].tag;
cover(ls,delta); cover(rs,delta); tree[now].tag=-1;
}
inline void BuildTree(int now,int l,int r)
{
tree[now].l=l; tree[now].r=r; tree[now].size=r-l+1; tree[now].tag=-1;
tree[now].len[1]=tree[now].len[2]=0;
if (l==r)
{
tree[now].val=V[l];
if (tree[now].val==1) tree[now].len[1]=1;
if (tree[now].val==2) tree[now].len[2]=1;
return;
}
int mid=(l+r)>>1;
BuildTree(ls,l,mid); BuildTree(rs,mid+1,r);
Update(now);
}
inline void Cover(int now,int L,int R,int D)
{
int l=tree[now].l,r=tree[now].r;
PushDown(now);
if (L<=l && R>=r) {cover(now,D); return;}
int mid=(l+r)>>1;
if (L<=mid) Cover(ls,L,R,D);
if (R>mid) Cover(rs,L,R,D);
Update(now);
}
inline SegmentTreeNode Query(int now,int L,int R)
{
SegmentTreeNode rl,rr,re; bool fl=0,fr=0;
int l=tree[now].l,r=tree[now].r;
PushDown(now);
if (L<=l && R>=r) return tree[now];
int mid=(l+r)>>1;
if (L<=mid) fl=1,rl=Query(ls,L,R);
if (R>mid) fr=1,rr=Query(rs,L,R);
if (fl && !fr) return rl;
if (!fl && fr) return rr;
if (fl && fr) return Merge(re,rl,rr),re;
}
}
using namespace SegmentTree;
inline void DFS_1(int now)
{
size[now]=1;
for (int i=head[now]; i; i=edge[i].next)
if (edge[i].to!=fa[now])
{
deep[edge[i].to]=deep[now]+1;
DFS_1(edge[i].to);
size[now]+=size[edge[i].to];
if (size[son[now]]<size[edge[i].to]) son[now]=edge[i].to;
}
}
inline void DFS_2(int now,int chain)
{
pl[now]=++dfn; pre[dfn]=now; top[now]=chain;
if (son[now]) DFS_2(son[now],chain);
for (int i=head[now]; i; i=edge[i].next)
if (edge[i].to!=fa[now] && edge[i].to!=son[now])
DFS_2(edge[i].to,edge[i].to);
pr[now]=dfn;
}
void DFS(int now)
{
for (int i=head[now]; i; i=edge[i].next)
if (edge[i].to!=fa[now])
DFS(edge[i].to),val[now]+=val[edge[i].to]>=2? 1:0;
}
void Solve(int x,int y)
{
int L,R,len,t,last,now; bool f,flag=0;
if (val[x]==1) f=1; else f=0; val[x]^=1; last=val[fa[x]]; val[fa[x]]+=f? -1:1; now=val[fa[x]];
t=x=fa[x];
if (now==0 || now==3) {SegmentTree::Cover(1,t,t,now); printf("%d\n",SegmentTree::Query(1,1,1).val>=2? 1:0); return;}
if (now==1 && last==0 || now==2 && last==3) {SegmentTree::Cover(1,t,t,now); printf("%d\n",SegmentTree::Query(1,1,1).val>=2? 1:0); return;}
if (now==1 && last==2) f=1; else f=0;
while (top[x]!=top[y])
{
// printf("Now(%d , %d)\n",x,y);
if (deep[top[x]]<deep[top[y]]) swap(x,y);
L=top[x],R=x; SegmentTreeNode t=Query(1,L,R);
if (f) len=t.len[2]; else len=t.len[1];
if (len==R-L+1) SegmentTree::Cover(1,L,R,f? 1:2);
else {L=L-len+1,SegmentTree::Cover(1,L,R,f? 1:2); flag=1; break;}
x=fa[top[x]];
}
if (!flag)
{
if (deep[x]>deep[y]) swap(x,y);
L=x,R=y; SegmentTreeNode t=Query(1,L,R);
if (f) len=t.len[2]; else len=t.len[1];
if (len==R-L+1) SegmentTree::Cover(1,L,R,f? 1:2); else L=L-len+1,SegmentTree::Cover(1,L,R,f? 1:2);
}
// puts("===========================================");
// for (int i=1; i<=5; i++) printf("%d %d %d %d %d %d %d\n",i,tree[i].l,tree[i].r,tree[i].size,tree[i].val,tree[i].len[1],tree[i].len[2]);
t=fa[pre[L]]; if (t) SegmentTree::Cover(1,t,t,f? val[t]-1:val[t]+1); val[t]+=f? -1:1;
printf("%d\n",SegmentTree::Query(1,1,1).val>=2? 1:0);
}
int main()
{
N=read();
for (int x,y,z,i=1; i<=N; i++)
x=read(),y=read(),z=read(),InsertEdge(i,x),InsertEdge(i,y),InsertEdge(i,z);
for (int i=1; i<=2*N+1; i++) val[N+i]=read(),val[fa[N+i]]+=val[N+i];
Q=read();
DFS(1);
DFS_1(1); DFS_2(1,1);
for (int i=1; i<=N; i++) V[pl[i]]=val[i];
SegmentTree::BuildTree(1,1,N);
while (Q--) {int pos=read(); Solve(pos,1);}
return 0;
}