#include <cstdio>
#include <algorithm>
#define NMAX 100010
using namespace std;
FILE*fin=fopen ("rmq.in", "r");
FILE*fout=fopen ("rmq.out", "w");
int M[NMAX][20];
int A[NMAX];
int n, m, log2n;
void precalculare();
int query (int, int);
int main()
{
int i, a, b;
fscanf(fin, "%d %d", &n, &m);
for (i=1; i<=n; ++i)
fscanf(fin, "%d", &A[i]);
precalculare();
for (i=1; i<=m; ++i)
{
fscanf(fin, "%d %d", &a, &b);
fprintf(fout, "%d\n", query (a, b));
}
fclose(fout);
return 0;
}
//M[i][j]=pozitia elementului minim in vectorul A din subsecventa care incepe la i si are lungimea 2^j
void precalculare()
{
int i, j;
for (log2n=0, j=1; j<n; j*=2, ++log2n);
//if ((1<<log2n)-n) --log2n;
for (i=1; i<=n; ++i)
M[i][0]=i;
for (j=1; j<=log2n; ++j)
for (i=1; i+(1<<j)-1<=n; ++i)
if (A[M[i][j-1]]<A[M[i+(1<<(j-1))][j-1]])
M[i][j]=M[i][j-1];
else
M[i][j]=M[i+(1<<(j-1))][j-1];
return;
}
int query (int st, int dr)
{
int lg, log2lg, ct;
lg=dr-st+1;
for (log2lg=0, ct=1; ct<lg; ct*=2, ++log2lg);
if ((1<<log2lg)-lg) --log2lg;
return (min (A[M[st][log2lg]], A[M[dr-(1<<log2lg)+1][log2lg]]));
}
//solutie cu arbori de intervale - 70 de puncte
/*#include <cstdio>
#include <algorithm>
#define NMAX 100010*4
using namespace std;
FILE*fin=fopen ("rmq.in", "r");
FILE*fout=fopen ("rmq.out", "w");
int H[NMAX];
int n, m;
void citire();
void actualizare (int, int, int, int, int);
void query (int, int, int, int, int, int&);
int main()
{
int i, val;
int a, b;
fscanf(fin, "%d %d", &n, &m);
for (i=1; i<=n; ++i)
{
fscanf(fin, "%d", &val);
actualizare (1, 1, n, i, val);
}
for (i=1; i<=m; ++i)
{
fscanf(fin, "%d %d", &a, &b);
val=NMAX;
query (1, 1, n, a, b, val);
fprintf(fout, "%d\n", val);
}
return 0;
}
void actualizare (int nod, int st, int dr, int where, int val)
{
int mijl;
if (st==dr)
{
H[nod]=val;
return;
}
//vad unde trebuie sa ma duc acum
mijl=(st+dr)/2;//st, dr reprezinta intervalul in care ma aflu eu acum
//where reprezinta intervalul de lungime 1 pe care trebuie sa il modific
if (where<=mijl)
actualizare (2*nod, st, mijl, where, val);
else
actualizare (2*nod+1, mijl+1, dr, where, val);
H[nod]=min(H[2*nod], H[2*nod+1]);
return;
}
void query (int nod, int st, int dr, int left_query, int right_query, int &rez)
{
int mijl;
if (left_query<=st && dr<=right_query)
{
if (H[nod]<rez)
rez=H[nod];
return;
}
mijl=(st+dr)/2;
if (left_query<=mijl)
query (2*nod, st, mijl, left_query, right_query, rez);
if (mijl<right_query)
query (2*nod+1, mijl+1, dr, left_query, right_query, rez);
return;
}*/