Problem:
Score : 600 points

Problem Statement

We have N colored balls arranged in a row from left to right; the color of the i-th ball from the left is c_i.

You are given Q queries. The i-th query is as follows: how many different colors do the l_i-th through r_i-th balls from the left have?

Constraints

1\leq N,Q \leq 5 \times 10^5

1\leq c_i \leq N

1\leq l_i \leq r_i \leq N

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N Q
c_1 c_2 \cdots c_N
l_1 r_1
l_2 r_2
:
l_Q r_Q

Output

Print Q lines. The i-th line should contain the response to the i-th query.

Sample Input 1

4 3
1 2 1 3
1 3
2 4
3 3

Sample Output 1

2
3
1

The 1-st, 2-nd, and 3-rd balls from the left have the colors 1, 2, and 1 - two different colors.

The 2-st, 3-rd, and 4-th balls from the left have the colors 2, 1, and 3 - three different colors.

The 3-rd ball from the left has the color 1 - just one color.

Sample Input 2

10 10
2 5 6 5 2 1 7 9 7 2
5 5
2 4
6 7
2 2
7 8
7 9
1 8
6 9
8 10
6 8

Sample Output 2

1
2
2
1
2
2
6
3
3
3

Solution in C++ (GCC 9.2.1) (judge verdict: Accepted)

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

vector<int> BIT; //1-indexed

void bitadd(int faddend, int findex){ //call by reference
    for(int i=findex+1; i<BIT.size(); i += (i & -i))BIT[i] += faddend;
    return;
}

int bitsum(int fright){
    int res = 0;
    for(int i=fright+1; i>0; i -= (i & -i))res += BIT[i];
    return res;
}

int main(void){
    int N, Q, cbuf, lbuf, rbuf;
    vector<int> c;
    cin >> N >> Q;
    BIT.assign(N+1, 0);
    vector<int> Colors(N, -1);
    vector<int> colFormer(N, -1);
    vector<int> res(Q);
    vector<vector<pair<int, int>>> query(N);
    for(int i=0; i<N; i++){
        cin >> cbuf;
        cbuf--;
        c.push_back(cbuf);
        colFormer[i]=Colors[cbuf];
        Colors[cbuf]=i;
    }
    for(int iquery=0; iquery<Q; iquery++){
        cin >> lbuf >> rbuf;
        lbuf--;
        rbuf--;
        query[rbuf].push_back(pair<int, int>(iquery, lbuf));
    }
    int iquery_sorted=0;
    for(int curR=0; curR<N; curR++){
        if(colFormer[curR]>=0)bitadd(-1, colFormer[curR]);
        bitadd(1, curR);
        int rightsum = 0;
        int querysize = query[curR].size();
        if(querysize > 0)rightsum = bitsum(curR);
        for(int i=0; i<querysize; i++){
            res[query[curR][i].first] = rightsum - bitsum(query[curR][i].second-1);
        }
    }
    for(int iquery=0; iquery<Q; iquery++)cout << res[iquery] << endl;
    return 0;
}