package main

import (
  "bufio"
  "os"
  "strconv"
  "strings"
  "fmt"
  "sort"
)

type BinaryIndexedTree []int
func (BIT BinaryIndexedTree) Get(idx int) int {
  b := 0
  for i := idx; 0 < i; i -= i & (-i) {
    b += BIT[i]
  }
  return b
}
func (BIT *BinaryIndexedTree) Update(idx, v int) {
  N := len((*BIT))
  d := v - BIT.Get(idx) + BIT.Get(idx - 1)
  for i := idx; i < N; i += i & (-i) {
    (*BIT)[i] += d
  }
}
func (BIT BinaryIndexedTree) Query(s, t int) int {
  // Get [s + 1, t]
  return BIT.Get(t) - BIT.Get(s)
}
func (BIT *BinaryIndexedTree) Increment(idx int) {
  N := len((*BIT))
  for i := idx; i < N; i += i & (-i) {
    (*BIT)[i]++
  }
}
func (BIT *BinaryIndexedTree) Decrement(idx int) {
  N := len((*BIT))
  for i := idx; i < N; i += i & (-i) {
    (*BIT)[i]--
  }
}
func InitBIT(N int) BinaryIndexedTree {
  BIT := make([]int, N + 1)
  return BIT
}

type Segment [][]int
func (S Segment) Len() int { return len(S) }
func (S Segment) Less(i, j int) bool { return S[i][1] < S[j][1] }
func (S Segment) Swap(i, j int) { S[i], S[j] = S[j], S[i] }

func Solve() {
  var N, Q, L, R int
  NextInt(&N, &Q)
  var C []int
  NextIntSlice(&C)
  LR := make([][]int, Q)
  for i := range LR {
    NextInt(&L, &R)
    LR[i] = []int{L - 1, R, i}
  }
  sort.Sort(Segment(LR))
  BIT := InitBIT(N)
  LA := make([]int, N + 1)
  A := make([]int, Q)
  q := 0
  for i, c := range C {
    BIT.Increment(i + 1)
    if LA[c] > 0 { BIT.Decrement(LA[c]) }
    LA[c] = i + 1
    for q < Q && LR[q][1] <= i + 1 {
      A[LR[q][2]] = BIT.Query(LR[q][0], LR[q][1])
      q++
    }
  }
  for _, a := range A { Write(a) }
}

func main() {
  Solve()
  Output()
}

var reader = bufio.NewReaderSize(os.Stdin, 1000000)
var writer = bufio.NewWriter(os.Stdout)
func NextLine() string {
  buffer := make([]byte, 0)
  for true {
    line, isPrefix, err := reader.ReadLine()
    if err != nil { panic(err) }
    buffer = append(buffer, line...)
    if !isPrefix { break }
  }
  return string(buffer)
}
func NextInt(A ...*int) {
  L := strings.Split(NextLine(), " ")
  for i, a := range A {
    *a, _ = strconv.Atoi(L[i])
  }
}
func NextIntSlice(A *[]int) {
  L := strings.Split(NextLine(), " ")
  if len(L) == 1 && L[0] == "" {
    (*A) = make([]int, 0)
    return
  }
  (*A) = make([]int, len(L))
  for i, l := range L {
    (*A)[i], _ = strconv.Atoi(l)
  }
}
func NextFloat(A ...*float64) {
  L := strings.Split(NextLine(), " ")
  for i, a := range A {
    *a, _ = strconv.ParseFloat(L[i], 64)
  }
}
func NextFloatSlice(A *[]float64) {
  L := strings.Split(NextLine(), " ")
  if len(L) == 1 && L[0] == "" {
    (*A) = make([]float64, 0)
    return
  }
  (*A) = make([]float64, len(L))
  for i, l := range L {
    (*A)[i], _ = strconv.ParseFloat(l, 64)
  }
}
func Write(S ...interface{}) {
  fmt.Fprintln(writer, S...)
}
func WriteIntSlice(A []int) {
  B := make([]interface{}, len(A))
  for i, a := range A { B[i] = a }
  fmt.Fprintln(writer, B...)
}
func Output() {
  _ = writer.Flush()
}
func MaxInt(A ...int) int {
  max := A[0]
  for _, a := range A {
    if max < a { max = a }
  }
  return max
}
func MinInt(A ...int) int {
  min := A[0]
  for _, a := range A {
    if a < min { min = a }
  }
  return min
}
func SumInt(A ...int) int {
  sum := 0
  for _, a := range A {
    sum += a
  }
  return sum
}
func AbsInt(x int) int {
  if x < 0 { x = -x }
  return x
}
func Ceil(x, y int) int {
  a := x / y
  if x % y > 0 { a++ }
  return a
}

Measured memory_bytes: 72008