#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
struct RMQ_t {
int32_t *buffer;
int32_t size;
};
typedef struct RMQ_t* RMQ;
int32_t min(int32_t a, int32_t b) {
return a < b ? a : b;
}
RMQ rm_Init(int32_t *buffer, int32_t size) {
RMQ self = malloc(sizeof(struct RMQ_t));
int32_t totalSize = 1;
while((totalSize <<= 1) < size);
self->size = totalSize * 2;
self->buffer = malloc(sizeof(int32_t) * self->size);
memset(self->buffer, 125, sizeof(int32_t) * self->size);
memcpy(self->buffer, buffer, sizeof(int32_t) * size);
for(int32_t i = 0; i < self->size - 2; i += 2) {
self->buffer[(i >> 1) + (self->size >> 1)] = min(self->buffer[i], self->buffer[i + 1]);
}
return self;
}
void rm_ShowRMQ(RMQ self) {
for(int32_t i = 0; i < self->size - 1; i++) {
printf("%d ", self->buffer[i]);
}
}
int32_t rm_Query(RMQ self, int32_t l, int32_t r) {
if(l >= r) {
return self->buffer[r];
}
int32_t cl = l;
int32_t offset = 1;
int32_t rangeSum = 1e9;
int32_t index = self->size >> 1;
int32_t sumOffset = 0;
while(!(cl & 1) && l + offset < r) {
cl >>= 1;
sumOffset += index + (l >> 1);
rangeSum = min(rangeSum, self->buffer[sumOffset]);
//printf("%d %d %d\n", rangeSum, sumOffset, self->buffer[sumOffset]);
offset <<= 1;
index >>= 1;
}
//printf("\n");
if(offset == 1) {
return min(self->buffer[l], rm_Query(self, l + offset, r));
}
// printf("%d %d %d", l, l + offset - 1, rangeSum);
// exit(0);
return min(rangeSum, rm_Query(self, l + offset, r));
}
int main() {
FILE *fd = fopen("rmq.in", "r+");
FILE *fr = fopen("rmq.out", "w+");
int32_t n, m, a, b;
fscanf(fd, "%d %d", &n, &m);
int32_t *buffer = malloc(sizeof(int32_t) * n);
for(int32_t i = 0; i < n; i++) {
fscanf(fd, "%d", &buffer[i]);
}
RMQ self = rm_Init(buffer, n);
for(int32_t i = 0; i < m; i++) {
fscanf(fd, "%d %d", &a, &b);
// printf("%d %d\n", a, b);
fprintf(fr, "%d\n", rm_Query(self, a - 1, b - 1));
}
// printf("%d\n", rm_Query(self, 0, 3));
// rm_ShowRMQ(self);
}