#include<bits/stdc++.h>
#define Nmax 201005
using namespace std;
typedef unsigned long long int dataTypeOf_IntervalTree;
ifstream fin("arbint.in");
ofstream fout("arbint.out");
/// leftIndex=1; values stocheaza de la 1
int rightIndexMaxValue; ///n
int m;
dataTypeOf_IntervalTree values[Nmax];
dataTypeOf_IntervalTree intervalTree[Nmax];
void BuildIntervalTree(int leftIndex, int rightIndex, int actualNode);
dataTypeOf_IntervalTree CustomBuildFunction(dataTypeOf_IntervalTree intervalTree_LeftNodeValue, dataTypeOf_IntervalTree intervalTree_RightNodeValue);
dataTypeOf_IntervalTree GetValueFromRequestedInterval(int leftRequestIndex, int rightRequestIndex, int leftIndex, int rightIndex, int actualNode);
void UpdateIntervalTree(int valuesPosition, dataTypeOf_IntervalTree newValue, int leftIndex, int rightIndex, int actualNode);
int main()
{
//ios_base::sync_with_stdio(false), cin.tie(0),cout.tie(0);
fin >> rightIndexMaxValue >> m;
for(int i = 1; i<=rightIndexMaxValue; i++)
{
fin >> values[i];
}
BuildIntervalTree(1, rightIndexMaxValue, 1);
for(int i = 1; i<=m; i++)
{
int c, a, b;
fin >> c >> a >> b;
if(c==0)
{
fout << GetValueFromRequestedInterval(a,b, 1, rightIndexMaxValue, 1) << '\n';
}
else
{
UpdateIntervalTree(a, b, 1, rightIndexMaxValue, 1);
}
}
}
void UpdateIntervalTree(int valuesPosition, dataTypeOf_IntervalTree newValue, int leftIndex, int rightIndex, int actualNode)
{
if(leftIndex==rightIndex)
{
values[valuesPosition] = newValue;
intervalTree[actualNode] = newValue;
return ;
}
else
{
int midIndex = (leftIndex + rightIndex)/2;
int leftNode = actualNode*2;
int rightNode = leftNode+1;
if(valuesPosition<=midIndex)
{
UpdateIntervalTree(valuesPosition, newValue, leftIndex, midIndex, leftNode);
}
else
{
UpdateIntervalTree(valuesPosition, newValue, midIndex+1, rightIndex, rightNode);
}
intervalTree[actualNode] = CustomBuildFunction(intervalTree[leftNode], intervalTree[rightNode]);
return;
}
}
dataTypeOf_IntervalTree GetValueFromRequestedInterval(int leftRequestIndex, int rightRequestIndex, int leftIndex, int rightIndex, int actualNode)
{
if (leftIndex>=leftRequestIndex && rightIndex<=rightRequestIndex)
{
return intervalTree[actualNode];
}
int midIndex = (leftIndex+rightIndex)/2;
int leftNode = actualNode*2;
int rightNode = leftNode+1;
if (leftRequestIndex>midIndex)
{
return GetValueFromRequestedInterval(leftRequestIndex, rightRequestIndex, midIndex+1, rightIndex, rightNode);
}
else if (rightRequestIndex <= midIndex)
{
return GetValueFromRequestedInterval(leftRequestIndex, rightRequestIndex, leftIndex, midIndex, leftNode);
}
else
{
int leftNodeValue = GetValueFromRequestedInterval(leftRequestIndex, rightRequestIndex, leftIndex, midIndex, leftNode);
int rightNodeValue = GetValueFromRequestedInterval(leftRequestIndex, rightRequestIndex, midIndex+1, rightIndex, rightNode);
return CustomBuildFunction(leftNodeValue, rightNodeValue);
}
}
void BuildIntervalTree(int leftIndex, int rightIndex, int actualNode)
{
if(leftIndex>rightIndex)
{
return;
}
else if(leftIndex==rightIndex)
{
intervalTree[actualNode] = values[leftIndex];
}
else
{
int midIndex = (leftIndex + rightIndex)/2;
int leftNode = actualNode*2;
int rightNode = leftNode + 1;
BuildIntervalTree(leftIndex, midIndex, leftNode);
BuildIntervalTree(midIndex+1, rightIndex, rightNode);
intervalTree[actualNode] = CustomBuildFunction(intervalTree[leftNode], intervalTree[rightNode]);
}
}
dataTypeOf_IntervalTree CustomBuildFunction(dataTypeOf_IntervalTree intervalTree_LeftNodeValue, dataTypeOf_IntervalTree intervalTree_RightNodeValue)
{
///memoram maximul din interval
if(intervalTree_LeftNodeValue>intervalTree_RightNodeValue)
{
return intervalTree_LeftNodeValue;
}
else
{
return intervalTree_RightNodeValue;
}
}