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)

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 Fenwick {
    nodes: Vec<i32>,
}

impl Fenwick {
    fn new(len: usize) -> Self {
        Self {
            nodes: vec![0; len + 1],
        }
    }

    fn add(&mut self, mut pos: usize, val: i32) {
        while pos < self.nodes.len() {
            self.nodes[pos] += val;
            pos += Fenwick::lsb(pos);
        }
    }

    fn get(&mut self, mut pos: usize) -> i32 {
        let mut res = 0;
        while pos > 0 {
            res += self.nodes[pos];
            pos -= Fenwick::lsb(pos);
        }
        res
    }

    fn lsb(pos: usize) -> usize {
        let pos = pos as i32;
        (pos & -pos) as usize
    }
}

fn solve(colors: &Vec<usize>, queries: &mut Vec<Query>) {
    let mut prev = vec![None; colors.len() + 1];
    let mut dist = Fenwick::new(colors.len());

    queries.sort_by(|&a, &b| a.right.cmp(&b.right));
    let mut index = 0;

    for i in 0..colors.len() {
        if let Some(prev) = prev[colors[i]] {
            dist.add(prev, -1);
        }
        prev[colors[i]] = Some(i + 1);
        dist.add(i + 1, 1);

        while index < queries.len() && queries[index].right == i + 1 {
            let left = queries[index].left;
            let ans = dist.get(i + 1) - dist.get(left - 1);
            queries[index].answer = ans as usize;
            index += 1;
        }
    }
}

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);
    }
}