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-----
4 3
1 2 1 3
1 3
2 4
3 3

-----Sample Output-----
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.

Difficulty: MEDIUM_HARD

Solutions:
import sys
input = sys.stdin.readline
(n, q) = map(int, input().split())
c = list(map(int, input().split()))
l = [list(map(int, input().split())) for i in range(q)]
for i in range(q):
	l[i].append(i)
l.sort(key=lambda x: x[1])
L = [-1] * (5 * 10 ** 5 + 1)

class Bit:

	def __init__(self, n):
		self.size = n
		self.tree = [0] * (n + 1)
		self.depth = n.bit_length()

	def sum(self, i):
		s = 0
		while i > 0:
			s += self.tree[i]
			i -= i & -i
		return s

	def add(self, i, x):
		while i <= self.size:
			self.tree[i] += x
			i += i & -i
BIT = Bit(n + 1)
ans = [0] * q
ct = 0
for i in range(q):
	while ct <= l[i][1]:
		if L[c[ct - 1] - 1] != -1:
			BIT.add(L[c[ct - 1] - 1], -1)
		L[c[ct - 1] - 1] = ct + 1
		BIT.add(ct + 1, 1)
		ct += 1
	ans[l[i][2]] = BIT.sum(l[i][1] + 1) - BIT.sum(l[i][0])
for i in range(q):
	print(ans[i])


class BIT:

	def __init__(self, size):
		self.array = [0] * size
		self.size = size

	def add(self, ind, value):
		while ind <= self.size:
			self.array[ind - 1] += value
			ind += ind & -ind

	def sum(self, x):
		out = 0
		while x > 0:
			out += self.array[x - 1]
			x -= x & -x
		return out
import sys
input = sys.stdin.readline

def main(N, Q, c, q):
	bit = BIT(N)
	rbi = {}
	ans = [0] * Q
	q.sort(key=lambda x: x[1])
	R = 0
	for (l, r, ind) in q:
		for i in range(R, r):
			if c[i] in rbi:
				bit.add(rbi[c[i]], -1)
			rbi[c[i]] = i + 1
			bit.add(rbi[c[i]], 1)
		ans[ind] = bit.sum(r) - bit.sum(l - 1)
		R = r
	return ans
(N, Q) = map(int, input().split())
c = list(map(int, input().split()))
q = list((list(map(int, input().split())) + [i] for i in range(Q)))
ans = main(N, Q, c, q)
for i in ans:
	print(i)


from sys import stdin
input = stdin.readline

class Bit:

	def __init__(self, n):
		self.size = n
		self.tree = [0] * (n + 1)

	def sum(self, i):
		s = 0
		while i > 0:
			s += self.tree[i]
			i -= i & -i
		return s

	def add(self, i, x):
		while i <= self.size:
			self.tree[i] += x
			i += i & -i
(n, q) = map(int, input().split())
tmp = list(map(int, input().split()))
color = [-1]
for v in tmp:
	color.append(v)
qry = [None] * q
ans = [0] * q
p = 0
for _ in ans:
	(l, r) = map(int, input().split())
	qry[p] = [l - 1, r, p]
	p += 1
qry.sort(key=lambda x: x[1])
dic = {}
last_update_idx = 1
bit = Bit(n)
for (l, r, i) in qry:
	if last_update_idx < r + 1:
		st = set()
		for j in range(last_update_idx, r + 1):
			if not color[j] in st and color[j] in dic:
				bit.add(dic[color[j]], -1)
			dic[color[j]] = j
			st.add(color[j])
		for v in st:
			bit.add(dic[v], 1)
		last_update_idx = r + 1
	ans[i] = bit.sum(r) - bit.sum(l)
for v in ans:
	print(v)


class Bit:

	def __init__(self, n):
		self.bl = n.bit_length()
		self.size = n
		self.tree = [0] * (n + 1)

	def sum(self, i):
		s = 0
		while i > 0:
			s += self.tree[i]
			i -= i & -i
		return s

	def add(self, i, x):
		while i <= self.size:
			self.tree[i] += x
			i += i & -i
