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<bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef pair<int,int> P;

#define p_ary(ary,a,b) do { cout << "["; for (int count = (a);count < (b);++count) cout << ary[count] << ((b)-1 == count ? "" : ", "); cout << "]\n"; } while(0)
#define p_map(map,it) do {cout << "{";for (auto (it) = map.begin();;++(it)) {if ((it) == map.end()) {cout << "}\n";break;}else cout << "" << (it)->first << "=>" << (it)->second << ", ";}}while(0)

template<typename T1,typename T2>ostream& operator<<(ostream& os,const pair<T1,T2>& a) {os << "(" << a.first << ", " << a.second << ")";return os;}

const char newl = '\n';

struct BinaryIndexedTree {
private:
    int n,b;
    vector<int> bit;
public:
    BinaryIndexedTree(int n_) {
        n = n_+10;
        b = 1;
        while (b < n) b <<= 1;
        b >>= 1;
        bit = vector<int>(n,0);
    }

    void add(int a,int w) {
        a++;
        for (int x = a;x < n;x += x&-x) bit[x] += w;
    }

    int sum(int a) {
        a++;
        int ret = 0;
        for (int x = a;x > 0;x -= x&-x) ret += bit[x];
        return ret;
    }

    void update(int a,int w) {
        // a++;
        int v = w-sum(a)+sum(a-1);
        add(a,v);
    }

    int lower_bound(int w) {
        if (w <= 0) return 0;
        int x = 0;
        for (int k = b;k > 0;k /= 2) {
            if (x+k < n && bit[x+k] < w) {
                w -= bit[x+k];
                x += k;
            }
        }
        return x;
    }
};

struct query {
    int l,r,i;
    bool operator<(const query& a) const {
        return r < a.r;
    }
};

int main() {
    int n,q;
    cin >> n >> q;
    vector<int> c(n);
    BinaryIndexedTree bit(n);
    vector<query> a(q);
    vector<int> ans(q),b(n,-1);
    for (int i = 0;i < n;++i) {scanf("%d",&c[i]);c[i]--;}
    for (int i = 0;i < q;++i) {
        scanf("%d%d",&a[i].l,&a[i].r);
        a[i].i = i;
    }
    sort(a.begin(),a.end());
    int j = 0;
    for (int i = 0;i < n;++i) {
        if (b[c[i]] >= 0) bit.add(b[c[i]],-1);
        bit.add(i+1,1);
        b[c[i]] = i+1;
        while (j < q && a[j].r <= i+1) {
            ans[a[j].i] = bit.sum(a[j].r)-bit.sum(a[j].l-1);
            j++;
        }
    }
    for (int i = 0;i < q;++i) printf("%d\n",ans[i]);
}