#include <bits/stdc++.h>
using namespace std;
int n, m;
int arr[1000005];
namespace Tree{
struct Node{
int data;
int left_node, right_node;
};
Node Heap[25000000];
int history[1000005];
int Index = 1;
int h_Index = 1;
inline int Malloc()
{
return Index++;
}
inline int h_Malloc()
{
return h_Index++;
}
void Build(int now, int l, int r)
{
if(l == r){
Heap[now].data = arr[l];
return ;
}
int mid = (l + r) /2;
Build(Heap[now].left_node = Malloc(), l, mid);
Build(Heap[now].right_node = Malloc(), mid + 1, r);
}
void _change(int now, int loc, int l, int r, int val)
{
if(l == r){
Heap[now].data = val;
return ;
}
int mid = (l + r) / 2;
int idx = Malloc();
if(loc <= mid){
Heap[idx] = Heap[Heap[now].left_node];
_change(Heap[now].left_node = idx, loc, 1, mid, val);
}
else{
Heap[idx] = Heap[Heap[now].right_node];
_change(Heap[now].right_node = idx, loc, mid + 1, r, val);
}
}
void change(int v, int loc, int val, int i)
{
int now;
now = history[i] = Malloc();
Heap[now] = Heap[history[v]];
_change(now, loc, 1, n, val);
}
int _query(int now, int loc, int l, int r)
{
if(l == r){
return Heap[now].data;
}
int mid = (l + r) / 2;
if(loc <= mid){
return _query(Heap[now].left_node, loc, l, mid);
}
else{
return _query(Heap[now].right_node, loc, mid + 1, r);
}
}
int query(int v, int loc, int i)
{
int now = history[i] = history[v];
return _query(now, loc, 1, n);
}
}
void Deal()
{
int loc, value, v, opt;
scanf("%d %d", &n, &m);
for(int i = 1; i <= n; i++){
scanf("%d", arr + i);
}
Tree::Build(0, 1, n);
for(int i = 1; i <= m; i++){
scanf("%d %d", &v, &opt);
if(opt == 1){
scanf("%d %d", &loc, &value);
Tree::change(v, loc, value, i);
}
else{
scanf("%d", &loc);
printf("%d\n", Tree::query(v, loc, i));
}
}
}
int main()
{
Deal();
}