CodeEff/ECCO huggingface dataset:
# Original solution
I=lambda:list(map(int,input().split()))
N=0xfffff
n,q=I()
c=list(I())
Q=[]
for i in range(q):l,r=I();Q.append(l<<40|r<<20|i)
Q.sort()
A=[[]for i in range(N)]
for i,x in enumerate(c):A[x].append(i)
B=[0]*N
def P(i,x):
	i+=1
	while i<=n:B[i]+=x;i+=i&-i
def G(i):
	s=0
	while i:s+=B[i];i-=i&-i
	return s
for i in A:
	if i:P(i[0],1);i.reverse()
t=0
o=[0]*q
for x in Q:
	l=x>>40
	r=x>>20&N
	i=x&N
	while t+1<l:
		b=A[c[t]]
		P(b[-1],-1)
		b.pop()
		if b:P(b[-1],1)
		t+=1
	o[i]=G(r)-G(l-1)
for i in o:print(i)

# Optimized solution
I=lambda:list(map(int,input().split()))
N=0xfffff
n,q=I()
c=list(I())
Q=[]
for i in range(q):l,r=I();Q.append(l<<40|r<<20|i)
Q.sort()
A=[[]for i in range(N)]
for i in range(n):A[c[i]].append(i)
B=[0]*N
def P(i,x):
	i+=1
	while i<=n:B[i]+=x;i+=i&-i
def G(i):
	s=0
	while i:s+=B[i];i-=i&-i
	return s
for i in A:
	if i:P(i[0],1);i.reverse()
t=0
o=[0]*q
for x in Q:
	l=x>>40
	r=x>>20&N
	i=x&N
	while t+1<l:
		b=A[c[t]]
		P(b[-1],-1)
		b.pop()
		if b:P(b[-1],1)
		t+=1
	o[i]=G(r)-G(l-1)
for i in o:print(i)
# Original solution
I=lambda:list(map(int,input().split()))
N=0xfffff
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
def G(i):
	s=0
	while i:s+=B[i];i-=i&-i
	return s
for i in A:
	if i:P(i[0],1);i.reverse()
t=0
o=[0]*q
for x in Q:
	l=x>>40
	r=x>>20&N
	i=x&N
	while t+1<l:
		b=A[c[t]]
		P(b[-1],-1)
		b.pop()
		if b:P(b[-1],1)
		t+=1
	o[i]=G(r)-G(l-1)
for i in o:print(i)

# Optimized solution
I=lambda:list(map(int,input().split()))
N=0xfffff
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)
# Original solution
N, Q = list(map(int, input().split()))
lists = [list(map(int, input().split())) for i in range(Q+1)]
master = lists.pop(0)

X = [master[l[0]-1:l[1]] for l in lists]

for x in X:
  print((len(set(x))))


# Optimized solution
N, Q = list(map(int, input().split()))
lists = [list(map(int, input().split())) for i in range(Q+1)]
master = lists.pop(0)

X = [len(set(master[l[0]-1:l[1]])) for l in lists]

for x in X:
  print(x)
# Original solution
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 = list(map(int,input().split()))
a = list(map(int,input().split()))
lr = [list(map(int,input().split())) for i in range(q)]
ans = [0]*q
for i in range(q):
  lr[i].append(i)
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
for i in ans:
  print(i)

# Optimized solution
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")
# Original solution
from collections import defaultdict

n, q = (int(i) for i in input().split())
nums = [0] # not a color
nums = [int(i) for i in input().split()]
nums_info = []
colors = defaultdict(lambda: 0)
for num in nums:
    colors[num] += 1
    nums_info.append(dict(colors))
#print(nums_info)
for _ in range(q):
    s, e = (int(i) for i in input().split())
    s -= 2
    e -= 1
    if s < 0:
        print((len(list(nums_info[e].keys()))))
        continue
    if e - s == len(nums_info[e]) - len(nums_info[s]):
      	print((e - s))
      	continue
    count = 0
    for k, v in list(nums_info[e].items()):
        if k in nums_info[s] and nums_info[s][k] == v:
            continue
        count += 1
    print(count)
    

# Optimized solution
n, q = (int(i) for i in input().split())
nums = [int(i) for i in input().split()]

#print(nums_info)
for _ in range(q):
    s, e = (int(i) for i in input().split())
    s -= 1
    ans = set()
    for i in range(s, e):
        ans.add(nums[i])
    print((len(ans)))
