#include <fstream>
#include <iostream>
#include <algorithm>
#include <vector>
#define Forward(x) std::forward<decltype(x)>(x)
template<typename T,
typename Alloc = std::vector<T>>
class SegTree {
public:
SegTree(auto&& values) {
n = values.size();
resizeTree(n);
buildTree(0, 0, n - 1, Forward(values));
}
void update(int pos, auto&& values) {
update(0, 0, n - 1, pos, Forward(values));
}
T query(int ql, int qr) const {
return query(0, 0, n - 1, ql, qr);
}
private:
void buildTree(int node, int l, int r, auto&& values) {
if (l == r) {
tree[node] = Forward(values)[l];
} else {
int mid = (l + r) / 2;
buildTree(2 * node + 1, l, mid, Forward(values));
buildTree(2 * node + 2, mid + 1, r, Forward(values));
tree[node] = combine(tree[2 * node + 1], tree[2 * node + 2]);
}
}
void resizeTree(std::size_t n) {
std::size_t size = 1;
while (size < 2 * n) {
size <<= 1;
}
tree.resize(size, INF);
}
T combine(const T& a, const T& b) const {
return a < b ? a : b;
}
void update(int node, int l, int r, int pos, auto&& value) {
if (l == r) {
tree[node] = Forward(value)[l];
} else {
int mid = (l + r) / 2;
if (mid <= pos) update(2 * node + 1, l, mid, pos, Forward(value));
else update(2 * node + 2, mid + 1, r, pos, Forward(value));
tree[node] = combine(tree[2 * node + 1], tree[2 * node + 2]);
}
}
T query(int node, int l, int r, int ql, int qr) const {
if (ql <= l && r <= qr) {
return tree[node];
} else {
int mid = (l + r) / 2;
T answer = INF;
if (ql <= mid) answer = combine(answer, query(2 * node + 1, l, mid, ql, qr));
if (mid < qr) answer = combine(answer, query(2 * node + 2, mid + 1, r, ql, qr));
return answer;
}
}
private:
Alloc tree;
std::size_t n;
const T INF = std::numeric_limits<T>::max();
};
int main() {
std::ifstream fin("rmq.in");
std::ofstream fout("rmq.out");
int n, m;
fin >> n >> m;
std::vector<int> values(n);
for (auto& itr : values) {
fin >> itr;
}
SegTree<int> st(std::move(values));
while (m--) {
int l, r;
fin >> l >> r;
fout << st.query(l - 1, r - 1) << "\n";
}
return 0;
}