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.io.*;
import java.util.*;

class Main
{
    static int MAX = 1000001;

    // structure to store queries
    static class Query
    {
        int l, r, idx;
    }

    // updating the bit array
    static void update(int idx, int val,int bit[], int n)
    {
        for (; idx <= n; idx += idx & -idx)
            bit[idx] += val;
    }

    // querying the bit array
    static int query(int idx, int bit[], int n)
    {
        int sum = 0;
        for (; idx > 0; idx -= idx & -idx)
            sum += bit[idx];
        return sum;
    }

    static void answeringQueries(int[] arr, int n,
                                 Query[] queries, int q)
    {

        // initialising bit array
        int[] bit = new int[n + 1];
        Arrays.fill(bit, 0);

        // holds the rightmost index of any number
        // as numbers of a[i] are less than or equal to 10^6
        int[] last_visit = new int[MAX];
        Arrays.fill(last_visit, -1);

        // answer for each query
        int[] ans = new int[q];
        int query_counter = 0;
        for (int i = 0; i < n; i++)
        {

            // If last visit is not -1 update -1 at the
            // idx equal to last_visit[arr[i]]
            if (last_visit[arr[i]] != -1)
                update(last_visit[arr[i]] + 1, -1, bit, n);

            // Setting last_visit[arr[i]] as i and updating
            // the bit array accordingly
            last_visit[arr[i]] = i;
            update(i + 1, 1, bit, n);

            // If i is equal to r of any query store answer
            // for that query in ans[]
            while (query_counter < q && queries[query_counter].r == i)
            {
                ans[queries[query_counter].idx] =
                        query(queries[query_counter].r + 1, bit, n)
                                - query(queries[query_counter].l, bit, n);
                query_counter++;
            }
        }

        // print answer for each query
        for (int i = 0; i < q; i++)
            System.out.println(ans[i]);
    }

    // Driver Code
    public static void main(String[] args)throws Exception
    {
        BufferedReader bu=new BufferedReader(new InputStreamReader(System.in));
        String s[]=bu.readLine().split(" ");
        int n=Integer.parseInt(s[0]),q=Integer.parseInt(s[1]);
        int a[]=new int[n],i;
        s=bu.readLine().split(" ");
        for(i=0;i<n;i++)
        a[i]=Integer.parseInt(s[i]);

        Query[] queries = new Query[q];
        for (i = 0; i < q; i++)
        {
            queries[i] = new Query();
            s=bu.readLine().split(" ");
            queries[i].l=Integer.parseInt(s[0])-1;
            queries[i].r=Integer.parseInt(s[1])-1;
            queries[i].idx=i;
        }


        Arrays.sort(queries, new Comparator<Query>()
        {
            public int compare(Query x, Query y)
            {
                if (x.r < y.r)
                    return -1;
                else if (x.r == y.r)
                    return 0;
                else
                    return 1;
            }
        });
        answeringQueries(a, n, queries, q);
    }
}