/*我的首要看法是先进行排序,采用复杂度为O(nlogn)的排序算法,如堆排序,之后再用二分查找找到在范围内的最大数和最小数的位置,再运算得到数量(当然要设置标志位防止个数为0)每一次操作复杂度为O(logn),总复杂度为O((n + q)logn)。
*/
#include <stdio.h>
#include <stdlib.h>

//交换数组两个元素的位置的函数
void swap(int *a, int *b){
    int temp = *a;
    *a = *b;
    *b = temp;
}

//下沉操作的实现
void sink(int *a, int n, int i){
    while(1){
        int largest = i;
        int left = 2 * i + 1;
        int right = 2 * i + 2;

        //判断左右节点是否大于根节点,如果大于,谁更大?
        if(left < n && a[left] > a[largest]){
            largest = left;
        }
        if(right < n && a[right] > a[largest]){
            largest = right;
        }
        
        //已经下沉到最底部了,不需要再次下沉
        if(largest == i){
            break;
        }
        //交换较大的子节点与根节点的值,并进行下一次循环,对换下去后的结点进行下沉
        else{
            swap(a + i, a + largest);
            i = largest;
        } 
    }
}


//堆排序的函数
void heap_sort_sl(int *a, int n ){
    //堆化操作,形成大顶堆
    //从最后一个非叶节点开始,向前对每一个结点进行下沉操作
    for(int i = n / 2 - 1; i >= 0; i --){
        sink(a, n, i);
    }
    
//排序,每次取堆顶结点,与堆最后一个结点做交换,并使得堆长度减1,再让堆顶元素下沉,直到堆缩小到大小为1
    for(int i = n - 1; i > 0; i --){
        swap(a, a + i);
        sink(a, i, 0);
    }
}

int main() {
    //读取数据
    int n,q;
    scanf("%d %d\n",&n,&q);
    int *a = (int *)malloc(sizeof(int) * n);
    if(a == NULL){
        printf("Failed Malloc!\n");
        return -1;
    }
    for(int i = 0; i < n; i ++){
        scanf("%d", a + i);
    }
    int **lr = (int **)malloc(sizeof(int *) * q);
    if(lr == NULL){
        printf("Failed Malloc!\n");
        return -1;
    }
    for(int i = 0; i < q; i ++){
        lr[i]= (int *)malloc(sizeof(int) * 2);
        if(lr[i] == NULL){
            printf("Failed Malloc!\n");
            return -1;
        }
        scanf("%d %d\n",lr[i],lr[i] + 1);
    }
    heap_sort_sl(a, n);//排序数组,从小到大
    //处理q行
    for(int i = 0; i < q; i ++){
        //取l,r的值
        int l = lr[i][0];
        int r = lr[i][1];

        //设置两个端点
        int low = 0;
        int high = n - 1;
        //rl和rh用来存储范围内的最大数和最小数
        int rl = -1;
        int rh = n + 1;
        
        int flag = 0;//设置标志位,若flag为0,则个数为0
        //进入第一个循环找出范围内的最大数
        while(low <= high){
            int mid = low + (high - low) / 2;
            if(a[mid] <= r && a[mid] >= l){
                flag = 1;//有数在范围内,标志位置1
                rh = mid;
                low = mid + 1;
            }
            else{
               if(a[mid] > r){
                high = mid - 1;
               }
               else{
                low = mid + 1;
               }
            }
        }

        //两个端点复位
        low = 0;
        high = n - 1;

        //进入第二个循环找出范围内的最小数
        while(low <= high){
            int mid = low + (high - low) / 2;
            if(a[mid] <= r && a[mid] >= l){
                flag = 1;//有数在范围内,标志位置1
                rl = mid;
                high = mid - 1;
            }
            else{
               if(a[mid] > r){
                high = mid - 1;
               }
               else{
                low = mid + 1;
               }
            }
        }

        //最大数减去最小数加1就是区间中的元素个数
        int num = rh - rl + 1;
        if(!flag){
            num = 0;
        }
        printf("%d\n",num);
    }
    
    //释放空间
    free(a);
    free(lr);

    return 0;
}