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 C++ (GCC 9.2.1) (judge verdict: Accepted)

#include <iostream>
#include<bits/stdc++.h>
using namespace std;
#define ff first
#define ss second
long int block = 0;
const long int N = 5e5 + 100;
long int tree[4*N]={0};
void update(long int node,long int l,long int r,long int ind, long int val)
{
    if(l==r)
    tree[node]=val;
    else
    {
       long int mid = (l+r)/2;
       if(ind<=mid)
       update(2*node+1,l,mid,ind,val);
       else
       update(2*node+2,mid+1,r,ind,val);
       tree[node] = tree[2*node+1] + tree[2*node+2];
    }
}
long int query(long int node,long int l,long int r,long int L,long int R)
{
    if(R<l || r<L)
    return 0;
    if(L<=l && R>=r)
    return tree[node];
    long int mid = (l+r)/2;
    return query(2*node+1,l,mid,L,R) + query(2*node+2,mid+1,r,L,R);
}
int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
	long int n,q;
	cin>>n>>q;
	long int a[n+1],p[n+1],cnt[n+1]={0};
	for(long int i=1;i<=n;i++)
	cin>>a[i],p[i]=-1;
	vector<pair<long int, long int>> x[n+1];
	long int ans[q]={0};
	long int aa,bb;
	for(long int i=0;i<q;i++)
	{
	    cin>>aa>>bb;
	    x[bb].push_back({aa,i});
	}
	for(long int i=1;i<=n;i++)
	{
	    if(p[a[i]]!=-1)
	    {
	      cnt[p[a[i]]]--;
	      update(0,1,n,p[a[i]],0);
	    }
	      p[a[i]]=i;
	      cnt[i]++;
	      update(0,1,n,i,1);
	      for(long int j=0;j<x[i].size();j++)
	      {
	          ans[x[i][j].ss] = query(0,1,n,x[i][j].ff,i);
	      }
	}
	for(long int i=0;i<q;i++)
	cout<<ans[i]<<endl;
	return 0;
}