# Original solution
from sys import stdin
#import numpy as np

readline = stdin.readline

N, Q = map(int, readline().split())
C = list(map(int, readline().split()))
S = [list(map(int, readline().split())) for _ in range(Q)]

def main(N, Q, C, S):    
  # Binary Indexed Tree 
  # https://juppy.hatenablog.com/entry/2018/11/17/%E8%9F%BB%E6%9C%AC_python_Binary_Indexed_Tree_%E7%AB%B6%E6%8A%80%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0
  b = [0 for _ in range(N+1)]
  def BIT_query(idx): #idxまでの和(1からスタート)
    res_sum = 0
    while idx > 0:
      res_sum += b[idx]
      idx -= idx&(-idx) #一番下の位を減らす（例：13=1011 → 1010 → 1000） 
    return res_sum
  def BIT_update(idx,x): #idxをx増やした時
    while idx <= N:
      b[idx] += x
      idx += idx&(-idx) #一番下の位を繰り上げる（例：13=1011 → 1100 → 10000 ※N=16のとき） 
    return

  loc = [0 for _ in range(N)] #各種類の玉のうちの最右端の所在地
  S = [[S[i][1], S[i][0], i] for i in range(Q)] #クエリ
  S.sort() #区間の右端でソート
  #S = np.array(S, dtype = np.int64)
  #print(S)
  ans = [0 for _ in range(Q)]
  k = 0
  for j in range(N):
    if loc[C[j]-1] > 0: #玉の更新
      BIT_update(loc[C[j]-1], -1)
    loc[C[j]-1] = j+1
    BIT_update(j+1, 1)  
    
    if S[k][0] == j+1:
      t = BIT_query(j+1)
    while k < len(S) and S[k][0] == j+1: #クエリへの返答
      ans[S[k][2]] = t - BIT_query(S[k][1]-1)
      k += 1
    if k == len(S):
      break
  return ans

ans = main(N, Q, C, S)
print(*ans, sep='\n')


# Optimized solution
from sys import stdin
#import numpy as np

readline = stdin.readline

N, Q = map(int, readline().split()) 
C = list(map(int, readline().split())) 
S = [list(map(int, readline().split())) for _ in range(Q)] 
#print(S)
def main(N, Q, C, S):    
  # Binary Indexed Tree 
  # https://juppy.hatenablog.com/entry/2018/11/17/%E8%9F%BB%E6%9C%AC_python_Binary_Indexed_Tree_%E7%AB%B6%E6%8A%80%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0
  b = [0 for _ in range(N+1)]
  def BIT_query(idx): #idxまでの和(1からスタート)
    res_sum = 0
    while idx > 0:
      res_sum += b[idx]
      idx -= idx&(-idx) #一番下の位を減らす（例：13=1011 → 1010 → 1000） 
    return res_sum
  def BIT_update(idx,x): #idxをx増やした時
    while idx <= N:
      b[idx] += x
      idx += idx&(-idx) #一番下の位を繰り上げる（例：13=1011 → 1100 → 10000 ※N=16のとき） 
    return

  loc = [0 for _ in range(N)] #各種類の玉のうちの最右端の所在地
  S = [(S[i], i) for i in range(Q)] #クエリ
  S.sort(key = lambda s: s[0][1]) #区間の右端でソート
  #S = np.array(S, dtype = np.int64)
  #print(S)
  ans = [0 for _ in range(Q)]
  k = 0
  for j in range(N):
    if loc[C[j]-1] > 0: #玉の更新
      BIT_update(loc[C[j]-1], -1)
    loc[C[j]-1] = j+1
    BIT_update(j+1, 1)  
    
    if S[k][0][1] == j+1:
      t = BIT_query(j+1)
    while k < len(S) and S[k][0][1] == j+1: #クエリへの返答
      ans[S[k][1]] = t - BIT_query(S[k][0][0]-1)
      k += 1
    if k == len(S):
      break
  return ans

ans = main(N, Q, C, S)
print(*ans, sep='\n')
# Original solution
BIT = [0] * ((1 << 19) + 1)
def add(i, x):
    while i <= (1 << 19):
        BIT[i] += x
        i += i & (-i)
def query(i):
    res = 0
    while i > 0:
        res += BIT[i]
        i -= i & (-i)
    return res
