#include <bits/stdc++.h>
#define rep(i,n) for(int i=0;i<n;i++)
#define repr(i,n) for(int i=n-1;i>=0;i--)
#define MAX(a,b) a=a>b?a:b
#define MIN(a,b) a=a<b?a:b
#define REP(i,x,n) for(int i=x;i<n;i++)
#define REPR(i,x,n) for(int i=n-1;i>=x;i--)
#define pb  push_back
#define ALL(obj) (obj).begin(), (obj).end()
#define ALLr(obj) (obj).rbegin(), (obj).rend()
#define endl "\n"
#define F first
#define S second
#define EN cout<<endl;
#define FAST ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
using namespace std;

typedef long long ll;
typedef pair<ll, ll> P;
typedef tuple<ll,ll,ll> PP;
typedef tuple<ll,ll,ll,ll> PPP;
typedef vector<ll> VLL;
typedef vector<VLL> VVLL;
typedef vector<P> VP;
typedef vector<PP> VPP;
typedef priority_queue<ll> PQ;
const ll mod=1000000007;
template<class T> void out(T a){cout<<a<<'\n';}
template<class T> void outp(T a){cout<<'('<<a.fi<<','<<a.se<<')'<<'\n';}
template<class T> void outvp(T v){rep(i,v.size())cout<<'('<<v[i].fi<<','<<v[i].se<<')';cout<<'\n';}
template<class T> void outvvp(T v){rep(i,v.size())outvp(v[i]);}
template<class T> void outv(T v){rep(i,v.size()){if(i)cout<<' ';cout<<v[i];}cout<<'\n';}
template<class T> void outvv(T v){rep(i,v.size())outv(v[i]);}
template<class T> bool isin(T x,T l,T r){return (l)<=(x)&&(x)<=(r);}
template<class T> void yes(T b){if(b)out("yes");else out("no");}
template<class T> void Yes(T b){if(b)out("Yes");else out("No");}
template<class T> void YES(T b){if(b)out("YES");else out("NO");}
template<class T> void no(T b){if(b)out("no");else out("yes");}
template<class T> void No(T b){if(b)out("No");else out("Yes");}
template<class T> void NO(T b){if(b)out("NO");else out("YES");}
template<class T> int sint(T s){int n;sscanf(s.c_str(),"%d",&n);return n;}
//combsort
template<typename T> void cSort(vector<T>& v){size_t h = (v.size()*10)/13;bool is_sorted = false;while(!is_sorted){if(h==1)is_sorted = true;for(size_t i=0; i<v.size()-h; ++i){if(v[i]>v[i+h]){swap(v[i],v[i+h]);if(is_sorted)is_sorted = false;}}if(h>1) h = (h*10)/13;if(h==0) h = 1;}}
ll gcd(ll a,ll b){if(b==0)return a;return gcd(b,a%b);}
ll modpow(ll a,ll b){ll res=1;a%=mod;while(b){if(b&1)res=res*a%mod;a=a*a%mod;b>>=1;}return res;}
//約数列挙
vector<long long> divisor(long long n) {vector<long long> ret;for (long long i = 1; i * i <= n; i++) {if (n % i == 0) {ret.push_back(i);if (i * i != n) ret.push_back(n / i);}}sort(ret.begin(), ret.end()); return ret;}
template <int MOD>
struct ModInt {int val;ModInt(ll v = 0) : val(v % MOD) {if (val < 0) val += MOD;};ModInt operator+() const { return ModInt(val); }ModInt operator-() const { return ModInt(MOD - val); }ModInt inv() const { return this->pow(MOD - 2); }ModInt operator+(const ModInt& x) const { return ModInt(*this) += x; }ModInt operator-(const ModInt& x) const { return ModInt(*this) -= x; }ModInt operator*(const ModInt& x) const { return ModInt(*this) *= x; }ModInt operator/(const ModInt& x) const { return ModInt(*this) /= x; }ModInt pow(ll n) const {auto x = ModInt(1);auto b = *this;while (n > 0) {if (n & 1) x *= b;n >>= 1;b *= b;}return x;}ModInt& operator+=(const ModInt& x) {if ((val += x.val) >= MOD) val -= MOD;return *this;}ModInt& operator-=(const ModInt& x) {if ((val -= x.val) < 0) val += MOD;return *this;}ModInt& operator*=(const ModInt& x) {val = ll(val) * x.val % MOD;return *this;}ModInt& operator/=(const ModInt& x) { return *this *= x.inv(); }bool operator==(const ModInt& b) const { return val == b.val; }bool operator!=(const ModInt& b) const { return val != b.val; }friend istream& operator>>(istream& is, ModInt& x) noexcept { return is >> x.val; }friend ostream& operator<<(ostream& os, const ModInt& x) noexcept { return os << x.val; }};
constexpr int MOD = 1e9 + 7;
using mint = ModInt<MOD>;

