#include <fstream>
#include <cstring>
using namespace std;
int A[400010],AD[400010],v[100010], n, m, i, op, a, b, maxim;
//ad[nod] =
void build(int nod, int st, int dr) {
if (st == dr){
A[nod] = v[st];
return;
}
int mid = (st + dr)/2;
build(2*nod, st, mid);
build(2*nod + 1, mid + 1, dr);
A[nod] = max(A[2*nod], A[2*nod+1]);
}
void lazy_update(int nod, int st, int dr, int a, int b, int x) {
if (a<= st && dr <= b) { // ==p
AD[nod] = x;
return;
}
if (AD[nod] != -1) {
AD[2*nod] = AD[2*nod+1] = AD[nod];
A[nod] = AD[nod];
AD[nod] = -1;
}
int mid = (st + dr)/2;
if (a<=mid)
lazy_update(2*nod , st, mid, a,b, x);
if (b>mid)
lazy_update(2*nod+1, mid+1, dr, a,b, x);
A[nod] = max( AD[2*nod] != -1 ? AD[2*nod] : A[2*nod] , AD[2*nod+1]!=-1 ? AD[2*nod+1]:A[2*nod+1] );
}
void query(int nod, int st, int dr, int a, int b) {
if (a <= st && dr <= b) {
maxim = max(maxim, AD[nod] != -1 ? AD[nod] : A[nod]);
return;
}
if (AD[nod] != -1) {
AD[2*nod] = AD[2*nod+1] = AD[nod];
A[nod] = AD[nod];
AD[nod] = -1;
}
int mid = (st + dr)/2;
if (a <= mid)
query(2*nod, st, mid, a, b);
if (b > mid)
query(2*nod+1, mid+1, dr, a, b);
}
int main() {
ifstream fin("arbint.in");
ofstream fout("arbint.out");
fin>>n>>m;
for (i=1;i<=n;i++)
fin>>v[i];
memset(AD,-1,sizeof(AD));
build(1, 1, n);
for (i=1;i<=m;i++) {
fin>>op;
if (op == 0) {
fin>>a>>b;
maxim = 0;
query(1, 1, n, a, b);
fout<<maxim<<"\n";
} else {
fin>>a>>b;
lazy_update(1, 1, n, a, a, b);
}
}
return 0;
}