n, q = map(int, input().split())
c = list(map(int, input().split()))
Q = [[] for i in range(n)]
for i in range(q):
    l, r = map(int, input().split())
    Q[r - 1].append([l - 1, i])
l = [-1] * n
a = [-1] * q
add(1, n)
for i in range(n):
    add(l[c[i] - 1] + 2, -1)
    add(i + 2, 1)
    l[c[i] - 1] = i
    for j in Q[i]:
        a[j[1]] = query(1 << 19) - query(j[0] + 1)
print(*a, sep="\n")


# Optimized solution
BIT = [0] * ((1 << 19) + 1)
def add(i, x):
    while i <= (1 << 19):
        BIT[i] += x
        i += i & -i
def query(i):
    res = 0
    while i > 0:
        res += BIT[i]
        i -= i & -i
    return res
n, q = map(int, input().split())
c = list(map(int, input().split()))
Q = [[] for i in range(n)]
for i in range(q):
    l, r = map(int, input().split())
    Q[r - 1].append([l - 1, i])
l = [-1] * n
a = [-1] * q
add(1, n)
for i in range(n):
    add(l[c[i] - 1] + 2, -1)
    add(i + 2, 1)
    l[c[i] - 1] = i
    for j in Q[i]:
        a[j[1]] = query(1 << 19) - query(j[0] + 1)
print(*a, sep="\n")
# Original solution
import sys
read=sys.stdin.buffer.readline

class BIT:
    def __init__(self,N):
        self.N=N
        self.bit=[0]*N
    def add(self,a,w):
        x=a
        while(x<self.N):
            self.bit[x]+=w
            x|=x+1
    def get(self,a):
        ret,x=0,a-1
        while(x>=0):
            ret+=self.bit[x]
            x=(x&(x+1))-1
        return ret
    def cum(self,l,r):
        return self.get(r)-self.get(l)

def main():
    def update(x,i):
        if good[x]==-1:
            good[x]=i
            bit.add(i,1)
        else:
            bit.add(good[x],-1)
            good[x]=i
            bit.add(good[x],1)
    
    N,Q=map(int,read().split())
    c=list(map(int,read().split()))
    li=[list(map(lambda x:int(x)-1,read().split()))+[i] for i in range(Q)]
    Query=[(li[i][0],li[i][1],i) for i in range(Q)]
    Query.sort(key=lambda x:x[1])
    ans=[-1]*Q
    good=[-1]*(N+1)
    bit=BIT(N)

    i=0
    for L,R,w in Query:
        while(i<=R and i<N):
            update(c[i],i)
            i+=1
        ans[w]=bit.cum(L,R+1)

    print(*ans,sep='\n')
    
if __name__=='__main__':
    main()


# Optimized solution
import sys
read=sys.stdin.buffer.readline

class BIT:
    def __init__(self,N):
        self.N=N
        self.bit=[0]*N
    def add(self,a,w):
        x=a
        while(x<self.N):
            self.bit[x]+=w
            x|=x+1
    def get(self,a):
        ret,x=0,a-1
        while(x>=0):
            ret+=self.bit[x]
            x=(x&(x+1))-1
        return ret
    def cum(self,l,r):
        return self.get(r)-self.get(l)

def main():
    def update(x,i):
        if good[x]==-1:
            good[x]=i
            bit.add(i,1)
        else:
            bit.add(good[x],-1)
            good[x]=i
            bit.add(good[x],1)
        return
    
    N,Q=map(int,read().split())
    c=tuple(map(int,read().split()))
    Query=[]
    for i in range(Q):
        l,r=map(lambda x:int(x)-1,read().split())
        Query.append((l,r,i))
    Query.sort(key=lambda x:x[1])
    ans=[-1]*Q
    good=[-1]*(N+1)
    bit=BIT(N)

    i=0
    for L,R,w in Query:
        while(i<=R):
            update(c[i],i)
            i+=1
        ans[w]=bit.cum(L,R+1)

    print(*ans,sep='\n')
    return
    
if __name__=='__main__':
    main()
# Original solution
import sys
read=sys.stdin.buffer.readline

