#include <bits/stdc++.h>
#define pb emplace_back
using namespace std;
const int N=4e5+5,B=650;
int n,q;
int a[N],id[N],idx;
bitset<N>vis;
vector<int>ts;
int las;
template<typename T>
void rd(T &x)
{
x=0;
char ch=getchar();
while(ch<'0' && ch>'9')ch=getchar();
while(ch>='0' && ch<='9')x=x*10+ch-48,ch=getchar();
}
template<typename T,typename... Args>
void rd(T &x,Args &... args)
{
rd(x),rd(args...);
}
template<typename T>
void wr(T x)
{
if(x<=9)
putchar(x+48);
else
wr(x/10),putchar(x%10+48);
}
template<typename T>
void wrln(T x)
{
wr(x),putchar('\n');
}
struct block{
int l,r,f[B],fl;
long long laz;
void reset()
{
fl=1;
for(int i=l;i<=r;i++)
{
if(id[a[i]]!=id[i])
f[i-l]=i;
else
fl=0,f[i-l]=f[a[i]-l];
}
}
void upd(int L,int R,int val)
{
for(int i=L;i<=R;i++)
a[i]=i==1?0:max(a[i]-val,1);
reset();
}
void upd(int val)
{
if(fl)laz+=val;
else upd(l,r,val);
}
}b[N/B+5];
void upd(int l,int r,int val)
{
if(id[l]==id[r])
{
b[id[l]].upd(l,r,val);
return;
}
b[id[l]].upd(l,b[id[l]].r,val);
for(int i=id[l]+1;i<id[r];i++)
b[i].upd(val);
b[id[r]].upd(b[id[r]].l,r,val);
}
void clear()
{
for(int i=0;i<ts.size();i++)
vis[ts[i]]=0;
ts.clear();
}
int lca(int x,int y)
{
while(b[id[x]].f[x-b[id[x]].l]!=b[id[y]].f[y-b[id[y]].l])
{
if(id[x]<id[y])
swap(x,y);
x=(b[id[x]].f[x-b[id[x]].l]==1)?0:max(1ll,a[b[id[x]].f[x-b[id[x]].l]]-b[id[x]].laz);
}
int tar=(b[id[x]].f[x-b[id[x]].l]==1)?0:max(1ll,a[b[id[x]].f[x-b[id[x]].l]]-b[id[x]].laz);
clear();
while(x!=tar)
{
vis[x]=1;
ts.pb(x);
x=(x==1)?0:max(1ll,a[x]-b[id[x]].laz);
}
while(y!=tar)
{
if(vis[y])
return y;
y=(y==1)?0:max(1ll,a[y]-b[id[y]].laz);
}
}
signed main()
{
rd(n,q);
for(int i=2;i<=n;i++)
rd(a[i]);
idx=(n-1)/B+1;
for(int i=1;i<=idx;i++)
{
b[i].l=(i-1)*B+1,b[i].r=min(n,i*B);
b[i].laz=b[i].fl=0;
for(int j=b[i].l;j<=b[i].r;j++)
id[j]=i;
}
vis.reset();
for(int i=1;i<=idx;i++)
b[i].reset();
while(q--)
{
int op,x,y,z;
rd(op,x,y);
x^=las,y^=las;
if(op==1)
rd(z),z^=las,upd(x,y,z);
else
wrln(las=lca(x,y));
}
return 0;
}