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)

#pragma GCC optimize("O3")
// 頑張れ！！
#pragma GCC target("avx,avx2")
#pragma GCC optimize("unroll-loops")
// 頑張れ！！
#include <bits/stdc++.h>
int i;
#define rep2(i, a, b) for(i = a; i <= b; ++i)
#define rep(i, n) for(i = 0; i < n; ++i)
using namespace std;
// _________コーディングはここから！！___________
template <const int sz = 5 * 10000000, typename T = long long> struct IO {
    char reader[sz], writer[sz];
    char *now, *now2 = writer;
    IO() {
        reader[fread(reader, sizeof(char), sizeof(char) * sz, stdin)];
        now = reader;
    }
    inline T read() {
        while(*now && *now <= 32) now++;
        if(*now == '-') {
            now++;
            T res = 0;
            while('0' <= *now and *now <= '9') { res = res * 10 + *now++ - '0'; }
            return -res;
        } else {
            T res = 0;
            while('0' <= *now and *now <= '9') { res = res * 10 + *now++ - '0'; }
            return res;
        }
    }
    inline string read_str() {
        string res;
        while(*now and *now != '\n' and *now != ' ') res += *now++;
        now++;
        return res;
    }
    inline void write(T x, char margin = ' ') {
        if(x == 0) {
            putchar('0');
            putchar(margin);
            return;
        }
        if(x < 0) {
            putchar('-');
            x = -x;
        }
        while(x) {
            *now2 = '0' + x % 10;
            now2++;
            x /= 10;
        }
        do {
            now2--;
            putchar(*now2);
        } while(now2 != writer);
        putchar(margin);
    }
    inline void write_str(string s, char margin = ' ') {
        for(auto c : s) putchar(c);
        putchar(margin);
    }
};
IO io;
inline int read() { return io.read(); }
inline void write(int x) { io.write(x); }
inline void write(int x, char c) { io.write(x, c); }
constexpr int N = 500003;
int c[N];
struct T {
    int l, r, idx;
    constexpr bool operator<(const T &rhs) const noexcept { return r < rhs.r; }
} q[N];
int ans[N], last[N], dat[N];

/**
 * Fenwick Tree(0-indexed, int only)
 * X is height of tree
 * yosupo さん
 */
#include <immintrin.h>
template <int X> struct FenwickSimd {
#define m256 __m256i
    int *seg_base;
    int *(seg[X]);
    m256 segC;
    FenwickSimd() {}
    FenwickSimd(int N) {
        // N < 8**X
        assert(N < 1 << (3 * X));
        int S = 0;
        int segCbuf[8] = {};
        for(int i = 0; i < X; i++) {
            N = (N + 7) / 8;
            segCbuf[i] = S;
            S += 8 * (N + 1);
        }
        seg_base = (int *)aligned_alloc(32, sizeof(int) * S);
        for(int i = 0; i < X; i++) { seg[i] = seg_base + segCbuf[i]; }
        segC = _mm256_load_si256((m256 *)segCbuf);
    }
    /// a[i] += x
    void add(int p, int x) {
        for(int i = 0; i < X; i++) {
            int dp = p & 7, up = p & ~7;

            const m256 pd = _mm256_set1_epi32(dp);
            const m256 base = _mm256_set_epi32(7, 6, 5, 4, 3, 2, 1, 0);
            m256 xx = _mm256_set1_epi32(x);
            xx = _mm256_and_si256(xx, _mm256_cmpgt_epi32(base, pd));

            m256 tar = _mm256_load_si256((m256 *)(seg[i] + up));
            tar = _mm256_add_epi32(tar, xx);
            _mm256_store_si256((m256 *)(seg[i] + up), tar);

            p >>= 3;
        }
    }
    // sum [0, i)
    int sum(int p) {
        int s{0};
        const m256 off = _mm256_set_epi32(21, 18, 15, 12, 9, 6, 3, 0);
        m256 adr = _mm256_set1_epi32(p);
        adr = _mm256_srlv_epi32(adr, off);
        adr = _mm256_add_epi32(adr, segC);

        m256 buf = _mm256_setzero_si256();
        const m256 mask =
            _mm256_set_epi32(7 < X ? -1 : 0, 6 < X ? -1 : 0, 5 < X ? -1 : 0, 4 < X ? -1 : 0, 3 < X ? -1 : 0, 2 < X ? -1 : 0, 1 < X ? -1 : 0, 0 < X ? -1 : 0);
        buf = _mm256_mask_i32gather_epi32(buf, seg_base, adr, mask, 4);

        buf = _mm256_hadd_epi32(buf, buf);
        buf = _mm256_hadd_epi32(buf, buf);
        s += _mm256_extract_epi32(buf, 0);
        s += _mm256_extract_epi32(buf, 4);

        return s;
    }
    // sum [a, b)
    int sum(int a, int b) { return sum(b) - sum(a); }
};
int n, Q, now = 1;
T qq[N];
int cnt[N], all;
main() {
    n = io.read(), Q = io.read();
    rep2(i, 1, n) c[i] = io.read();
    rep(i, Q) qq[i].l = io.read(), qq[i].r = io.read() + 1, qq[i].idx = i, cnt[qq[i].r]++;
    // sort
    rep(i, N - 1) cnt[i + 1] += cnt[i];
    rep(i, Q) { q[--cnt[qq[i].r]] = move(qq[i]); }
    // sort end
    FenwickSimd<7> bit(N);
    rep(i, Q) {
        for(; now < q[i].r; ++now) {
            if(last[c[now]]) ++all, bit.add(last[c[now]], 1);
            last[c[now]] = now;
        }
        ans[q[i].idx] = q[i].r - q[i].l - (all - bit.sum(q[i].l));
    }
    rep(i, Q) write(ans[i], '\n');
}