#pragma GCC push_options
#pragma GCC optimize("Os")
#include <cstdio>
#include <vector>
#include <climits>
#include <iostream>
struct Min
{
constexpr int operator()(const int a, const int b) const
{
return std::min(a, b);
}
};
template<typename Pred>
class IntTree
{
public:
IntTree(std::vector<int>& vec)
: n(vec.size())
{
data.resize(12 * n, 0);
for(unsigned i = 0; i < n; ++i)
{
insert(i + 1, i + 1, vec[i]);
}
}
IntTree(const unsigned size)
: n(size)
{
data.resize(12 * n, 0);
}
void insert(const unsigned l, const unsigned r, const int value)
{
insert(1, 1, n, l, r, value);
}
int query(const unsigned l, const unsigned r)
{
return query(1, 1, n, l, r);
}
static unsigned lchild(const unsigned index)
{
return index * 2;
}
static unsigned rchild(const unsigned index)
{
return index * 2 + 1;
}
static constexpr int DUMMY = INT_MAX;
private:
void insert(const unsigned index, const unsigned left, const unsigned right,
const unsigned l, const unsigned r, const int value)
{
if(l > right || r < left)
{
return;
}
if(left == right)
{
data[index] = value;
return;
}
const unsigned mij = left + (right - left) / 2;
const unsigned lc_idx = lchild(index);
const unsigned rc_idx = rchild(index);
if(l <= mij)
{
insert(lc_idx, left, mij, l, std::min(mij, r), value);
}
if(r > mij)
{
insert(rc_idx, mij + 1, right, std::max(mij + 1, l), r, value);
}
data[index] = Pred{}(data[lc_idx], data[rc_idx]);
}
int query(const unsigned index, const unsigned left, const unsigned right,
const unsigned l, const unsigned r)
{
if(l > right || r < left)
{
return DUMMY;
}
if(l == left && r == right)
{
return data[index];
}
const unsigned mij = left + (right - left) / 2;
const unsigned lc_idx = lchild(index);
const unsigned rc_idx = rchild(index);
int a = DUMMY;
int b = DUMMY;
if(l <= mij)
{
a = query(lc_idx, left, mij, l, std::min(mij, r));
}
if(r > mij)
{
b = query(rc_idx, mij + 1, right, std::max(mij + 1, l), r);
}
return std::min(a, b);
}
private:
std::vector<int> data;
unsigned n;
};
int main()
{
std::freopen("rmq.in", "r", stdin);
std::freopen("rmq.out", "w", stdout);
unsigned N, M;
std::scanf("%u%u", &N, &M);
IntTree<Min> itree(N);
for(unsigned i = 0; i < N; ++i)
{
int value;
std::scanf("%d", &value);
itree.insert(i + 1, i + 1, value);
}
for(unsigned i = 0; i < M; ++i)
{
int a, b;
std::scanf("%d%d", &a, &b);
std::printf("%d\n", itree.query(a, b));
}
}
#pragma GCC pop_options