class BIT:
    def __init__(self,N):
        self.N=N
        self.bit=[0]*N
    def add(self,a,w):
        x=a
        while(x<self.N):
            self.bit[x]+=w
            x|=x+1
    def get(self,a):
        ret,x=0,a-1
        while(x>=0):
            ret+=self.bit[x]
            x=(x&(x+1))-1
        return ret
    def cum(self,l,r):
        return self.get(r)-self.get(l)

def update(x,i):
    if good[x]==-1:
        good[x]=i
        bit.add(i,1)
    else:
        bit.add(good[x],-1)
        good[x]=i
        bit.add(good[x],1)
    return
    
N,Q=map(int,read().split())
c=tuple(map(int,read().split()))
Query=[]
for i in range(Q):
    l,r=map(lambda x:int(x)-1,read().split())
    Query.append((l,r,i))
Query.sort(key=lambda x:x[1])
ans=[-1]*Q
good=[-1]*(N+1)
bit=BIT(N)

i=0
for L,R,w in Query:
    while(i<=R):
        update(c[i],i)
        i+=1
    ans[w]=bit.cum(L,R+1)

print(*ans,sep='\n')


# Optimized solution
import sys
read=sys.stdin.buffer.readline

class BIT:
    def __init__(self,N):
        self.N=N
        self.bit=[0]*N
    def add(self,a,w):
        x=a
        while(x<self.N):
            self.bit[x]+=w
            x|=x+1
    def get(self,a):
        ret,x=0,a-1
        while(x>=0):
            ret+=self.bit[x]
            x=(x&(x+1))-1
        return ret
    def cum(self,l,r):
        return self.get(r)-self.get(l)

def update(x,i):
    if good[x]==-1:
        good[x]=i
        bit.add(i,1)
    else:
        bit.add(good[x],-1)
        good[x]=i
        bit.add(good[x],1)
    return
    
N,Q=map(int,read().split())
c=tuple(map(int,read().split()))
Query=[]
for i in range(Q):
    l,r=map(lambda x:int(x)-1,read().split())
    Query.append(r*10**12+l*10**6+i)
Query.sort()
ans=[-1]*Q
good=[-1]*(N+1)
bit=BIT(N)

i=0
for w in Query:
    R=w//10**12
    w%=10**12
    L=w//10**6
    w%=10**6
    while(i<=R):
        update(c[i],i)
        i+=1
    ans[w]=bit.cum(L,R+1)

print(*ans,sep='\n')
# Original solution
def main():
    import sys
    input = sys.stdin.readline
    class BIT:
        def __init__(self,n):
            self.tree = [0]*(n+1)
            self.size = n
        
        def add(self,i,x):
            while i <= self.size:
                self.tree[i] += x
                i += i&-i
        
        def sum(self,i):
            s = 0
            while i > 0:
                s += self.tree[i]
                i -= i&-i
            return s

    N,Q = list(map(int,input().split()))
    bit = BIT(N)
    C = list(map(int,input().split()))
    query = []
    for i in range(Q):
        l,r = list(map(int,input().split()))
        query.append([l,r,i])
    query.sort(key=lambda x: x[1])
    ans = []
    #良い玉のindexを1-indexで管理する
    colorMemo = [0]*(N+1)
    cur = 1
    for q in query:
        l,r,j = q
        #良い玉の情報を更新する
        for i in range(cur,r+1):
            c = C[i-1]
            if colorMemo[c]:
                bit.add(colorMemo[c],-1)
            bit.add(i,1)
            colorMemo[c] = i
        cur = r + 1
        ans.append([j,bit.sum(r)-bit.sum(l-1)])

    ans.sort()
    for a in ans:
        print((a[1]))
main()

# Optimized solution
def main():
    import sys
    input = sys.stdin.readline
    class BIT:
        def __init__(self,n):
            self.tree = [0]*(n+1)
            self.size = n
        
        def add(self,i,x):
            while i <= self.size:
                self.tree[i] += x
                i += i&-i
        
        def sum(self,i):
            s = 0
            while i > 0:
                s += self.tree[i]
                i -= i&-i
            return s

    N,Q = map(int,input().split())
    bit = BIT(N)
    C = list(map(int,input().split()))
    query = []
    for i in range(Q):
        l,r = map(int,input().split())
        query.append([l,r,i])
    query.sort(key=lambda x: x[1])
    ans = [0]*Q
    #良い玉のindexを1-indexで管理する
    colorMemo = [0]*(N+1)
    cur = 1
    for q in query:
        l,r,j = q
        #良い玉の情報を更新する
        for i in range(cur,r+1):
            c = C[i-1]
            if colorMemo[c]:
                bit.add(colorMemo[c],-1)
            bit.add(i,1)
            colorMemo[c] = i
        cur = r + 1
        ans[j]=bit.sum(r)-bit.sum(l-1)

    print(*ans, sep="\n")
