#include <iostream>
#include <fstream>
#define min_SIZE 100005
#define min_VAL (0x3f3f3f3f)
using namespace std;
ifstream f("rmq.in");
ofstream g("rmq.out");
int n, m, arr_init[min_SIZE], tree[min_SIZE*4], pos_min;
int create_tree(int st, int dr, int pos)
{
if (st==dr)
{
tree[pos]=arr_init[st];
if (pos>pos_min)
pos_min=pos;
return tree[pos];
}
int mij=(st+dr)/2;
int val_stanga=create_tree(st,mij,pos*2);
int val_dreapta=create_tree(mij+1,dr,pos*2+1);
tree[pos]=min(val_dreapta,val_stanga);
return tree[pos];
}
int cautare_min(int st, int dr, int stanga_query, int dreapta_query, int pos)
{
if (st>=stanga_query && dr<=dreapta_query)
{
return tree[pos];
}
if (st<stanga_query && dr<stanga_query || st>dreapta_query && dr>dreapta_query)
{
return min_VAL;
}
int mij=(st+dr)/2;
int val_st=cautare_min(st,mij,stanga_query,dreapta_query,pos*2);
int val_dr=cautare_min(mij+1,dr,stanga_query,dreapta_query,pos*2+1);
return min(val_st,val_dr);
}
int update_tree(int st, int dr, int index_tb_updated, int val, int pos)
{
if (st==dr)
{
tree[pos]=val;
return tree[pos];
}
int mij=(st+dr)/2;
if (index_tb_updated<=mij)
{
tree[pos]=min(tree[pos*2+1],update_tree(st,mij,index_tb_updated,val,pos*2));
return tree[pos];
}
else
{
tree[pos]=min(tree[pos*2],update_tree(mij+1,dr,index_tb_updated,val,pos*2+1));
return tree[pos];
}
}
int main() {
int cerinta, termen1, termen2;
f >> n >> m;
for (int i=1; i<=n; i++)
{
f >> arr_init[i];
tree[i]=tree[n+i]=tree[2*n+i]=tree[3*n+i]=min_VAL;
}
create_tree(1,n,1);
for (int query=0; query<m; query++)
{
f >> termen1 >> termen2;
g <<cautare_min(1,n,termen1,termen2, 1) << '\n';
}
return 0;
}