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 Rust (1.42.0) (judge verdict: Accepted)

// This code is generated by [cargo-atcoder](https://github.com/tanakh/cargo-atcoder)
// Original source code:
/*
use competitive::prelude::*;

#[argio(output = AtCoder)]
fn main(n: usize, q: usize, c: [Usize1; n], q: [(Usize1, Usize1); q]) -> Vertical<isize> {
    let q = q
        .into_iter()
        .enumerate()
        .sorted_by_key(|r| r.1)
        .collect_vec();

    let mut cur_l = 0;

    let mut prev_occ = vec![-1_isize; n];
    let mut prev_pos = vec![-1_isize; n];

    for i in 0..n {
        prev_pos[i] = prev_occ[c[i]];
        prev_occ[c[i]] = i as isize;
    }

    let mut upd = vec![-1_isize; n];
    let mut b = SegmentTree::<Sum<isize>>::new(n);

    for i in 0..n {
        if prev_pos[i] == -1 {
            b.update(i, Sum(1));
        } else {
            upd[prev_pos[i] as usize] = i as isize;
        }
    }

    let mut ans = vec![-1_isize; q.len()];

    for (i, (l, r)) in q {
        while l > cur_l {
            if upd[cur_l] >= 0 {
                b.update(upd[cur_l] as usize, Sum(1));
            }
            cur_l += 1;
        }

        ans[i] = b.query(l, r + 1).0;
    }

    Vertical(ans)
}
*/

fn main() {
    let exe = "/tmp/binD28635E0";
    std::io::Write::write_all(&mut std::fs::File::create(exe).unwrap(), &decode(BIN)).unwrap();
    std::fs::set_permissions(exe, std::os::unix::fs::PermissionsExt::from_mode(0o755)).unwrap();
    std::process::exit(std::process::Command::new(exe).status().unwrap().code().unwrap())
}

fn decode(v: &str) -> Vec<u8> {
    let mut ret = vec![];
    let mut buf = 0;
    let mut tbl = vec![64; 256];
    for i in 0..64 { tbl[TBL[i] as usize] = i as u8; }
    for (i, c) in v.bytes().filter_map(|c| { let c = tbl[c as usize]; if c < 64 { Some(c) } else { None } }).enumerate() {
        match i % 4 {
            0 => buf = c << 2,
            1 => { ret.push(buf | c >> 4); buf = c << 4; }
            2 => { ret.push(buf | c >> 2); buf = c << 6; }
            3 => ret.push(buf | c),
            _ => unreachable!(),
        }
    }
    ret
}

const TBL: &'static [u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
const BIN: &'static str = "<base64-encoded ELF executable removed>";