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: Time Limit Exceeded)

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
#define MOD ll(1e9+7)
#define all(x) (x).begin(),(x).end()
#define dbg(x) cerr<<#x<<": "<<x<<endl


template<class T>
void print_set(set<T> &s){
    cout << "size = " << s.size() << endl;
    for(auto it = s.begin(); it != s.end(); ++it){
        cout << *it << " ";
    }
    cout << endl << endl;
}

class segtree{
public:
    segtree(ll size, vector<set<ll>> &v){
        n = 1;
        while(n < size){n *= 2;}
        data = vector<set<ll>>(2*n-1, INIT_VAL);
        build(v);
    }
    void build(vector<set<ll>> &v){
        for(int i = 0; i < v.size(); i++){
            data[n-1+i].insert(all(v[i]));
        }
        for(int i = n-2; i >= 0; i--){
            data[i].insert(all(data[2*i+1]));
            data[i].insert(all(data[2*i+2]));
        }
    }

    ll getSize(){return n;}
    set<ll> getData(ll x){return data[n-1+x];}
    //[a,b)の最小値を返す
    //segtree.query(a,b,0,0,n)で呼ぶ

    set<ll> query(ll a, ll b, ll k, ll l, ll r){
        if(r <= a || b <= l){return INIT_VAL;}   //交差しない
        if(a <= l && r <= b){return data[k];}   //完全に含む
        else{
            set<ll> vl = query(a, b, 2*k+1, l, (l+r)/2);
            set<ll> vr = query(a, b, 2*k+2, (l+r)/2, r);
            vl.insert(all(vr));
            return vl;
        }
    }
    void p(){
        for(int i = 0; i < data.size(); i++){
            print_set(data[i]);

        }
    }
private:
    ll n;
    vector<set<ll>> data;
    set<ll> INIT_VAL;
};



int main(){
    ll n, q;
    cin >> n >> q;
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    vector<ll> c(n);
    for(int i = 0; i < n; i++){
        cin >> c[i];
    }

    set<ll> init_val;
    vector<set<ll>> a(n, init_val);
    for(int i = 0; i < n; i++){
        a[i].insert(c[i]);
    }
    segtree st(n, a);
    for(int i = 0; i < q; i++){
        ll l, r;
        cin >> l >> r;
        l--; r--;
        set<ll> ret = st.query(l, r+1, 0, 0, st.getSize());
        cout << ret.size() << endl;

    }

}