#include <bits/stdc++.h>
//#include <ext/pb_ds/assoc_container.hpp>
//using namespace __gnu_pbds;
using namespace std;
typedef long long ll;
typedef long double ld;
//typedef tree<int,null_type,less<int >,rb_tree_tag,tree_order_statistics_node_update>indexed_set;
template<class T1, class T2>
ostream &operator <<(ostream &os, pair<T1,T2>&p);
template <class T>
ostream &operator <<(ostream &os, vector<T>&v);
template <class T>
ostream &operator <<(ostream &os, set<T>&v);
template <class T1, class T2>
ostream &operator <<(ostream &os, map<T1,T2>&v);
#ifdef APURBA
#define debug(a) cout<<#a<<" --> "<<(a)<<"\n";
#define debug2(a) cout<<#a<<" --> "<<(a)<<" ";
#define HERE cout<<"here - "<<__LINE__<<"\n";
#else
#define debug(a)
#define debug2(a)
#define HERE
#endif
const ll mod = 1e9+7;
const int N = 5e5 +5;
typedef pair<int,int> pii;
int block;
struct query
{
    int l,r,idx;
};
bool comp1(query p,query q)
{
    if (p.l / block != q.l / block)
    {
        if(p.l==q.l)
            return p.r<q.r;
        return p.l < q.l;
    }

    return (p.l / block & 1) ? (p.r < q.r) : (p.r > q.r);
}

int n,q,a[N];
int cnt[N];
vector<query>qarra;
int ans[N];
int currans=0;
void Add(int i)
{
    // do your work here
    i = a[i];
    cnt[i]++;
    if(cnt[i]==1)
    {
        currans++;
    }
}
void Remove(int i)
{
    // do your work here
    i = a[i];
    cnt[i]--;
    if(cnt[i]==0)
    {
        currans--;
    }
}

void TEST_CASES(int cas)
{
    scanf("%d %d",&n,&q);
    for(int i=1; i<=n; i++)
    {
        scanf("%d",&a[i]);
    }
    for(int i=0; i<q; i++)
    {
        int l,r;
        scanf("%d %d",&l,&r);
        qarra.push_back({l,r,i});
    }
    block = (int)sqrt(n); // be careful of the block size
    sort(qarra.begin(),qarra.end(),comp1);
    int currL=qarra[0].l,currR=qarra[0].r;

    for(int i=currL; i<=currR; i++)
    {
        Add(i);
    }
    ans[qarra[0].idx] = currans;
    for(int i=1; i<q; i++)
    {
        int l= qarra[i].l,r=qarra[i].r;
        while(currL < l)
        {
            Remove(currL);
            currL++;
        }
        while(currL> l)
        {
            currL--;
            Add(currL);
        }
        while(currR < r)
        {
            currR++;
            Add(currR);
        }
        while(currR > r)
        {
            Remove(currR);
            currR--;
        }
        ans[qarra[i].idx]= currans;
    }

    for(int i=0; i<q; i++)
    {
        printf("%d\n",ans[i]);
    }



}


/*

*/

int main()
{
    //freopen("input.txt","r",stdin);
    //freopen("output.txt","w",stdout);
    int t=1,cas=0;
    //scanf("%d",&t);
    while(t--)
    {
        TEST_CASES(++cas);
    }
    return 0;
}


template<class T1, class T2>
ostream &operator <<(ostream &os, pair<T1,T2>&p)
{
    os<<"{"<<p.first<<", "<<p.second<<"} ";
    return os;
}
template <class T>
ostream &operator <<(ostream &os, vector<T>&v)
{
    os<<"[ ";
    for(int i=0; i<v.size(); i++)
    {
        os<<v[i]<<" " ;
    }
    os<<" ]";
    return os;
}

template <class T>
ostream &operator <<(ostream &os,set<T>&v)
{
    os<<"[ ";
    for(T i:v)
    {
        os<<i<<" ";
    }
    os<<" ]";
    return os;
}
template <class T1, class T2>
ostream &operator <<(ostream &os, map<T1,T2>&v)
{
    for(auto i:v)
    {
        os<<"Key : "<<i.first<<" , Value : "<<i.second<<endl;
    }
    return os;
}


Measured memory_bytes: 15536