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 Scala (2.13.1) (judge verdict: Accepted)

object Main extends App {
  val sc = new FastScanner(System.in)
  val n, q = sc.nextInt()
  val c = List.fill(n)(sc.nextInt()-1)
  val lr = List.fill(q)((sc.nextInt()-1, sc.nextInt()-1))

  val pre = Array.fill(n)(-1)
  val ps = Array.fill(n)(List[Int]())
  for ((r, idx) <- c.zipWithIndex) {
    val l = pre(r)
    if (l != -1) {
      ps(l) ::= idx
    }
    pre(r) = idx
  }

  val qs = Array.fill(n)(List[(Int, Int)]())
  for (((l, r), idx) <- lr.zipWithIndex) {
    qs(l) ::= (r, idx)
  }

  val ans = Array.fill(q)(0)
  val bit = new BinaryIndexedTree(n)

  for (x <- n-1 to 0 by -1) {
    for (y <- ps(x)) {
      bit.add(y, 1)
    }
    for ((y, idx) <- qs(x)) {
      ans(idx) = y-x+1 - bit.query(y+1)
    }
  }

  val pw = new java.io.PrintWriter(Console.out)
  ans.foreach(pw.println)
  pw.flush()
}

class BinaryIndexedTree(n: Int) {
  private val tree = Array.fill(n+1)(0)

  def query(r: Int): Int = {
    var res = 0
    var i = r
    while (i > 0) {
      res += tree(i)
      i -= i & -i
    }
    res
  }

  def add(idx: Int, a: Int): Unit = {
    var i = idx+1
    while (i <= n) {
      tree(i) += a
      i += i & -i
    }
  }
}

class FastScanner(source: java.io.InputStream) {
  val buf = new Array[Byte](1024)
  var now, end = 0

  def isPrintable(b: Byte): Boolean = 33 <= b && b <= 126
  def isNum(b: Byte): Boolean = 48 <= b && b <= 57

  def hasNextByte: Boolean = {
    if (now < end) {
      true
    } else {
      now = 0
      end = source.read(buf)
      end > 0
    }
  }

  def nextByte(): Byte = {
    if (hasNextByte) {
      val b = buf(now)
      now += 1
      b
    } else {
      -1
    }
  }

  def hasNext: Boolean = {
    while (hasNextByte && !isPrintable(buf(now))) {
      now += 1
    }
    hasNextByte
  }

  def next(): String = {
    if (hasNext) {
      val sb = new StringBuilder()
      var b = nextByte()
      while (isPrintable(b)) {
        sb += b.toChar
        b = nextByte()
      }
      sb.toString
    } else {
      throw new NoSuchElementException()
    }
  }

  def nextInt(): Int = {
    nextLong().toInt
  }

  def nextLong(): Long = {
    if (hasNext) {
      var b = nextByte()
      var sign = 1
      var n = 0L
      if (b == '-') {
        sign = -1
        b = nextByte()
      }
      while (isNum(b)) {
        n = n * 10 + (b - 48)
        b = nextByte()
      }
      sign * n
    } else {
      throw new NoSuchElementException()
    }
  }

  def nextDouble(): Double = next().toDouble
}