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 <bits/stdc++.h>
using namespace std;
#define pb push_back
#define mk make_pair
#define mod 1000000007
#define ll long long
#define lb lower_bound
#define ub upper_bound
#define endl "\n"
#define ff first
#define ss second
#define prec(y,x) fixed<<setprecision(y)<<x
#define inf 1e18
#define pi 3.1415926535


int main()
{
	ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif

	int n, q;
	cin >> n >> q;
	int arr[n + 1] = {0};
	for (int i = 1; i <= n; i++)
	{
		cin >> arr[i];
	}
	int h = sqrt(n);
	vector<pair<int, int>> v;
	vector<vector<pair<int, int>>> v1;
	v1.resize(h + 1);

	while (q--)
	{
		int l, r;
		cin >> l >> r;
		v.pb(mk(l, r));
		int u = l / h;
		v1[u].pb(mk(r, l));
		// cout << u << endl;
	}
	for (int i = 0; i <= h; i++)
		sort(v1[i].begin(), v1[i].end());
	/*for (int i = 0; i <= h; i++)
	{
		cout << i << endl;
		for (int j = 0; j < v1[i].size(); j++)
		{
			cout << v1[i][j].ff << " " << v1[i][j].ss << endl;
		}
	}*/
	map<pair<int, int>, int> ans;

	for (int i = 0; i <= h; i++)
	{
		//cout << i << endl;
		int count[n + 1] = {0};
		int cnt = 0;
		if (v1[i].size() == 0)
			continue;
		int l = v1[i][0].ss; int r = v1[i][0].ff;
		int l1 = v1[i][0].ss; int r1 = v1[i][0].ff;
		for (int j = l; j <= r; j++)
		{
			if (count[arr[j]] == 0)
				cnt++;
			count[arr[j]]++;
		}
		ans[mk(l, r)] = cnt;
		//cout << l << " " << r << " " << mp.size() << endl;
		for (int j = 1; j < v1[i].size(); j++)
		{
			l1 = v1[i][j].ss; r1 = v1[i][j].ff;
			if (l1 < l)
			{
				for (int w = l - 1; w >= l1; w--)
				{
					if (count[arr[w]] == 0)
						cnt++;
					count[arr[w]]++;
				}
				//cout<<"as";
			}
			else if (l1 == l)
			{

			}
			else
			{
				for (int w = l; w < l1; w++)
				{
					count[arr[w]]--;
					if (count[arr[w]] == 0)
						cnt--;
				}

			}
			if (r1 < r)
			{
				for (int w = r; w < r1; w--)
				{
					count[arr[w]]--;
					if (count[arr[w]] == 0)
						cnt--;
				}
			}
			else if (r1 == r)
			{

			}
			else
			{
				for (int w = r + 1; w <= r1; w++)
				{
					if (count[arr[w]] == 0)
						cnt++;
					count[arr[w]]++;
				}
			}
			//cout << l1 << " " << r1 << " " << mp.size() << endl;
			ans[mk(l1, r1)] = cnt;
			l = l1; r = r1;
		}

	}
	for (int i = 0; i < v.size(); i++)
	{
		int l = v[i].ff; int r = v[i].ss;
		cout << ans[mk(l, r)] << endl;
	}


	return 0;
}