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# (.NET Core 3.1.201) (judge verdict: Time Limit Exceeded)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;

namespace ABC
{
    class ABC174E
    {
        const string FILE = "/tmp/data.txt";

        static void Main(string[] args)
        {
#if DEBUG
            Console.SetIn(new StreamReader(FILE));
#endif
            int N, Q;
            RI2(out N, out Q);
            var Ia = RIa(N);
            var q = RIa(Q, 2);

            var dic = new Dictionary<long, Node>();

            for (int i = 0; i < N - 1; ++i)
            {
                var node = new Node();
                node.l = i;
                node.r = i + 1;
                node.colorSet.Add(Ia[i]);
                node.colorSet.Add(Ia[i + 1]);

                long key = (long)node.l << 32 | (long)(node.r);
                dic[key] = node;
            }
            for (int len = 2; len < N; ++len)
            {
                for (int i = 0; i < N - len; ++i)
                {
                    long lkey = (long)i << 32 | (long)(i + len - 1);
                    var lnode = dic[lkey];
                    long rkey = (long)(i + 1) << 32 | (long)(i + len);
                    var rnode = dic[rkey];

                    var node = new Node();
                    node.l = i;
                    node.r = i + len;
                    node.colorSet.UnionWith(lnode.colorSet);
                    node.colorSet.UnionWith(rnode.colorSet);

                    long key = (long)node.l << 32 | (long)(node.r);
                    dic[key] = node;
                }
            }

            for (int i = 0; i < Q; ++i)
            {
                if (q[i, 0] == q[i, 1])
                {
                    Console.WriteLine(1);
                }
                else
                {
                    long key = (long)(q[i, 0] - 1) << 32 | (long)(q[i, 1] - 1);
                    Console.WriteLine(dic[key].colorSet.Count);
                }
            }



#if DEBUG
            Console.WriteLine("*** end ***");
            Console.SetIn(Console.In);
            Console.ReadKey();
            Console.WriteLine();
#endif
        }

        class Node
        {
            public HashSet<int> colorSet = new HashSet<int>();
            public int l;
            public int r;
        }

        static int RI()
        {
            return int.Parse(Console.ReadLine());
        }

        static void RI2(out int x, out int y)
        {
            string[] sa = Console.ReadLine().Split(' ');
            x = int.Parse(sa[0]);
            y = int.Parse(sa[1]);
        }

        static int[] RIa(int n)
        {
            string[] sa = Console.ReadLine().Split(' ');
            int[] la = new int[n];
            for (int i = 0; i < n; ++i)
            {
                la[i] = int.Parse(sa[i]);
            }
            return la;
        }

        static int[,] RIa(int r, int c)
        {
            int[,] la = new int[r, c];
            for (int i = 0; i < r; ++i)
            {
                string[] sa = Console.ReadLine().Split(' ');
                for (int j = 0; j < c; ++j)
                {
                    la[i, j] = int.Parse(sa[j]);
                }
            }
            return la;
        }

    }
}