import sys
input = sys.stdin.readline
from collections import defaultdict
(n, q) = map(int, input().split())
a = list(map(int, input().split()))
lr = [tuple(map(int, input().split())) + (i,) for i in range(q)]
ans = [0] * q
lr.sort(key=lambda x: x[1])
bit = Bit(n + 2)
dc = defaultdict(int)
cnt = 0
for (L, R, p) in lr:
	L -= 1
	for i in range(cnt, R):
		if dc[a[i]]:
			l = dc[a[i]] - 1
			r = i
			bit.add(l + 2, 1)
			bit.add(r + 2, -1)
		else:
			bit.add(1, 1)
			bit.add(i + 2, -1)
		dc[a[i]] = i + 1
	ans[p] = bit.sum(L + 1)
	cnt = R
print(*ans, sep='\n')


def segfunc(x, y):
	return x + y
ide_ele = 0

class SegTree:

	def __init__(self, init_val, segfunc, ide_ele):
		n = len(init_val)
		self.segfunc = segfunc
		self.ide_ele = ide_ele
		self.num = 1 << (n - 1).bit_length()
		self.tree = [ide_ele] * 2 * self.num
		for i in range(n):
			self.tree[self.num + i] = init_val[i]
		for i in range(self.num - 1, 0, -1):
			self.tree[i] = self.segfunc(self.tree[2 * i], self.tree[2 * i + 1])

	def update(self, k, x):
		k += self.num
		self.tree[k] = x
		while k > 1:
			self.tree[k >> 1] = self.segfunc(self.tree[k], self.tree[k ^ 1])
			k >>= 1

	def query(self, l, r):
		res = self.ide_ele
		l += self.num
		r += self.num
		while l < r:
			if l & 1:
				res = self.segfunc(res, self.tree[l])
				l += 1
			if r & 1:
				res = self.segfunc(res, self.tree[r - 1])
			l >>= 1
			r >>= 1
		return res
(n, q) = map(int, input().split())
c = list(map(int, input().split()))
st = SegTree([0] * n, segfunc, ide_ele)
lr = [[] for _ in range(n + 1)]
for i in range(q):
	(l, r) = map(int, input().split())
	lr[r] += [(l, i)]
d = {}
for i in range(n):
	if not d.get(c[i]):
		d[c[i]] = [i]
	else:
		d[c[i]] += [i]
for i in d:
	st.update(d[i][-1], 1)
ans = [0] * q
r = n
while r > 0:
	if lr[r]:
		(l, i) = lr[r].pop()
		ans[i] = st.query(l - 1, r)
	while not lr[r] and r > 0:
		if d[c[r - 1]]:
			st.update(d[c[r - 1]].pop(), 0)
		if d[c[r - 1]]:
			st.update(d[c[r - 1]][-1], 1)
		r -= 1
for i in ans:
	print(i)


import sys
reader = (s.rstrip() for s in sys.stdin)
input = reader.__next__

class Binary_Indexed_Tree_RAQ:

	def __init__(self, n):
		self.bit = [0] * (n + 1)
		self.n = n + 1

	def __add(self, ind, num):
		while ind <= self.n:
			self.bit[ind - 1] += num
			ind += ind & -ind

	def range_add(self, s, t, x):
		self.__add(s, x)
		self.__add(t + 1, -x)

	def query(self, i):
		ret = 0
		while i > 0:
			ret += self.bit[i - 1]
			i -= i & -i
		return ret
(n, q) = map(int, input().split())
a = list(map(int, input().split()))
m = 10 ** 6 + 1
prev = [-1] * m
query = []
for i in range(q):
	(l, r) = map(int, input().split())
	(l, r) = (l - 1, r - 1)
	query.append((l, r, i))
ans = [0] * q
query.sort(key=lambda x: x[1])
BIT = Binary_Indexed_Tree_RAQ(n + 1)
cur = 0
for (l, r, i) in query:
	while cur <= r:
		ai = a[cur]
		BIT.range_add(prev[ai] + 2, cur + 1, 1)
		prev[ai] = cur
		cur += 1
	ans[i] = BIT.query(l + 1)
