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: Runtime Error)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

struct event {
	struct QueryEvent *qe;
	struct NumberEvent *ne;
	int type;
};

struct QueryEvent {
	int i, j, ans;
};

struct NumberEvent {
	int num, ind;
};

struct node {
	int l, r, v;
};

int reg[1000001];

struct node *root;

int cmpFun(const void *a, const void *b){
	struct event *f = (struct event *)a;
	struct event *s = (struct event *)b;
	int r = 0;
	if(f->type==1){
		if(s->type==1){
			r = f->ne->ind - s->ne->ind;
		}else{
			r = f->ne->ind - s->qe->j;
			if(r==0)r=-1;
		}
	}else if(f->type==2){ 
		if(s->type==1){ 
			r = f->qe->j - s->ne->ind;
			if(r==0)r = 1;
		}else{ 
			r = f->qe->j - s->qe->j; 
		}
	} 
	return r;
}

int insert(int start, int end, int index, int pos){
	if(start==end){
		root[index].l = 0;
		root[index].r = 0;
		root[index].v = 1;
		return 1;
	}

	int mid = (start+end)/2;

	if(pos <= mid){
		int l = insert(start, mid, index*2+1, pos); 
		root[index].l = l;
	}else{
		int r = insert(mid+1, end, index*2+2, pos);
		root[index].r = r;
	}

	return root[index].v = root[index].l + root[index].r;
}

int removee(int start, int end, int del, int index){
	int pos = del;
	if(start==end){
		root[index].l = 0;
		root[index].r = 0;
		root[index].v = 0;
		return 0;
	}

	int mid = (start+end)/2;

	if(pos <= mid){
		int l = removee(start, mid, del, index*2+1); 
		root[index].l = l;
	}else{
		int r = removee(mid+1, end, del, index*2+2);
		root[index].r = r;
	}

	return root[index].v = root[index].l + root[index].r;
}

int query(int start, int end, int qi, int qj, int index){ 
	if(start>=qi && end <= qj){
		return root[index].v;
	}

	if(qj<start || qi>end){
		return 0;
	}

	int mid = (start+end)/2;
	return query(start, mid, qi, qj, index*2+1)
		+  query(mid+1, end, qi, qj, index*2+2);
}

int main()
{
	memset(reg, -1, 1000001*sizeof(int));
	int n, q;
	struct event *events;
	scanf("%d", &n);
	scanf("%d", &q);

	root = (struct node*)malloc(sizeof(struct node)*(2*pow(2, ceil(log((double)n)/log((double)2)))));

	events = (struct event *)malloc(sizeof(struct event)*(n+200000));
	int ind=0;
	for(int i=0;i<n;++i){
		struct event *e = events+ind++;
		struct NumberEvent *ne = (struct NumberEvent *)malloc(sizeof(struct NumberEvent));
		scanf("%d", &ne->num);
		ne->ind = i;
		e->ne = ne;
		e->type = 1;
	}

	
	struct QueryEvent **original_Queries = (struct QueryEvent **)malloc(q*sizeof(struct QueryEvent*));

	for(int i=0;i<q;++i){
		struct event *q = events+ind++;
		struct QueryEvent *e = (struct QueryEvent *)malloc(sizeof(struct QueryEvent));
		int a, b;
		scanf("%d%d", &a, &b);
		q->type = 2;
		e->i = a-1;
		e->j = b-1;
		q->qe = e;
		original_Queries[i] = e;
	}

	qsort(events, ind, sizeof(struct event), cmpFun);

	for(int i=0;i<ind;++i){
		struct event *e = events+i; 
		if(e->type==1){
			//Number Event
			if(reg[e->ne->num]==-1){
				//Not in tree, add
				insert(0, n-1, 0, e->ne->ind);
				reg[e->ne->num] = e->ne->ind;
			}else{
				int del = reg[e->ne->num];
				//delete this from seg tree
				removee(0, n-1, del, 0);
				reg[e->ne->num] = e->ne->ind;
				//Add this
				insert(0, n-1, 0, e->ne->ind);
			}
		}else{
			//Query Event
			int i = e->qe->i;
			int j = e->qe->j;
			int ans = query(0, n-1, i, j, 0);
			e->qe->ans = ans;
		}
	}

	for(int i=0;i<q;++i){
		printf("%d\n", original_Queries[i]->ans);
	}
	return 0;
}