#include <fstream>
#include <math.h>
#include <vector>

using namespace std;

ifstream fin("vao.inp");
ofstream fout("ra.out");

const int maxN = 1e5;
const int maxT = 4*maxN;
const int minint = -2e9;

class Interval_tree
{
public:
    /* properties */
    int depth, numL, firstB;
    int T[maxT];
    int startI[maxT], endI[maxT];
    /* method */
    void init(int *a, int n);
    int get_max(int left, int right);
    void fix(int i, int v);
};

void Interval_tree::init(int *a, int n)
{
    for(depth=0;(1<<depth)<n;depth++);
    numL =1<<depth;
    firstB = numL-1;
    for(int i=0;i<n;i++)
    {
        T[firstB+i] = a[i];
        startI[firstB+i] = i;
        endI[firstB+i] = i;
    }
    for(int i=firstB-1;i>-1;i--)
    {
        T[i] = max(T[(i<<1)+1],T[(i<<1)+2]);
        startI[i] = min(startI[(i<<1)+1],startI[(i<<1)+2]);
        endI[i] = max(endI[(i<<1)+2],endI[(i<<1)+1]);
    }
    return;
}

int Interval_tree::get_max(int left, int right)
{
    int i, res=minint;
    std::vector <int> stackI;
    stackI.push_back(0);
    while(!stackI.empty())
    {
        i = stackI.back();
        stackI.pop_back();
        if(left>endI[i] || right<startI[i]) continue;
        if(left<=startI[i] && right>=endI[i])
        {
            res=max(res,T[i]);
            continue;
        }
        stackI.push_back((i<<1)+1);
        stackI.push_back((i<<1)+2);
    }
    return res;
}

void Interval_tree::fix(int i, int v)
{
    int j = firstB+i;
    T[j]=v;
    for(--j>>1;j>=0;--j>>1) T[j]= max(T[(j<<1)+1],T[(i<<1)+2]);
    return;
}

int a[maxN];

int n,m,kind,L,R,v;

Interval_tree Ia;

int main()
{
    fin >> n >> m;
    for(int i=0;i<n;i++) fin >> a[i];
    Ia.init(a,n);
    for(int i=0;i<m;i++)
    {
        fin >> kind >> L >> R;
        if (kind==1) { a[L]=R; Ia.fix(L-1,R); }
        if (kind==2) fout << Ia.get_max(L-1,R-1)<<endl;
    }
    return 0;
}
