//预处理出以这个点为起点并跳出这个块的次数和位置
//更新一个点的弹力系数可以只更新这个点以及这个块内之前的点
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<cmath>
#include<iostream>
using namespace std;
const int N=2e5+10;
struct node
{
//ahead为从该点跳的距离
int ahead;
//step为跳到下一个块的所需步数
int step;
//Next为跳到的下一个块 跳出Next为0
int Next;
//pos为跳到下一个块的位置
int pos;
}p[N];
int temp;
int block[N];
int main()
{
int n,m,op;
scanf("%d",&n);
for(int i=0; i<n; i++)
scanf("%d",&p[i].ahead);
temp=sqrt(n);
//分块
for(int i=0; i<n; i++)
block[i]=i/temp+1;
for(int i=n-1; i>=0; i--)
{
//如果在同一个块内
if(block[i+p[i].ahead]!=block[i])
{
p[i].Next=block[i+p[i].ahead];
p[i].pos=i+p[i].ahead;
p[i].step=1;
}
else
{
p[i].Next=p[i+p[i].ahead].Next;
p[i].pos=p[i+p[i].ahead].pos;
p[i].step=p[i+p[i].ahead].step+1;
}
}
scanf("%d",&m);
int x,y;
for(int cas=1; cas<=m; ++cas)
{
scanf("%d",&op);
if(op==1)
{
scanf("%d",&x);
int ans=0;
//一个块一个块的跳
while(p[x].Next!=0)
{
ans+=p[x].step;
x=p[x].pos;
}
ans+=p[x].step;
printf("%d\n",ans);
}
else if(op==2)//更新
{
scanf("%d%d",&x,&y);
p[x].ahead=y;
//更新的话,只更新在同一块内的
int l=(block[x]-1)*temp;
for(int i=x; i>=l; i--)
{
if(block[i+p[i].ahead]!=block[i])
{
p[i].Next=block[i+p[i].ahead];
p[i].pos=i+p[i].ahead;
p[i].step=1;
}
else
{
p[i].Next=p[i+p[i].ahead].Next;
p[i].pos=p[i+p[i].ahead].pos;
p[i].step=p[i+p[i].ahead].step+1;
}
}
}
}
return 0;
}