main()
# Original solution
def main():
    import sys
    input = sys.stdin.readline
    class BIT:
        def __init__(self,n):
            self.tree = [0] * (n+1)
            self.size = n
        
        def add(self,i,x):
            while i <= self.size:
                self.tree[i] += x
                i += i&-i
        
        def get(self,i):
            s = 0
            while i > 0:
                s += self.tree[i]
                i -= i&-i
            return s


    N,Q = list(map(int,input().split()))
    C = list(map(int,input().split()))
    LR = [list(map(int,input().split()))+[i] for i in range(Q)]
    LR.sort(key=lambda x: x[1])
    bit = BIT(N)
    stone = [0]*(N+1)
    cur = 1
    ans = [0]*(Q)
    for l,r,i in LR:
        for j in range(cur,r+1):
            c = C[j-1]
            if stone[c]:
                bit.add(stone[c],-1)
            stone[c] = j
            bit.add(stone[c],1)
        ans[i] = bit.get(r)-bit.get(l-1)
    for a in ans:
        print(a)
main()

# Optimized solution
def main():
    import sys
    input = sys.stdin.readline
    class BIT:
        def __init__(self,n):
            self.tree = [0]*(n+1)
            self.size = n
        
        def add(self,i,x):
            while i <= self.size:
                self.tree[i] += x
                i += i&-i
        
        def sum(self,i):
            s = 0
            while i > 0:
                s += self.tree[i]
                i -= i&-i
            return s

    N,Q = list(map(int,input().split()))
    bit = BIT(N)
    C = list(map(int,input().split()))
    query = []
    for i in range(Q):
        l,r = list(map(int,input().split()))
        query.append([l,r,i])
    query.sort(key=lambda x: x[1])
    ans = [0]*Q
    #良い玉のindexを1-indexで管理する
    colorMemo = [0]*(N+1)
    cur = 1
    for q in query:
        l,r,j = q
        #良い玉の情報を更新する
        for i in range(cur,r+1):
            c = C[i-1]
            if colorMemo[c]:
                bit.add(colorMemo[c],-1)
            bit.add(i,1)
            colorMemo[c] = i
        cur = r + 1
        ans[j]=bit.sum(r)-bit.sum(l-1)

    for a in ans:
        print(a)
main()
# Original solution
import sys

input = sys.stdin.buffer.readline
n, q = list(map(int, input().split()))
C = list(map(int, input().split()))


def popcnt(n):
    c = (n & 0x5555555555555555) + ((n >> 1) & 0x5555555555555555)
    c = (c & 0x3333333333333333) + ((c >> 2) & 0x3333333333333333)
    c = (c & 0x0F0F0F0F0F0F0F0F) + ((c >> 4) & 0x0F0F0F0F0F0F0F0F)
    c = (c & 0x00FF00FF00FF00FF) + ((c >> 8) & 0x00FF00FF00FF00FF)
    c = (c & 0x0000FFFF0000FFFF) + ((c >> 16) & 0x0000FFFF0000FFFF)
    c = (c & 0x00000000FFFFFFFF) + ((c >> 32) & 0x00000000FFFFFFFF)
    return c


num = 2 ** ((n - 1).bit_length())
SEG = [0] * (2 * num)


def func(a, b):
    return a | b


for idx, val in enumerate(C):
    idx += num
    SEG[idx] = 1 << (val - 1)
    while idx > 0:
        idx //= 2
        SEG[idx] = func(SEG[2 * idx], SEG[2 * idx + 1])


def query(left, right):
    resleft = 0
    resright = 0
    left += num
    right += num
    while right - left > 0:
        if left % 2 == 1:
            resleft = func(resleft, SEG[left])
            left += 1
        if right % 2 == 1:
            right -= 1
            resright = func(resright, SEG[right])
        left //= 2
        right //= 2
    return func(resleft, resright)


for _ in range(q):
    l, r = list(map(int, input().split()))
    temp = query(l - 1, r)
    print((popcnt(temp)))


