// Se da un vector si doi indici
// Sa se determine pozitia elementului minim situat intre cei doi indici.
// Rezolvare cu arbore de intervale
#include <stdio.h>
long n, i, a[100002], m[1000000], s, d,mm;
void initai (int nod, int b, int e, int n) { // initializarea arborelui de intervale
if (b == e) // begin, end
m[nod] = b;
else {
initai (2*nod, b, (b+e)/2, n);
initai (2*nod+1, (b+e)/2+1, e, n);
if (a[m[2*nod]] <= a[m[2*nod+1]]) // Comparam minimele din subarborii fiilor.
m[nod] = m[2*nod];
else
m[nod] = m[2*nod+1];
}
}
int cerere (int nod, int b, int e, int s, int d) {
int mins, mind;
if (d < b || e < s) // Intervalul curent si cel de cautare nu se intersecteaza
return -1;
if (s <= b && e <= d) // Intervalul curent este in interiorul intervalului de cautare
return m[nod];
else {
mins = cerere (2*nod, b, (b+e)/2, s, d); // minimul din stanga
mind = cerere (2*nod+1, (b+e)/2+1, e, s, d); // minimul din dreapta
if (mins == -1)
return mind;
if (mind == -1)
return mins;
if (a[mins] <= a[mind])
return mins;
else
return mind;
}
}
int main() {
freopen("rmq.in","r",stdin);
freopen("rmq.out","w",stdout);
scanf("%ld %ld",&n,&mm);
for (i = 1; i <= n; i++) {
scanf("%ld",&a[i]);
}
initai (1, 1, n, n);
for (i = 1; i <= mm; i++)
{
scanf("%ld %ld",&s,&d);
printf("%ld\n",a[cerere(1, 1, n, s, d)]);
}
return 0;
}
/*
Cazurile posibile in cerere:
( ) [ ] caz 1
s d b e
( [ ) ] caz 3
s b d e
( [ ] ) caz 2
s b e d
[ ()] caz 3
b sde
[ ( ] ) caz 3
b s e d
[ ] () caz 1
b e sd
*/