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: Time Limit Exceeded)

/*
AUTHOR: Aman Raj
LANG: C++
*/

using namespace std;

typedef   long long  int ll;
#include <bits/stdc++.h>


//setbase - cout << setbase (16); cout << 100 << endl; Prints 64
//setfill -   cout << setfill ('x') << setw (5); cout << 77 << endl; prints xxx77
//setprecision - cout << setprecision (14) << f << endl; Prints x.xxxx
//cout.precision(x)  cout<<fixed<<val;  // prints x digits after decimal in val
#define fast  ios_base::sync_with_stdio(false); cin.tie(0);  cout.tie(0);
#define all(a) a.begin(),a.end()
//#define mod 998244353


#define mod   1000000007

#define inf 1e18
//#define mod 3
#define flush fflush(stdout)

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
typedef cc_hash_table<ll, ll, hash< ll > > ht;

// find_by_order()  // order_of_key
typedef tree<
    ll,
    null_type,
    less<ll>,
    rb_tree_tag,
    tree_order_statistics_node_update>
    ordered_set;






ll power1(ll a, ll b)//a raised to power b
   {  if(b<=0) return 1; if(b==1) return a;
       ll c=power1(a,b/2);
        c*=c;c%=mod;if(b%2==1) c*=a;c%=mod;
        return c;
   }
   ll mi(ll a,ll m)
   { ll c= power1(a,m-2);

     return c;
   }



 struct less_then_greater {
    template<typename T, typename U>
    bool operator()(T const& lhs, U const& rhs) const {
        if (lhs.first < rhs.first) return true;
        if (rhs.first < lhs.first) return false;
        return lhs.second > rhs.second;
    }
};
 /*std::priority_queue<std::pair<int, int>,
                    std::vector<std::pair<int, int>>,
                    less_then_greater
                   > pq;*/
  /*   #define MAXN 1000001
ll spf[MAXN];
void sieve()
{
    spf[1] = 1;
    for (int i=2; i<MAXN; i++)

        // marking smallest prime factor for every
        // number to be itself.
        spf[i] = i;

    // separately marking spf for every even
    // number as 2
    for (int i=4; i<MAXN; i+=2)
        spf[i] = 2;

    for (int i=3; i*i<MAXN; i++)
    {
        // checking if i is prime
        if (spf[i] == i)
        {
            // marking SPF for all numbers divisible by i
            for (int j=i*i; j<MAXN; j+=i)

                // marking spf[j] if it is not
                // previously marked
                if (spf[j]==j)
                    spf[j] = i;
        }
    }
}
vector<ll> getFactorization(ll x)
{
    vector<ll> ret;
    while (x != 1)
    {
        ret.push_back(spf[x]);
        x = x / spf[x];
    }
    return ret;
}
*/
// take multiset of all edges
// meanwhile for all cc keep record of all edges in multiset too which can be used to digest
// one line or two lines
//
// SEGMENT TREE with N size and balanced
 vector<vector<ll> > vseg;


 ll N,n;
 vector<ll> vv;
  void build(ll l,ll r,ll p)//min and gcd
  {
      if(l==r)
      {
         if(l>=n){ }
         else vseg[p]={vv[l]};
         return;
      }
      ll mid=(l+r)/2;
      build(l,mid,2*p+1);build(mid+1,r,2*p+2);
      vector<ll> v;
      ll a=0,b=0;
      while(1)
      {
          if(a<vseg[2*p+1].size()&&b<vseg[2*p+2].size())
          {
              if(vseg[2*p+1][a]<=vseg[2*p+2][b]){v.push_back(vseg[2*p+1][a]);a++;}
              else { v.push_back(vseg[2*p+2][b]);b++;}
          }
          else if(a<vseg[2*p+1].size()){v.push_back(vseg[2*p+1][a]);a++;}
          else if(b<vseg[2*p+2].size()){v.push_back(vseg[2*p+2][b]);b++;}
          else break;

      }
       vseg[p]=v;
       //cout<<l<<" "<<r<<": ";for(auto x:vseg[p])cout<<x<<" ";cout<<endl;

  }

   ll get(ll l,ll r,ll l1,ll r1,ll p)
   { //cout<<l<<" "<<r<<endl;

       if(r1<l||l1>r)return 0;
        if(l1<=l&&r1>=r)
        {
            vector<ll> v=vseg[p];
             ll a=r1;
             ll l2=0,r2=v.size()-1;
             if(v[0]>a)return v.size();
              while(l2<r2)
              {
                  ll mid=l2+(r2-l2+1)/2;
                  if(v[mid]<=a)l2=mid;
                  else r2=mid-1;
              }
              return v.size()-l2-1;
        }


      ll mid=(l+r)/2;
       ll p1=get(l,mid,l1,r1,2*p+1);
        ll p2=get(mid+1,r,l1,r1,2*p+2);

      return p1+p2;;

   }
int main()
{    fast;
     ll q;cin>>n>>q;
vector<set<ll> > sp(n+1);
     vector<ll> v(n);for(ll i=0;i<n;i++){cin>>v[i];sp[v[i]].insert(i);}


      vv.resize(n);
      ll a=log2(n);a++;N=power1(2,a);
      vseg.resize(4*N);

      for(ll i=0;i<n;i++)
      {
          ll a=v[i];
          auto p=sp[a].find(i);p++;
          if(p!=sp[a].end())vv[i]=*p;
          else vv[i]=n;

      }
      build(0,N-1,0);
       //for(auto x:vv)cout<<x<<" ";cout<<endl;
    //for(auto x:vseg){for(auto y:x)cout<<y<<" ";cout<<endl; }
      while(q--)
      {
          ll l,r;cin>>l>>r;
           cout<<get(0,N-1,l-1,r-1,0)<<endl;
      }
    return 0;
}