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)

struct SegmentTree {
  offset : usize,
  data : Vec<usize>,
}

impl SegmentTree {
  fn new(n : usize) -> SegmentTree {
    let offset = n.next_power_of_two();
    let data = vec![0; offset * 2];
    SegmentTree{offset, data}
  }
  
  fn update(&mut self, i : usize, x : usize) {
    let offset = self.offset;
    let data = &mut self.data;

    data[offset + i] = x;
    let mut j = (offset + i) / 2;
    while j > 0 {
      data[j] = data[2 * j] + data[2 * j + 1];
      j /= 2;
    }
  }

  fn range_sum(&self, a : usize, b: usize) -> usize {
    self.range_sum_recursive(a,b,1,0,self.offset).unwrap_or(0)
  }

  fn range_sum_recursive(&self, a:usize, b:usize, k:usize, l:usize, r:usize) -> Option<usize> {
    if r <= a || b <= l {
      return None;
    }
    
    if a <= l && r <= b {
      return Some(self.data[k]);
    }
    let mid = (l + r) / 2;
    
    Some( self.range_sum_recursive(a,b,2 * k, l, mid).unwrap_or(0) 
      + self.range_sum_recursive(a,b,2 * k + 1, mid, r).unwrap_or(0))
  }
}

#[allow(non_snake_case, unused_variables)]
fn main(){  
  use std::io::Read;
  use std::collections::*;
  
  let mut buf = String::new();
  
  std::io::stdin().read_to_string(&mut buf).unwrap();
  let uvec : Vec<usize> = buf.split_whitespace().map(|s| s.parse().unwrap()).collect();

  let N = uvec[0];
  let M = uvec[1];
  let C = &uvec[2 .. N + 2].to_vec();
  let Q :Vec<(usize, usize)>= uvec[N + 2 .. ].chunks(2).map(|ch| (ch[0], ch[1]) ).collect();
  let mut st = SegmentTree::new(N + 1);
  let mut A = vec![0_usize; M];
  
  
  let mut Qi:VecDeque<usize> = {
    let mut i : Vec<usize> = (0 .. M).into_iter().collect();
    i.sort_by_key(|i|{ Q[*i].1 });
    i.into_iter().collect()
  };
  let mut Ci = vec![0_usize; N + 1];

  for i in 1 ..= N {
    let c = C[i - 1];
    let k = Ci[c];
    
    Ci[c] = i;    
    st.update(k, 0);
    st.update(i, 1);
    
    loop {
      if let Some(&j) = Qi.front() {
        let (l,r) = Q[j];
        if r > i {
          break;
        }
      } else {
        break;
      }
      
      if let Some(j) = Qi.pop_front() {
        let (l,r) = Q[j];
        A[j] = st.range_sum(l, r + 1);
      }
    }
  }
  for ans in A {
    println!("{}", ans);
  }
}