rt
#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+7;
int N,QWQ,val[maxn];
struct SegmentTree{
struct node
{int ls,rs,L,R,dat,setv=-1;}dat[400005];
#define ls(p) (dat[p].ls)
#define rs(p) (dat[p].rs)
#define len(p) (dat[p].R-dat[p].L+1)
void pushup(int p)
{dat[p].dat=dat[ls(p)].dat+dat[rs(p)].dat;}
void pushdown(int p){
if(dat[p].setv!=-1){
dat[ls(p)].dat=dat[p].setv*len(ls(p));
dat[rs(p)].dat=dat[p].setv*len(rs(p));
dat[ls(p)].setv=dat[rs(p)].setv=dat[p].setv;
dat[p].setv=-1;
}
}
void build(int p,int L,int R){
dat[p].L=L;dat[p].R=R;
if(L==R){dat[p].dat=val[L];return;}
int mid=(L+R)>>1;
ls(p)=(p<<1);rs(p)=(p<<1|1);
build(ls(p),L,mid);build(rs(p),mid+1,R);
pushup(p);
}
int QueryPoint(int p,int inx){
int L=dat[p].L,R=dat[p].R;
if(L==R)return dat[p].dat;
int mid=(L+R)>>1;
if(inx<=mid)return QueryPoint(ls(p),inx);
else return QueryPoint(rs(p),inx);
}
void SetRange(int p,int ql,int qr,int xx){
int L=dat[p].L,R=dat[p].R;
if(ql<=L&&R<=qr)
{dat[p].dat=xx*len(p);dat[p].setv=xx;return;}
pushdown(p);
int mid=(L+R)>>1;
if(ql<=mid)SetRange(ls(p),ql,qr,xx);
if(mid+1<=qr)SetRange(rs(p),ql,qr,xx);
pushup(p);
}
int QueryRange(int p,int ql,int qr){
int L=dat[p].L,R=dat[p].R;
if(ql<=L&&R<=qr){return dat[p].dat;}
pushdown(p);
int mid=(L+R)>>1,ret=0;
if(ql<=mid)ret+=QueryRange(ls(p),ql,qr);
if(mid+1<=qr)ret+=QueryRange(rs(p),ql,qr);
return ret;
}
};
struct SLPF{
int dfs_clock=0;
int head[maxn],nxt[maxn],to[maxn],cnt_edge;
int Fa[maxn],dep[maxn],sz[maxn],id[maxn],Hd[maxn],Hson[maxn];
SegmentTree SegTree;
void AddEdge(int u,int v){
nxt[++cnt_edge]=head[u];to[cnt_edge]=v;head[u]=cnt_edge;
nxt[++cnt_edge]=head[v];to[cnt_edge]=u;head[v]=cnt_edge;
}
void dfs1(int u,int fa){
Fa[u]=fa;dep[u]=dep[fa]=1;sz[u]=1;
int MaxSonW=-1;
for(int i=head[u];i;i=nxt[i]){
if(to[i]==fa)continue;
dfs1(to[i],u);sz[u]+=sz[to[i]];
if(sz[to[i]]>MaxSonW)
MaxSonW=sz[to[i]],Hson[u]=to[i];
}
}
void dfs2(int u,int Top){
Hd[u]=Top;id[u]=++dfs_clock;
if(!Hson[u])return;
dfs2(Hson[u],Top);
for(int i=head[u];i;i=nxt[i]){
if(to[i]==Fa[u]||to[i]==Hson[u])continue;
dfs2(to[i],to[i]);
}
}
void init(){
scanf("%d",&N);
for(int i=2;i<=N;i++){
int a;scanf("%d",&a);
AddEdge(a+1,i);
}
dfs1(1,0);dfs2(1,1);SegTree.build(1,1,dfs_clock);
}
void SetSubTree(int u,int xx)
{SegTree.SetRange(1,u,id[u]+sz[u]-1,xx);}
int QuerySubTree(int u)
{return SegTree.QueryRange(1,id[u],id[u]+sz[u]-1);}
void SetToRoot(int u,int xx){
while(Hd[u]!=1){
SegTree.SetRange(1,id[Hd[u]],id[u],xx);
u=Fa[Hd[u]];
}
SegTree.SetRange(1,1,id[u],xx);
}
int QueryToRoot(int u){
int ret=0;
while(Hd[u]!=1){
ret+=SegTree.QueryRange(1,id[Hd[u]],id[u]);
u=Fa[Hd[u]];
}
ret+=SegTree.QueryRange(1,1,id[u]);return ret;
}
void Install(int u){SetToRoot(u,1);}
void UnInstall(int u){SetSubTree(u,0);}
void QueryInstall(int u){
if(SegTree.QueryPoint(1,id[u])==1)
{printf("0\n");return;}
int Installed=QueryToRoot(u);
printf("%d\n",dep[u]-Installed);
}
void QueryUnInstall(int u){
if(SegTree.QueryPoint(1,id[u])==0)
{printf("0\n");return;}
printf("%d\n",sz[u]-1-QuerySubTree(u));
}
void Query(){
char op[114];scanf("%s",op);
int xx;scanf("%d",&xx);xx++;
if(op[0]=='i'){
QueryInstall(xx);
Install(xx);
}else if(op[0]=='u'){
QueryUnInstall(xx);
UnInstall(xx);
}
}
}Tree;
int main(){
Tree.init();
scanf("%d",&QWQ);
while(QWQ--)Tree.Query();
return 0;
}