template<class T>
struct RMQ {
int n;
vector<vector<T>> f;
vector<int> log_2;
vector<T> a;
function <T(T, T)> cmp;
RMQ() {}
RMQ(int n, function<T(T, T)> op) :
n(n), f(n + 5, vector<T>(__lg(n) + 1)), log_2(n + 5), a(n + 5), cmp(op) {}
RMQ(int n, const vector <T> &_a, function<T(T, T)> op) :
n(n), f(n + 5, vector<T>(__lg(n) + 1)), log_2(n + 5), a(_a), cmp(op) { init(); }
void init() {
int m = __lg(n);
for(int j = 0; j <= m; j++) {
for(int i = 1; i + (1 << j) - 1 <= n; i++) {
if(!j) f[i][j] = a[i];
else f[i][j] = cmp(f[i][j - 1], f[i + (1 << j - 1)][j - 1]);
}
}
log_2[0] = -1;
for(int i = 1; i <= n; i++) log_2[i] = log_2[i >> 1] + 1;
}
T query(T l, T r) {
assert(l <= r);
int k = log_2[r - l + 1];
return cmp(f[l][k], f[r - (1 << k) + 1][k]);
}
};