/* SegTree<X>(n,fx,ex): モノイド(集合X, 二項演算fx, 単位元ex)についてサイズnで構築
    set(int i, X x), build(): i番目の要素をxにセット。まとめてセグ木を構築する。O(n)
    update(i,x): i 番目の要素を x に更新。O(log(n))
    query(a,b):  [a,b) 全てにfxを作用させた値を取得。O(log(n))
*/
template <typename X>
struct SegTree {
    using FX = function<X(X, X)>;
    int n;
    FX fx;
    const X ex;
    vector<X> dat;
    SegTree(int n_, FX fx_, X ex_) : n(), fx(fx_), ex(ex_), dat(n_ * 4, ex_) {
        int x = 1;
        while (n_ > x) {
            x *= 2;
        }
        n = x;
    }
    void set(int i, X x) { dat[i + n - 1] = x; }
    void build() {
        for (int k = n - 2; k >= 0; k--) dat[k] = fx(dat[2 * k + 1], dat[2 * k + 2]);
    }
    void update(int i, X x) {
        i += n - 1;
        dat[i] = x;
        while (i > 0) {
            i = (i - 1) / 2;  // parent
            dat[i] = fx(dat[i * 2 + 1], dat[i * 2 + 2]);
        }
    }
    // the minimum element of [a,b)
    X query(int a, int b) { return query_sub(a, b, 0, 0, n); }
    X query_sub(int a, int b, int k, int l, int r) {
        if (r <= a || b <= l) {
            return ex;
        } else if (a <= l && r <= b) {
            return dat[k];
        } else {
            X vl = query_sub(a, b, k * 2 + 1, l, (l + r) / 2);
            X vr = query_sub(a, b, k * 2 + 2, (l + r) / 2, r);
            return fx(vl, vr);
        }
    }
    /* debug */
    inline X operator[](int a) { return query(a, a + 1); }
    void print() {
        for (int i = 0; i < n; ++i) {
            cout << (*this)[i];
            if (i != n) cout << ",";
        }
        cout << endl;
    }
};

int main() {
    FAST;
    ll n,q;
    cin>>n>>q;
    VVLL qu(n+10);
    using X = int;
    auto fx = [](X x1, X x2) -> X { return x1 + x2; };
    X ex = 0;
    SegTree<X> seg(n, fx, ex);
    VLL c;
    VVLL cv(n+10);
    rep(i,n){
        ll a;cin>>a;
        c.pb(a);
        
        if(cv[a].size()==0){
            seg.set(i,1);
        }else{
            seg.set(i,0);
        }
        cv[a].pb(i);
    }
    
    seg.build();
    VPP vp;
    rep(i,q){
        ll l,r;cin>>l>>r;
        vp.pb(PP(l-1,r-1,i));
    }
    sort(ALL(vp));
    ll ans[501010]={};
    ll x=0;
    ll cnt[501010]={};
    rep(i,n){
        while(get<0>(vp[x])==i){
            ans[get<2>(vp[x])]=seg.query(i,get<1>(vp[x])+1);
            x++;
            if(x==q)break;
        }
        cnt[c[i]]++;
        if(cv[c[i]].size()>cnt[c[i]]){
            seg.update(cv[c[i]][cnt[c[i]]],1);
            
        }
    }
    // rep(i,q){
    //     cout<<get<0>(vp[i])+1<<get<1>(vp[i])+1<<get<2>(vp[i])<<endl;
    // }
    rep(i,q)out(ans[i]);


    

    
}


Measured memory_bytes: 77332