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 Java (OpenJDK 11.0.6) (judge verdict: Time Limit Exceeded)

import java.util.*;
import java.io.*;

public class Main {
	public static void main (String[] args) throws Exception {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String[] first = br.readLine().split(" ", 2);
 		int n = Integer.parseInt(first[0]);
		int q = Integer.parseInt(first[1]);
		String[] nums = br.readLine().split(" ", n);
		Query[] queries = new Query[q];
		for (int i = 0; i < q; i++) {
		    String[] line = br.readLine().split(" ", 2);
		    queries[i] = new Query(i, Integer.parseInt(line[0]) - 1, Integer.parseInt(line[1]) - 1);
		}
		Arrays.sort(queries);
		HashMap<Integer, Integer> map = new HashMap<>();
		ArrayList<Integer> list = new ArrayList<>();
		int[] ans = new int[q];
		int idx = 0;
		for (int i = 0; i < n; i++) {
		    int y = Integer.parseInt(nums[i]);
		    if (map.containsKey(y)) {
		        int x = map.get(y);
		        int left = 0;
		        int right = list.size();
		        while (true) {
		            int m = (left + right) / 2;
		            if (list.get(m) == x) {
		                list.remove(m);
		                break;
		            } else if (list.get(m) < x) {
		                left = m + 1;
		            } else {
		                right = m;
		            }
		        }
		    }
		    list.add(i);
		    map.put(y, i);
		    while (idx < q && queries[idx].right == i) {
		        int left = -1;
		        int right = list.size() - 1;
		        while (right - left > 1) {
		            int m = (left + right) / 2;
		            if (list.get(m) < queries[idx].left) {
		                left = m;
		            } else {
		                right = m;
		            }
		        }
		        ans[queries[idx].idx] = list.size() - right;
		        idx++;
		    }
		}
		StringBuilder sb = new StringBuilder();
		for (int x : ans) {
		    sb.append(x).append("\n");
		}
		System.out.print(sb);
	}
	
	static class Query implements Comparable<Query> {
	    int idx;
	    int left;
	    int right;
	    
	    public Query(int idx, int left, int right) {
	        this.idx = idx;
	        this.left = left;
	        this.right = right;
	    }
	    
	    public int compareTo(Query another) {
	        return right - another.right;
	    }
	}
}