# Optimized solution
import sys

input = sys.stdin.buffer.readline
n, q = map(int, input().split())
C = list(map(int, input().split()))
LR = []
for i in range(q):
    l, r = map(int, input().split())
    LR.append((l, r, i))
LR.sort(key=lambda x: x[1])


BIT = [0] * (n + 1)


def update(idx, val):
    while idx <= n:
        BIT[idx] += val
        idx += idx & (-idx)


def query(idx):
    res = 0
    while idx > 0:
        res += BIT[idx]
        idx -= idx & (-idx)
    return res


pos = [-1] * (n + 1)


def func(idx):
    temp = C[idx]
    if pos[temp] == -1:
        pos[temp] = idx + 1
        update(idx + 1, 1)
    else:
        pre = pos[temp]
        pos[temp] = idx + 1
        update(pre, -1)
        update(idx + 1, 1)


ans = [0] * (q)
idx = 0
for i in range(q):
    l, r, ans_num = LR[i]
    # l,rは0-indexに戻す
    l -= 1
    r -= 1
    while idx < r + 1:  # rになるまで増やす
        if idx < n:  # n超えないように注意
            func(idx)
            idx += 1
        else:
            break
    res = 0
    res += query(r + 1)
    if l > 0:
        res -= query(l)
    ans[ans_num] = res

print(*ans, sep="\n")
# Original solution
from operator import or_
import sys
input = sys.stdin.buffer.readline
sys.setrecursionlimit(10 ** 7)


class SparseTable:
    def __init__(self, N, arr, op):
        self.N = N
        self.depth = N.bit_length()
        self.op = op
        self.arr = tuple(arr)
        self._build()

    def __call__(self, s, t):
        """
        [s, t)区間（0-indexed）での値を返す
        """
        i = (t - s).bit_length() - 1
        L = self.table[i][s]
        R = self.table[i][t - (1 << i)]
        return self.op(L, R)

    def _build(self):
        self.table = []
        self.table.append(self.arr)
        N = self.N
        for i in range(self.depth - 1):
            shift = 1 << i
            N -= shift
            t = tuple(self.op(self.table[-1][j], self.table[-1][j+shift])
                      for j in range(N))
            self.table.append(t)


N, Q = list(map(int, input().split()))
C = [1 << (i-1) for i in map(int, input().split())] + [0]
sp = SparseTable(N+1, C, or_)
for _ in range(Q):
    s, t = list(map(int, input().split()))
    b = bin(sp(s-1, t)).count("1")
    print(b)

# Optimized solution
class SegmentTree:
    def __init__(self, N, arr=None, op=None):
        """
        INPUT
        N: 配列のサイズ
        segment tree: 1-indexedで構築
        original array: 0-indexed
                 1
           2           3
         4    5     6     7
        8 9 10 11 12 13 14 15
        ---------------------
        0 1 2  3  4  5  6  7
        """
        self.N = N
        self.op = op
        self.tree = [set()] * (2 * N + 1)
        if arr is not None:
            self._build(arr)

    def _build(self, arr):
        op = self.op
        N = self.N
        for i, a in enumerate(arr, N):
            self.tree[i] = set([a])
        for i in reversed(list(range(1, N))):
            self.tree[i] = op(self.tree[i << 1], self.tree[i << 1 | 1])

    def update(self, i, x):
        """
        arr[i]の値をxに変更する
        i: 0-indexed
        """
        i += self.N
        op = self.op
        self.tree[i] = x
        while i > 1:
            i >>= 1
            self.tree[i] = op(self.tree[i << 1], self.tree[i << 1 | 1])

    def query(self, L, R):
        """
        L,R: 0-indexed
        半開区間[L,R)の累積演算した値を返す
        """
        op = self.op
        res = set()
        L += self.N
        R += self.N
        while L < R:
            if L & 1:
                res = op(res, self.tree[L])
                L += 1
            if R & 1:
                R -= 1
                res = op(res, self.tree[R])
            L >>= 1
            R >>= 1
        return len(res)


def union(a, b):
    return a | b


N, Q = list(map(int, input().split()))
C = list(map(int, input().split()))
seg = SegmentTree(N, C, union)
for _ in range(Q):
    s, t = list(map(int, input().split()))
    print((seg.query(s-1, t)))