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: Runtime Error)

use std::fmt::Debug;
use std::str::FromStr;

pub struct TokenReader {
    reader: std::io::Stdin,
    tokens: Vec<String>,
    index: usize,
}

impl TokenReader {
    pub fn new() -> Self {
        Self {
            reader: std::io::stdin(),
            tokens: Vec::new(),
            index: 0,
        }
    }

    pub fn next<T>(&mut self) -> T
    where
        T: FromStr,
        T::Err: Debug,
    {
        if self.index >= self.tokens.len() {
            self.load_next_line();
        }
        self.index += 1;
        self.tokens[self.index - 1].parse().unwrap()
    }

    pub fn vector<T>(&mut self) -> Vec<T>
    where
        T: FromStr,
        T::Err: Debug,
    {
        if self.index >= self.tokens.len() {
            self.load_next_line();
        }
        self.index = self.tokens.len();
        self.tokens.iter().map(|tok| tok.parse().unwrap()).collect()
    }

    pub fn load_next_line(&mut self) {
        let mut line = String::new();
        self.reader.read_line(&mut line).unwrap();

        self.tokens = line.split_whitespace().map(String::from).collect();
        self.index = 0;
    }
}

#[derive(Clone, Copy)]
struct Query {
    index: usize,
    left: usize,
    right: usize,
    answer: usize,
}

impl Query {
    fn new(index: usize, left: usize, right: usize) -> Self {
        Self {
            index,
            left,
            right,
            answer: 0,
        }
    }
}

struct Window<'a> {
    left: usize,
    right: usize,
    count: Vec<usize>,
    vec: &'a Vec<usize>,
    distinct: usize,
}

impl<'a> Window<'a> {
    fn new(vec: &'a Vec<usize>, start: usize) -> Window<'a> {
        let mut count = vec![0; vec.len() + 1];
        count[vec[start]] += 1;

        Self {
            left: start,
            right: start,
            distinct: 1,
            count,
            vec,
        }
    }

    fn distinct(&self) -> usize {
        self.distinct
    }

    fn overlap(&mut self, left: usize, right: usize) {
        while self.right < right {
            self.add_right();
        }
        while self.left > left {
            self.add_left();
        }

        while self.right > right {
            self.sub_right();
        }
        while self.left < left {
            self.sub_left();
        }
    }

    fn add_left(&mut self) {
        self.left -= 1;
        self.count[self.vec[self.left]] += 1;
        self.update_add(self.left);
    }

    fn add_right(&mut self) {
        self.right += 1;
        self.count[self.vec[self.right]] += 1;
        self.update_add(self.right);
    }

    fn sub_left(&mut self) {
        self.count[self.vec[self.left]] -= 1;
        self.left += 1;
        self.update_sub(self.left - 1);
    }

    fn sub_right(&mut self) {
        self.count[self.vec[self.right]] -= 1;
        self.right -= 1;
        self.update_sub(self.right + 1);
    }

    fn update_add(&mut self, pos: usize) {
        let num = self.vec[pos];
        if self.count[num] == 1 {
            self.distinct += 1;
        }
    }

    fn update_sub(&mut self, pos: usize) {
        let num = self.vec[pos];
        if self.count[num] == 0 {
            self.distinct -= 1;
        }
    }
}

fn solve(colors: &Vec<usize>, queries: &mut Vec<Query>) {
    let block_len = (colors.len() as f64).sqrt() as usize;
    queries.sort_by(|&a, &b| {
        let a_block = a.left / block_len;
        let b_block = b.left / block_len;

        if a_block != b_block {
            a_block.cmp(&b_block)
        } else {
            a.right.cmp(&b.right)
        }
    });

    let mut window = Window::new(colors, 0);
    for i in 0..queries.len() {
        if i == 0 || queries[i].left / block_len != queries[i - 1].left / block_len {
            window = Window::new(colors, queries[i].left);
        }

        window.overlap(queries[i].left - 1, queries[i].right - 1);
        queries[i].answer = window.distinct();
    }
}

fn main() {
    let mut reader = TokenReader::new();
    let _ = reader.next::<usize>();
    let q = reader.next();
    let colors = reader.vector();

    let mut queries = Vec::with_capacity(q);
    for i in 0..q {
        let left = reader.next();
        let right = reader.next();
        queries.push(Query::new(i, left, right));
    }

    solve(&colors, &mut queries);
    queries.sort_by(|&a, &b| a.index.cmp(&b.index));

    for q in queries {
        println!("{}", q.answer);
    }
}