#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <iostream>
#define MAXN 201000
using namespace std;
struct tree{
int sum1,sum2,l,r;
}tr[MAXN*5];
struct que{
int id,x,y,c,t,ans1,ans2;
}q1[MAXN];
struct que2{
int id,x,d;
}q2[MAXN];
struct edge{
int first,next,to;
}a[MAXN*2];
int dep[MAXN],fa[MAXN],size[MAXN],son[MAXN],top[MAXN],pos[MAXN];
int n,q,num=0,num2=0,cnt=0,cnt2=0;
void addedge(int from,int to){
a[++num].to=to;
a[num].next=a[from].first;
a[from].first=num;
}
void dfs1(int now,int f){
fa[now]=f,size[now]=1,dep[now]=dep[f]+1;
for(int i=a[now].first;i;i=a[i].next){
int to=a[i].to;
if(to==f) continue;
dfs1(to,now);
size[now]+=size[to];
if(size[son[now]]<size[to]) son[now]=to;
}
}
void dfs2(int now,int tp){
top[now]=tp,pos[now]=++num2;
if(son[now]) dfs2(son[now],tp);
for(int i=a[now].first;i;i=a[i].next){
int to=a[i].to;
if(to==fa[now]||to==son[now]) continue;
dfs2(to,to);
}
}
bool cmp(que x,que y){if(x.t!=y.t)return x.t<y.t;else return x.id<y.id;}
bool cmp2(que2 x,que2 y){return x.id<y.id;}
bool cmp3(que x,que y){return x.id<y.id;}
int query(int xv,int L,int R,int l,int r,int hh){
if(l==L&&r==R){
if(hh==1) return tr[xv].sum1;
else return tr[xv].sum2;
}
int mid=(L+R)/2;
if(r<=mid) return query(xv*2,L,mid,l,r,hh);
else if(l>mid) return query(xv*2+1,mid+1,R,l,r,hh);
else return query(xv*2,L,mid,l,mid,hh)+query(xv*2+1,mid+1,R,mid+1,r,hh);
}
void getans(int hh){
int x=q1[hh].x,y=q1[hh].y,topx=top[x],topy=top[y],ans1=0,ans2=0;
while(topx!=topy){
if(dep[topx]<dep[topy]) swap(topx,topy),swap(x,y);
ans1+=query(1,1,num2,pos[topx],pos[x],1);
ans2+=query(1,1,num2,pos[topx],pos[x],0);
x=fa[topx];
topx=top[x];
}
if(dep[x]<dep[y]) swap(x,y);
ans1+=query(1,1,num2,pos[y],pos[x],1);
ans2+=query(1,1,num2,pos[y],pos[x],0);
q1[hh].ans1=ans1,q1[hh].ans2=ans2;
}
void change(int xv,int L,int R,int id,int hh){
if(L==R&&L==id){
if(hh==1) tr[xv].sum1=1;
else tr[xv].sum2=1;
return;
}
int mid=(L+R)/2;
if(id<=mid) change(xv*2,L,mid,id,hh);
else change(xv*2+1,mid+1,R,id,hh);
tr[xv].sum1=tr[xv*2].sum1+tr[xv*2+1].sum1;
tr[xv].sum2=tr[xv*2].sum2+tr[xv*2+1].sum2;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++){
int x;scanf("%d",&x);
addedge(i,x),addedge(x,i);
}
dfs1(1,0);dfs2(1,1);
scanf("%d",&q);
for(int i=1;i<=q;i++){
int id;scanf("%d",&id);
if(id==1){
int x,y,c;scanf("%d%d%d",&x,&y,&c);cnt++;
q1[cnt].x=x,q1[cnt].y=y,q1[cnt].c=c,q1[cnt].t=i-c,q1[cnt].id=i;
}
else{
int x;scanf("%d",&x);
q2[++cnt2].x=x;q2[cnt2].id=i;
}
}
sort(q1+1,q1+cnt+1,cmp);
sort(q2+1,q2+cnt2+1,cmp2);
int now=1;
for(int i=1;i<=n;i++) change(1,1,num2,pos[i],2);
for(int i=1;i<=cnt;i++){
while(now<=cnt2&&q2[now].id<q1[i].t){
change(1,1,num2,pos[q2[now].x],1);now++;
}
getans(i);
}
sort(q1+1,q1+cnt+1,cmp3);
for(int i=1;i<=cnt;i++){
printf("%d %d\n",q1[i].ans2,q1[i].ans1);
}
return 0;
}