//
// Created by Octavian Farcasi on 28.05.2023.
//
#include<iostream>
#include<fstream>
int minim(int x, int y){
if(x>y)
return y;
return x;
}
//int get_dimensiune(int numar){
// return numar*2-1;
//}
void creare_arb(int valori[],int arb_int[], int low, int high, int poz){
if(low==high){
arb_int[poz]=valori[low];
return;
}
int mijloc=(low+high)/2;
creare_arb(valori,arb_int,low,mijloc,poz*2);
creare_arb(valori,arb_int,mijloc+1,high,(poz*2)+1);
arb_int[poz]= minim(arb_int[poz*2],arb_int[(poz*2)+1]);
}
void actualizare(int arb_int[], int low, int high, int radacina,int pozitie, int valoare){
if(low==high){
arb_int[radacina]=valoare;
return;
}
int mijloc = (low+high)/2;
if (pozitie<=mijloc) //in functie de cum e pozitia fata de mijloc, mergem pe stanga sau pe dreapta
actualizare(arb_int,low,mijloc,radacina*2,pozitie,valoare);
else
actualizare(arb_int,mijloc+1,high,(radacina*2)+1,pozitie,valoare);
arb_int[radacina]= minim(arb_int[radacina*2],arb_int[(radacina*2)+1]);
}
int afla_minimul(int arb_int[],int low, int high, int x, int y, int radacina) {
if(x<=low && high<=y)
return arb_int[radacina]; //intervalul este complet inclus si nodul contine valoarea cautata
int mijloc=(low + high)/2;
int max_stanga = 100001, max_dreapta = 100001;
if(mijloc>=x) //ne ducem pe stanga si cautam minimul
max_stanga = afla_minimul(arb_int,low,mijloc, x, y,radacina*2);
if(mijloc < y) //ne ducem pe dreapta si cautam minimul
max_dreapta = afla_minimul(arb_int,mijloc+1,high, x, y,(radacina*2)+1);
return minim(max_stanga, max_dreapta); //aflam minimul dintre cele doua
}
int main(){
std::ifstream f("rmq.in");
std::ofstream g("rmq.out");
int n,m,a,b;
f>>n>>m;
int arb_int[4*100001], valori[100001];
for(int i=1;i<=n;i++)
f>>valori[i];
for(int i=1;i<4*100001;i++)
arb_int[i]=100001;
creare_arb(valori,arb_int,1,n,1);
for(int i=1;i<=m;i++){
f>>a>>b;
g<<afla_minimul(arb_int,1,n,a,b,1)<<"\n";
}
f.close();
g.close();
return 0;
}