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 int long long
#define mod 1000000007
#define deb(x) cerr << "\n" \
                    << #x << "=" << x << "\n";
#define deb2(x, y) cerr << "\n"                   \
                        << #x << "=" << x << "\n" \
                        << #y << "=" << y << "\n";
#define w(x) \
  int x;     \
  cin >> x;  \
  while (x--)
int n,q;
vector<int> v;
vector<pair<pair<int,int>,int>> query;
int block;
bool comp(pair<pair<int,int>,int> a,pair<pair<int,int>,int> b) {
  if(a.first.first/block != b.first.first/block)
    return a.first.first/block < b.first.first/block;
  return a.first.second<b.first.second;
}
int32_t main()
{
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  cin>>n>>q;
  v.resize(n);
  for(int &i:v)
    cin>>i;
  query.resize(q);
  int pos = 0;
  for(auto &i:query){
    cin>>i.first.first>>i.first.second;
    i.second = pos++;
  }
  
  block = sqrt(n);
  sort(query.begin(),query.end(),comp);

  int curL = 0,curR = 0;
  vector<int> ans(q);
  int freq[n+1];
  memset(freq,0,sizeof freq);
  int si = 0;
  for(auto i:query) {
      int l = i.first.first-1,r = i.first.second-1;
      while (curR <= r) { 
        if(freq[v[curR]] == 0)
          si++;
        freq[v[curR]]++;
        curR++; 
      } 
      while (curR > r+1) { 
        freq[v[curR-1]]--;
        if(freq[v[curR-1]] == 0)
          si--;
        curR--; 
      } 
      while(curL<l) {
        freq[v[curL]]--;
        if(freq[v[curL]] == 0)
          si--;
        curL++;
      }
      while(curL > l) {
        if(freq[v[curL-1]] == 0)
          si++;
        freq[v[curL-1]]++;
        curL--;
      }
      ans[i.second] = si;
  }
  for(int i:ans)
    cout<<i<<"\n";
  return 0;
}