#include <bits/stdc++.h>
using namespace std;
int n, m, v[MAXN], t[TREE_MAXN];
void build(int nod, int64_t st, int64_t dr) {
if(st == dr) {
t[nod] = v[st];
return;
}
int64_t mij = st + (dr - st) / 2, left_child = nod << 1,
right_child = (nod << 1) + 1;
build(left_child, st, mij);
build(right_child, mij + 1, dr);
t[nod] = std::min(t[left_child], t[right_child]);
}
int query(int64_t nod, int64_t t_st, int64_t t_dr, int64_t st, int64_t dr) {
if(st > dr)
return MAX_ELEM;
if(st == t_st && dr == t_dr)
return t[nod];
int64_t mij = t_st + (t_dr - t_st) / 2;
return std::min(query(nod << 1, t_st, mij, st, std::min(dr, mij)),
query((nod << 1) + 1, mij + 1, t_dr, std::max(st, mij + 1), dr));
}
void update(int64_t nod, int64_t st, int64_t dr, int64_t pos, int val) {
if(st == dr) {
t[nod] = val;
return;
}
int64_t mij = st + (dr - st) / 2;
if(pos <= mij) {
update(nod << 1, st, mij, pos, val);
} else {
update((nod << 1) + 1, mij + 1, dr, pos, val);
}
t[nod] = std::min(t[nod << 1], t[(nod << 1) + 1]);
}
std::vector<int> rmq(const std::vector<int> &input,
const std::vector< std::pair<int, int> > &queries)
{
int n = input.size(); // input size
std::vector<int> ans; // return vector
ans.reserve(queries.size());
int k = 1;
for(int i : input) {
v[k++] = i;
}
// store segment tree as balanced binary tree of size 4 * n (like a heap)
std::vector<int> tree(n << 2);
// build segment tree
build(1, 1, n);
for(std::pair<int, int> q : queries) {
int left = q.first, right = q.second;
//cout << left << " " << right << ": ";
int result = query(1, 1, n, left, right);
//cout << result << "\n";
ans.push_back(result);
}
return ans;
}
int main()
{
ifstream in("rmq.in");
ofstream out("rmq.out");
int n, q;
in >> n >> q;
vector<int> input;
input.reserve(n);
vector<pair<int, int>> queries;
queries.reserve(q);
for(int i = 0; i < n; ++i) {
int t;
in >> t;
input.push_back(t);
}
for(int i = 0; i < q; ++i) {
int l, r;
in >> l >> r;
queries.push_back(make_pair(l - 1, r - 1));
}
vector<int> ans = rmq(input, queries);
for(int i : ans) {
out << i << "\n";
}
}