#include <functional>
#include <algorithm>
#include <iostream>
#include <utility>
#include <sstream>
#include <iomanip>
#include <numeric>
#include <cstdlib>
#include <cstring>
#include <climits>
#include <cstring>
#include <vector>
#include <cstdio>
#include <string>
#include <stack>
#include <deque>
#include <queue>
#include <cmath>
#include <map>
#include <set>
//#include <bits/stdc++.h>
//#define pb push_back
//#define pf push_front
//#define ppb pop_back
//#define ppf pop_front
#define lwb lower_bound
#define upb upper_bound
#define X first
#define Y second
//#define FOR(i,j,k) for(int i = j; i < (int)(k); i++)
//#define FORV(i, v) FOR(i, 0, ((v).size()))
//#define sz(a) (int)((a).size())
//#define all(a) a.begin() , a.end()
#define coud(a,b) cout<<fixed << setprecision((b)) << (a)
#define L(x) ((x)<<1)
#define R(x) (((x)<<1)+1)
//#define int long long
#define double long double
#define joon ios :: sync_with_stdio(false)
//#define cin fin
//#define cout fout

using namespace std;

typedef pair<int, int> pii;
typedef long long ll;
const double pi = acos(-1);
const double eps = 1e-7;
const int MAXN=800000+100;
int tree1[MAXN];
int tree2[MAXN];
int a[MAXN];
int anskol[MAXN];

void maket1(int id,int l,int r)
{
	if(l==r)
	{
		tree1[id]=a[l];
		return ;
	}
	maket1( L(id) , l , (l+r)/2 );
	maket1( R(id) , (l+r)/2 +1 , r );
	if( tree1[ L(id) ] <= tree1[ R(id) ] )
		tree1[id]=tree1[ L(id) ];
	else
		tree1[id]=tree1[ R(id) ];
}

int query(int id,int l,int r,int lq,int rq)
{
	if( r < lq || rq < l )
		return 1;
	if( lq <= l && r <= rq )
		return tree1[id];
	int ans1=query( L(id) , l , (l+r)/2 , lq , rq );
	int ans2=query( R(id) , (l+r)/2 +1 , r , lq , rq );
	if(ans1==1)
		return ans2;
	if(ans2==1)
		return ans1;
	if( ans1 <= ans2 )
		return ans1;
	return ans2;
}

int query2(int id,int l,int r,int lq,int rq)
{
//	cout<<"["<<l<<","<<r<<"]="<<tree2[id]<<endl;
	if( r < lq || rq < l )
		return 1;
	if( lq <= l && r <= rq )
		return tree2[id];
	int ans1=query2( L(id) , l , (l+r)/2 , lq , rq );
	int ans2=query2( R(id) , (l+r)/2 +1 , r , lq , rq );
	if(ans1==1)
		return ans2;
	if(ans2==1)
		return ans1;
	if( ans1 <= ans2 )
		return ans1;
	return ans2;
}

void add(int id,int l,int r,int pl,int tmp)
{
	if( pl < l || pl > r )
		return ;
	if(l==r)
	{
		tree2[id]=tmp;
		anskol[l]=tmp;
		return ;
	}
	tree2[id]=min(tree2[id],tmp);
	int mid=(l+r)/2;
	if( pl<=mid )
		add( L(id) , l , mid , pl , tmp );
	else
		add( R(id) , mid+1 , r , pl , tmp );
}

int main()
{
	int n,q;
	scanf("%d%d" , &n , &q );
	for(int i=0;i<n;i++)
	{
		int x;
		scanf("%d" , &x );
		a[i]=x;
		a[i]*=-1;
	}
	maket1(1,0,n-1);
	for(int i=1;i<=q;i++)
	{
		int t,l,r;
		scanf("%d%d%d" , &t , &l , &r );
		int ans;
		if(t==1)
		{
			ans=query(1,0,n-1,l-1,r-1);
			add(1,0,q-1,i-1,ans);
			continue;
		}
		ans=query2(1,0,q-1,l-1,r-1);
		add(1,0,q-1,i-1,ans);
	}
	for(int i=0;i<q;i++)
	{
		int xx=-1;
		xx*=anskol[i];
		printf("%d\n" , xx );
	}

	return 0;
}