print(*ans, sep='\n')


import sys
input = sys.stdin.readline

class Bit:

	def __init__(self, n):
		self.size = n
		self.tree = [0] * (n + 1)

	def sum(self, i):
		s = 0
		while i > 0:
			s += self.tree[i]
			i -= i & -i
		return s

	def add(self, i, x):
		while i <= self.size:
			self.tree[i] += x
			i += i & -i
(n, q) = list(map(int, input().split()))
ball = list(map(int, input().split()))
h = Bit(n + 1)
L = {}
jump = {}
on = set()
for (i, b) in enumerate(ball):
	if b not in L:
		h.add(i + 1, 1)
		on.add(i + 1)
	if b in L:
		jump[L[b]] = i + 1
	L[b] = i + 1
Q = []
for _ in range(q):
	(l, r) = list(map(int, input().split()))
	Q.append((l, r))
LOO = list(Q)
Q.sort(key=lambda x: x[0])
c = 1
ans = {}
for (l, r) in Q:
	for i in range(c, l):
		if i in on:
			on.remove(i)
			h.add(i, -1)
			if i in jump:
				dest = jump[i]
				h.add(dest, 1)
				on.add(dest)
	tmp = h.sum(r) - h.sum(l - 1)
	ans[l, r] = tmp
	c = l
p = []
for q in LOO:
	p.append(ans[q])
print(*p, sep='\n')


I = lambda : map(int, input().split())
N = 1048575
(n, q) = I()
c = list(I())
Q = []
R = range
for i in R(q):
	(l, r) = I()
	Q.append(l << 40 | r << 20 | i)
Q.sort()
A = [[] for i in R(N)]
for i in R(n):
	A[c[i]].append(i)
B = [0] * N

def P(i, x):
	i += 1
	while i <= n:
		B[i] += x
		i += i & -i
for i in A:
	if i:
		P(i[0], 1)
		i.reverse()
t = 0
o = [0] * q
for x in Q:
	l = (x >> 40) - 1
	r = x >> 20 & N
	i = x & N
	while t < l:
		b = A[c[t]]
		P(b[-1], -1)
		b.pop()
		if b:
			P(b[-1], 1)
		t += 1
	while r:
		o[i] += B[r]
		r -= r & -r
	while l:
		o[i] -= B[l]
		l -= l & -l
for i in o:
	print(i)


import sys
sys.setrecursionlimit(10 ** 6)
int1 = lambda x: int(x) - 1
p2D = lambda x: print(*x, sep='\n')

def II():
	return int(sys.stdin.readline())

def MI():
	return map(int, sys.stdin.readline().split())

def LI():
	return list(map(int, sys.stdin.readline().split()))

def LLI(rows_number):
	return [LI() for _ in range(rows_number)]

def SI():
	return sys.stdin.readline()[:-1]

class BitSum:

	def __init__(self, n):
		self.n = n + 1
		self.table = [0] * self.n

	def add(self, i, x):
		i += 1
		while i < self.n:
			self.table[i] += x
			i += i & -i

	def sum(self, i):
		i += 1
		res = 0
		while i > 0:
			res += self.table[i]
			i -= i & -i
		return res
(n, q) = MI()
cc = LI()
lri = []
mx = 500005
for i in range(q):
	(l, r) = MI()
	l -= 1
	lri.append((l, r - 1, i))
lri.sort(key=lambda x: x[1])
last = [-1] * mx
st = BitSum(mx)
ans = [0] * q
now = 0
for (l, r, i) in lri:
	for j in range(now, r + 1):
		c = cc[j]
		pre = last[c]
		if pre != -1:
			st.add(pre, -1)
		last[c] = j
		st.add(j, 1)
	now = r + 1
	ans[i] = st.sum(r) - st.sum(l - 1)
print(*ans, sep='\n')