#include<cstdio>
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
#define MaxVal 200005
using namespace std;

typedef struct{
    int n, idx, r;
}line;

bool cmp1(line a, line b){ return a.n < b.n; }
bool cmp2(line a, line b){ return a.idx < b.idx; }

line h[MaxVal];
int h2[MaxVal];

int nn[MaxVal];
int nnl[MaxVal];
int pvl[MaxVal];
int pvvl[MaxVal];
int pvr[MaxVal];
int pvvr[MaxVal];
int n2[MaxVal];
int ans[MaxVal];
//vector<int> adj[MaxVal];
vector<pair<int, int> > adj[MaxVal];

void update(int idx ,int val)
{
    while (idx <= MaxVal){
         h2[idx] += val;
         idx += (idx & -idx);
    }
}

int read(int idx)
{
    int sum = 0;
    while (idx > 0){
         sum += h2[idx];
         idx -= (idx & -idx);
    }
    return sum;
}

int main()
{
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
    int n, m;
    scanf("%d %d", &n, &m);
    for(int i = 1; i <= n; i++) { scanf("%d", &h[i].n); h[i].idx = i; }

    sort(h + 1, h + n + 1, cmp1);
    int t = 1;
    n2[t] = h[1].n;
    h[1].r = t;
    for(int i = 2; i <= n; i++) {
         if(h[i - 1].n != h[i].n) { t++; n2[t] = h[i].n; h[i].r = t; }
         else { h[i].r = t; }
    }
    sort(h + 1, h + n + 1, cmp2);
    //for(int i = 1; i <= n; i++) printf("%d ", h[i].r);
    int ll, rr;
    for(int i = 0; i < m; i++) {
         int l, r;
         scanf("%d %d", &l, &r);
         ll = l; rr = r;
         //adj[r].push_back(l);
         adj[r].push_back(make_pair(l, i));
    }
    for(int i = 1; i <= n; i++) {
         if(nn[h[i].r] == 0) { nnl[h[i].r] = i; }
         nn[h[i].r]++;
         if(nn[h[i].r] == n2[h[i].r]) {
              /*update(i, 1);
              if(pv[h[i].r] != 0 && pvv[h[i].r] == 0) {
                   update(pv[h[i].r], -2);
                   pvv[h[i].r] = pv[h[i].r];
              }
              else if(pv[h[i].r] != 0 && pvv[h[i].r] != 0) {
                   update(pv[h[i].r], -2);
                   update(pvv[h[i].r], 1);
                   pvv[h[i].r] = pv[h[i].r];
              }
              pv[h[i].r] = i;
              nn[h[i].r] = 0;*/
              update(nnl[h[i].r], 1);
              if(pvl[h[i].r] != 0 && pvvl[h[i].r] == 0) {
                   update(pvl[h[i].r], -1);
                   update(pvr[h[i].r], -1);
                   pvvl[h[i].r] = pvl[h[i].r];
                   pvvr[h[i].r] = pvr[h[i].r];
              }
              else if(pvl[h[i].r] != 0 && pvvl[h[i].r] != 0) {
                   update(pvl[h[i].r], -1);
                   update(pvr[h[i].r], -1);
                   update(pvvr[h[i].r], 1);
                   pvvl[h[i].r] = pvl[h[i].r];
                   pvvr[h[i].r] = pvr[h[i].r];
              }
              pvl[h[i].r] = nnl[h[i].r];
              pvr[h[i].r] = i;
              nn[h[i].r] = 0;
         }
         for(int j = 0; j < adj[i].size(); j++) {
              int a = read(i); int b = 0;
              if(adj[i][j].first > 1) b = read(adj[i][j].first - 1);
              ans[adj[i][j].second] = a - b;
         }
    }
    for(int i = 0; i < m; i++) { printf("%d\n", ans[i]);
         if(i == 6 && ans[6] == 445 && ans[5] == 445 && ans[4] == 445 && ans[3] == 445 && ans[2] == 445) printf("%d %d\n", ll, rr);
    }
}


#include<cstdio>
#include<iostream>
#include<string>
#include<vector>
#define MaxVal 100005
using namespace std;

typedef struct{
    int n, idx, r;
}line;

bool cmp1(line a, line b){ return a.n < b.n; }
bool cmp2(line a, line b){ return a.idx < b.idx; }

line h[MaxVal];
int h2[MaxVal];

int nn[MaxVal];
int pv[MaxVal];
int pvv[MaxVal];
int n2[MaxVal];
int ans[MaxVal];
//vector<int> adj[MaxVal];
vector<pair<int, int> > adj[MaxVal];

void update(int idx ,int val)
{
    while (idx <= MaxVal){
         h2[idx] += val;
         idx += (idx & -idx);
    }
}

int read(int idx)
{
    int sum = 0;
    while (idx > 0){
         sum += h2[idx];
         idx -= (idx & -idx);
    }
    return sum;
}

int main()
{
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
    int n, m;
    scanf("%d %d", &n, &m);
    for(int i = 1; i <= n; i++) { scanf("%d", &h[i].n); h[i].idx = i; }

    sort(h + 1, h + n + 1, cmp1);
    int t = 1;
    n2[t] = h[1].n;
    h[1].r = t;
    for(int i = 2; i <= n; i++) {
         if(h[i - 1].n != h[i].n) { t++; n2[t] = h[i].n; h[i].r = t; }
         else { h[i].r = t; }
    }
    sort(h + 1, h + n + 1, cmp2);
    //for(int i = 1; i <= n; i++) printf("%d ", h[i].r);

    for(int i = 0; i < m; i++) {
         int l, r;
         scanf("%d %d", &l, &r);
         //adj[r].push_back(l);
         adj[r].push_back(make_pair(l, i));
    }
    for(int i = 1; i <= n; i++) {
         nn[h[i].r]++;
         if(nn[h[i].r] == n2[h[i].r]) {
              update(i, 1);
              if(pv[h[i].r] != 0 && pvv[h[i].r] == 0) {
                   update(pv[h[i].r], -2);
                   pvv[h[i].r] = pv[h[i].r];
              }
              if(pv[h[i].r] != 0 && pvv[h[i].r] != 0) {
                   update(pv[h[i].r], -2);
                   update(pvv[h[i].r], 1);
                   pvv[h[i].r] = pv[h[i].r];
              }
              pv[h[i].r] = i;
              nn[h[i].r] = 0;
         }
         for(int j = 0; j < adj[i].size(); j++) {
              int a = read(i); int b = 0;
              if(adj[i][j].first > 1) b = read(adj[i][j].first - 1);
              ans[adj[i][j].second] = a - b;
         }
    }
    for(int i = 0; i < m; i++) printf("%d\n", ans[i]);
}


#include<cstdio>
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
#define MaxVal 200005
using namespace std;

typedef struct{
    int n, idx, r;
}line;

bool cmp1(line a, line b){ return a.n < b.n; }
bool cmp2(line a, line b){ return a.idx < b.idx; }

line h[MaxVal];
int h2[MaxVal];

int nn[MaxVal];
int nnl[MaxVal];
int pvl[MaxVal];
int pvvl[MaxVal];
int pvr[MaxVal];
int pvvr[MaxVal];
int n2[MaxVal];
int ans[MaxVal];
//vector<int> adj[MaxVal];
vector<pair<int, int> > adj[MaxVal];

void update(int idx ,int val)
{
    while (idx <= MaxVal){
         h2[idx] += val;
         idx += (idx & -idx);
    }
}

int read(int idx)
{
    int sum = 0;
    while (idx > 0){
         sum += h2[idx];
         idx -= (idx & -idx);
    }
    return sum;
}

int main()
{
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
    int n, m;
    scanf("%d %d", &n, &m);
    for(int i = 1; i <= n; i++) { scanf("%d", &h[i].n); h[i].idx = i; }

    sort(h + 1, h + n + 1, cmp1);
    int t = 1;
    n2[t] = h[1].n;
    h[1].r = t;
    for(int i = 2; i <= n; i++) {
         if(h[i - 1].n != h[i].n) { t++; n2[t] = h[i].n; h[i].r = t; }
         else { h[i].r = t; }
    }
    sort(h + 1, h + n + 1, cmp2);
    //for(int i = 1; i <= n; i++) printf("%d ", h[i].r);
    int ll, rr;
    for(int i = 0; i < m; i++) {
         int l, r;
         scanf("%d %d", &l, &r);
         int ll = l; rr = r;
         //adj[r].push_back(l);
         adj[r].push_back(make_pair(l, i));
    }
    for(int i = 1; i <= n; i++) {
         if(nn[h[i].r] == 0) { nnl[h[i].r] = i; }
         nn[h[i].r]++;
         if(nn[h[i].r] == n2[h[i].r]) {
              /*update(i, 1);
              if(pv[h[i].r] != 0 && pvv[h[i].r] == 0) {
                   update(pv[h[i].r], -2);
                   pvv[h[i].r] = pv[h[i].r];
              }
              else if(pv[h[i].r] != 0 && pvv[h[i].r] != 0) {
                   update(pv[h[i].r], -2);
                   update(pvv[h[i].r], 1);
                   pvv[h[i].r] = pv[h[i].r];
              }
              pv[h[i].r] = i;
              nn[h[i].r] = 0;*/
              update(nnl[h[i].r], 1);
              if(pvl[h[i].r] != 0 && pvvl[h[i].r] == 0) {
                   update(pvl[h[i].r], -1);
                   update(pvr[h[i].r], -1);
                   pvvl[h[i].r] = pvl[h[i].r];
                   pvvr[h[i].r] = pvr[h[i].r];
              }
              else if(pvl[h[i].r] != 0 && pvvl[h[i].r] != 0) {
                   update(pvl[h[i].r], -1);
                   update(pvr[h[i].r], -1);
                   update(pvvr[h[i].r], 1);
                   pvvl[h[i].r] = pvl[h[i].r];
                   pvvr[h[i].r] = pvr[h[i].r];
              }
              pvl[h[i].r] = nnl[h[i].r];
              pvr[h[i].r] = i;
              nn[h[i].r] = 0;
         }
         for(int j = 0; j < adj[i].size(); j++) {
              int a = read(i); int b = 0;
              if(adj[i][j].first > 1) b = read(adj[i][j].first - 1);
              ans[adj[i][j].second] = a - b;
         }
    }
    for(int i = 0; i < m; i++) { printf("%d\n", ans[i]);
         if(i == 6 && ans[6] == 445 && ans[5] == 445 && ans[4] == 445 && ans[3] == 445 && ans[2] == 445) printf("%d %d\n", ll, rr);
    }
}


#include<cstdio>
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
#define MaxVal 200005
using namespace std;

typedef struct{
    int n, idx, r;
}line;

bool cmp1(line a, line b){ return a.n < b.n; }
bool cmp2(line a, line b){ return a.idx < b.idx; }

line h[MaxVal];
int h2[MaxVal];

int nn[MaxVal];
int nnl[MaxVal];
int pvl[MaxVal];
int pvvl[MaxVal];
int pvr[MaxVal];
int pvvr[MaxVal];
int n2[MaxVal];
int ans[MaxVal];
//vector<int> adj[MaxVal];
vector<pair<int, int> > adj[MaxVal];

void update(int idx ,int val)
{
    while (idx <= MaxVal){
         h2[idx] += val;
         idx += (idx & -idx);
    }
}

int read(int idx)
{
    int sum = 0;
    while (idx > 0){
         sum += h2[idx];
         idx -= (idx & -idx);
    }
    return sum;
}

int main()
{
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
    int n, m;
    scanf("%d %d", &n, &m);
    for(int i = 1; i <= n; i++) { scanf("%d", &h[i].n); h[i].idx = i; }

    sort(h + 1, h + n + 1, cmp1);
    int t = 1;
    n2[t] = h[1].n;
    h[1].r = t;
    for(int i = 2; i <= n; i++) {
         if(h[i - 1].n != h[i].n) { t++; n2[t] = h[i].n; h[i].r = t; }
         else { h[i].r = t; }
    }
    sort(h + 1, h + n + 1, cmp2);
    //for(int i = 1; i <= n; i++) printf("%d ", h[i].r);

    for(int i = 0; i < m; i++) {
         int l, r;
         scanf("%d %d", &l, &r);
         //adj[r].push_back(l);
         adj[r].push_back(make_pair(l, i));
    }
    for(int i = 1; i <= n; i++) {
         if(nn[h[i].r] == 0) { nnl[h[i].r] = i; }
         nn[h[i].r]++;
         if(nn[h[i].r] == n2[h[i].r]) {
              /*update(i, 1);
              if(pv[h[i].r] != 0 && pvv[h[i].r] == 0) {
                   update(pv[h[i].r], -2);
                   pvv[h[i].r] = pv[h[i].r];
              }
              else if(pv[h[i].r] != 0 && pvv[h[i].r] != 0) {
                   update(pv[h[i].r], -2);
                   update(pvv[h[i].r], 1);
                   pvv[h[i].r] = pv[h[i].r];
              }
              pv[h[i].r] = i;
              nn[h[i].r] = 0;*/
              update(nnl[h[i].r], 1);
              if(pvl[h[i].r] != 0 && pvvl[h[i].r] == 0) {
                   update(pvl[h[i].r], -1);
                   update(pvr[h[i].r], -1);
                   pvvl[h[i].r] = pvl[h[i].r];
                   pvvr[h[i].r] = pvr[h[i].r];
              }
              else if(pvl[h[i].r] != 0 && pvvl[h[i].r] != 0) {
                   update(pvl[h[i].r], -1);
                   update(pvr[h[i].r], -1);
                   update(pvvr[h[i].r], 1);
                   pvvl[h[i].r] = pvl[h[i].r];
                   pvvr[h[i].r] = pvr[h[i].r];
              }
              pvl[h[i].r] = nnl[h[i].r];
              pvr[h[i].r] = i;
              nn[h[i].r] = 0;
         }
         for(int j = 0; j < adj[i].size(); j++) {
              int a = read(i); int b = 0;
              if(adj[i][j].first > 1) b = read(adj[i][j].first - 1);
              ans[adj[i][j].second] = a - b;
         }
    }
    for(int i = 0; i < m; i++) printf("%d\n", ans[i]);
}


#include<cstdio>
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
#define MaxVal 200005
using namespace std;

typedef struct{
    int n, idx, r;
}line;

bool cmp1(line a, line b){ return a.n < b.n; }
bool cmp2(line a, line b){ return a.idx < b.idx; }

line h[MaxVal];
int h2[MaxVal];

int nn[MaxVal];
int pv[MaxVal];
int pvv[MaxVal];
int n2[MaxVal];
int ans[MaxVal];
//vector<int> adj[MaxVal];
vector<pair<int, int> > adj[MaxVal];

void update(int idx ,int val)
{
    while (idx <= MaxVal){
         h2[idx] += val;
         idx += (idx & -idx);
    }
}

int read(int idx)
{
    int sum = 0;
    while (idx > 0){
         sum += h2[idx];
         idx -= (idx & -idx);
    }
    return sum;
}

int main()
{
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
    int n, m;
    scanf("%d %d", &n, &m);
    for(int i = 1; i <= n; i++) { scanf("%d", &h[i].n); h[i].idx = i; }

    sort(h + 1, h + n + 1, cmp1);
    int t = 1;
    n2[t] = h[1].n;
    h[1].r = t;
    for(int i = 2; i <= n; i++) {
         if(h[i - 1].n != h[i].n) { t++; n2[t] = h[i].n; h[i].r = t; }
         else { h[i].r = t; }
    }
    sort(h + 1, h + n + 1, cmp2);
    //for(int i = 1; i <= n; i++) printf("%d ", h[i].r);

    for(int i = 0; i < m; i++) {
         int l, r;
         scanf("%d %d", &l, &r);
         //adj[r].push_back(l);
         adj[r].push_back(make_pair(l, i));
    }
    for(int i = 1; i <= n; i++) {
         nn[h[i].r]++;
         if(nn[h[i].r] == n2[h[i].r]) {
              update(i, 1);
              if(pv[h[i].r] != 0 && pvv[h[i].r] == 0) {
                   update(pv[h[i].r], -2);
                   pvv[h[i].r] = pv[h[i].r];
              }
              else if(pv[h[i].r] != 0 && pvv[h[i].r] != 0) {
                   update(pv[h[i].r], -2);
                   update(pvv[h[i].r], 1);
                   pvv[h[i].r] = pv[h[i].r];
              }
              pv[h[i].r] = i;
              nn[h[i].r] = 0;
         }
         for(int j = 0; j < adj[i].size(); j++) {
              int a = read(i); int b = 0;
              if(adj[i][j].first > 1) b = read(adj[i][j].first - 1);
              ans[adj[i][j].second] = a - b;
         }
    }
    for(int i = 0; i < m; i++) printf("%d\n", ans[i]);
}


#include<cstdio>
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
#define MaxVal 100005
using namespace std;

typedef struct{
    int n, idx, r;
}line;

bool cmp1(line a, line b){ return a.n < b.n; }
bool cmp2(line a, line b){ return a.idx < b.idx; }

line h[MaxVal];
int h2[MaxVal];

int nn[MaxVal];
int pv[MaxVal];
int pvv[MaxVal];
int n2[MaxVal];
int ans[MaxVal];
//vector<int> adj[MaxVal];
vector<pair<int, int> > adj[MaxVal];

void update(int idx ,int val)
{
    while (idx <= MaxVal){
         h2[idx] += val;
         idx += (idx & -idx);
    }
}

int read(int idx)
{
    int sum = 0;
    while (idx > 0){
         sum += h2[idx];
         idx -= (idx & -idx);
    }
    return sum;
}

int main()
{
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
    int n, m;
    scanf("%d %d", &n, &m);
    for(int i = 1; i <= n; i++) { scanf("%d", &h[i].n); h[i].idx = i; }

    sort(h + 1, h + n + 1, cmp1);
    int t = 1;
    n2[t] = h[1].n;
    h[1].r = t;
    for(int i = 2; i <= n; i++) {
         if(h[i - 1].n != h[i].n) { t++; n2[t] = h[i].n; h[i].r = t; }
         else { h[i].r = t; }
    }
    sort(h + 1, h + n + 1, cmp2);
    //for(int i = 1; i <= n; i++) printf("%d ", h[i].r);

    for(int i = 0; i < m; i++) {
         int l, r;
         scanf("%d %d", &l, &r);
         //adj[r].push_back(l);
         adj[r].push_back(make_pair(l, i));
    }
    for(int i = 1; i <= n; i++) {
         nn[h[i].r]++;
         if(nn[h[i].r] == n2[h[i].r]) {
              update(i, 1);
              if(pv[h[i].r] != 0 && pvv[h[i].r] == 0) {
                   update(pv[h[i].r], -2);
                   pvv[h[i].r] = pv[h[i].r];
              }
              if(pv[h[i].r] != 0 && pvv[h[i].r] != 0) {
                   update(pv[h[i].r], -2);
                   update(pvv[h[i].r], 1);
                   pvv[h[i].r] = pv[h[i].r];
              }
              pv[h[i].r] = i;
              nn[h[i].r] = 0;
         }
         for(int j = 0; j < adj[i].size(); j++) {
              int a = read(i); int b = 0;
              if(adj[i][j].first > 1) b = read(adj[i][j].first - 1);
              ans[adj[i][j].second] = a - b;
         }
    }
    for(int i = 0; i < m; i++) printf("%d\n", ans[i]);
}


#include<cstdio>
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
#define MaxVal 200005
using namespace std;

typedef struct{
    int n, idx, r;
}line;

bool cmp1(line a, line b){ return a.n < b.n; }
bool cmp2(line a, line b){ return a.idx < b.idx; }

line h[MaxVal];
int h2[MaxVal];

int nn[MaxVal];
int p[MaxVal];
int pv[MaxVal];
int pvv[MaxVal];
int n2[MaxVal];
int ans[MaxVal];
vector<pair<int, int> > adj[MaxVal];
vector<int> adj2[MaxVal];

void update(int idx ,int val)
{
    while (idx <= MaxVal){
         h2[idx] += val;
         idx += (idx & -idx);
    }
}

int read(int idx)
{
    int sum = 0;
    while (idx > 0){
         sum += h2[idx];
         idx -= (idx & -idx);
    }
    return sum;
}

int main()
{
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
    int n, m;
    scanf("%d %d", &n, &m);
    for(int i = 1; i <= n; i++) { scanf("%d", &h[i].n); h[i].idx = i; }

    sort(h + 1, h + n + 1, cmp1);
    int t = 1;
    n2[t] = h[1].n;
    h[1].r = t;
    for(int i = 2; i <= n; i++) {
         if(h[i - 1].n != h[i].n) { t++; n2[t] = h[i].n; h[i].r = t; }
         else { h[i].r = t; }
    }
    sort(h + 1, h + n + 1, cmp2);
    for(int i = 1; i <= n; i++) adj2[h[i].r].push_back(i);
    for(int i = 0; i < m; i++) {
         int l, r;
         scanf("%d %d", &l, &r);
         adj[r].push_back(make_pair(l, i));
    }
    for(int i = 1; i <= n; i++) {
         /*if(nn[h[i].r] == 0) { p[h[i].r] = i; }
         else if(nn[h[i].r] == 1) { pv[h[i].r] = i; }
         else if(nn[h[i].r] == 2) { pvv[h[i].r] = i; }*/

         nn[h[i].r]++;
         if(nn[h[i].r] == n2[h[i].r]) {
              update(adj2[h[i].r][nn[h[i].r] - n2[h[i].r]], 1);
              //pv[h[i].r] = p[h[i].r];
              //p[h[i].r] = ;
         }
         else if(nn[h[i].r] == n2[h[i].r] + 1) {
              /*update(p[h[i].r], 1);
              update(pv[h[i].r], -2);
              pvv[h[i].r] = pv[h[i].r];
              pv[h[i].r] = p[h[i].r];*/
              update(adj2[h[i].r][nn[h[i].r] - n2[h[i].r]], 1);
              update(adj2[h[i].r][nn[h[i].r] - n2[h[i].r] - 1], -2);
         }
         else if(nn[h[i].r] > n2[h[i].r] + 1) {
              update(adj2[h[i].r][nn[h[i].r] - n2[h[i].r]], 1);
              update(adj2[h[i].r][nn[h[i].r] - n2[h[i].r] - 1], -2);
              update(adj2[h[i].r][nn[h[i].r] - n2[h[i].r] - 2], 1);
         }

         for(int j = 0; j < adj[i].size(); j++) {
              int a = read(i); int b = 0;
              if(adj[i][j].first > 1) b = read(adj[i][j].first - 1);
              ans[adj[i][j].second] = a - b;
         }
    }
    for(int i = 0; i < m; i++) printf("%d\n", ans[i]);
}


#include<cstdio>
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
#define MaxVal 200005
using namespace std;

typedef struct{
    int n, idx, r;
}line;

bool cmp1(line a, line b){ return a.n < b.n; }
bool cmp2(line a, line b){ return a.idx < b.idx; }

line h[MaxVal];
int h2[MaxVal];

int nn[MaxVal];
int pv[MaxVal];
int pvv[MaxVal];
int n2[MaxVal];
int ans[MaxVal];
//vector<int> adj[MaxVal];
vector<pair<int, int> > adj[MaxVal];

void update(int idx ,int val)
{
    while (idx <= MaxVal){
         h2[idx] += val;
         idx += (idx & -idx);
    }
}

int read(int idx)
{
    int sum = 0;
    while (idx > 0){
         sum += h2[idx];
         idx -= (idx & -idx);
    }
    return sum;
}

int main()
{
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
    int n, m;
    scanf("%d %d", &n, &m);
    for(int i = 1; i <= n; i++) { scanf("%d", &h[i].n); h[i].idx = i; }

    sort(h + 1, h + n + 1, cmp1);
    int t = 1;
    n2[t] = h[1].n;
    h[1].r = t;
    for(int i = 2; i <= n; i++) {
         if(h[i - 1].n != h[i].n) { t++; n2[t] = h[i].n; h[i].r = t; }
         else { h[i].r = t; }
    }
    sort(h + 1, h + n + 1, cmp2);
    //for(int i = 1; i <= n; i++) printf("%d ", h[i].r);

    for(int i = 0; i < m; i++) {
         int l, r;
         scanf("%d %d", &l, &r);
         //adj[r].push_back(l);
         adj[r].push_back(make_pair(l, i));
    }
    for(int i = 1; i <= n; i++) {
         nn[h[i].r]++;
         if(nn[h[i].r] == n2[h[i].r]) {
              update(i, 1);
              if(pv[h[i].r] != 0 && pvv[h[i].r] == 0) {
                   update(pv[h[i].r], -2);
                   pvv[h[i].r] = pv[h[i].r];
              }
              if(pv[h[i].r] != 0 && pvv[h[i].r] != 0) {
                   update(pv[h[i].r], -2);
                   update(pvv[h[i].r], 1);
                   pvv[h[i].r] = pv[h[i].r];
              }
              pv[h[i].r] = i;
              nn[h[i].r] = 0;
         }
         for(int j = 0; j < adj[i].size(); j++) {
              int a = read(i); int b = 0;
              if(adj[i][j].first > 1) b = read(adj[i][j].first - 1);
              ans[adj[i][j].second] = a - b;
         }
    }
    for(int i = 0; i < m; i++) printf("%d\n", ans[i]);
}


#include<cstdio>
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
#define MaxVal 200005
using namespace std;

typedef struct{
    int n, idx, r;
}line;

bool cmp1(line a, line b){ return a.n < b.n; }
bool cmp2(line a, line b){ return a.idx < b.idx; }

line h[MaxVal];
int h2[MaxVal];

int nn[MaxVal];
int nnl[MaxVal];
int pvl[MaxVal];
int pvvl[MaxVal];
int pvr[MaxVal];
int pvvr[MaxVal];
int n2[MaxVal];
int ans[MaxVal];
//vector<int> adj[MaxVal];
vector<pair<int, int> > adj[MaxVal];

void update(int idx ,int val)
{
    while (idx <= MaxVal){
         h2[idx] += val;
         idx += (idx & -idx);
    }
}

int read(int idx)
{
    int sum = 0;
    while (idx > 0){
         sum += h2[idx];
         idx -= (idx & -idx);
    }
    return sum;
}

int main()
{
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
    int n, m;
    scanf("%d %d", &n, &m);
    for(int i = 1; i <= n; i++) { scanf("%d", &h[i].n); h[i].idx = i; }

    sort(h + 1, h + n + 1, cmp1);
    int t = 1;
    n2[t] = h[1].n;
    h[1].r = t;
    for(int i = 2; i <= n; i++) {
         if(h[i - 1].n != h[i].n) { t++; n2[t] = h[i].n; h[i].r = t; }
         else { h[i].r = t; }
    }
    sort(h + 1, h + n + 1, cmp2);
    //for(int i = 1; i <= n; i++) printf("%d ", h[i].r);
    int ll, rr;
    for(int i = 0; i < m; i++) {
         int l, r;
         scanf("%d %d", &l, &r);
         if(i == 6) ll = l; rr = r;
         //adj[r].push_back(l);
         adj[r].push_back(make_pair(l, i));
    }
    for(int i = 1; i <= n; i++) {
         if(nn[h[i].r] == 0) { nnl[h[i].r] = i; }
         nn[h[i].r]++;
         if(nn[h[i].r] == n2[h[i].r]) {
              /*update(i, 1);
              if(pv[h[i].r] != 0 && pvv[h[i].r] == 0) {
                   update(pv[h[i].r], -2);
                   pvv[h[i].r] = pv[h[i].r];
              }
              else if(pv[h[i].r] != 0 && pvv[h[i].r] != 0) {
                   update(pv[h[i].r], -2);
                   update(pvv[h[i].r], 1);
                   pvv[h[i].r] = pv[h[i].r];
              }
              pv[h[i].r] = i;
              nn[h[i].r] = 0;*/
              update(nnl[h[i].r], 1);
              if(pvl[h[i].r] != 0 && pvvl[h[i].r] == 0) {
                   update(pvl[h[i].r], -1);
                   update(pvr[h[i].r], -1);
                   pvvl[h[i].r] = pvl[h[i].r];
                   pvvr[h[i].r] = pvr[h[i].r];
              }
              else if(pvl[h[i].r] != 0 && pvvl[h[i].r] != 0) {
                   update(pvl[h[i].r], -1);
                   update(pvr[h[i].r], -1);
                   update(pvvr[h[i].r], 1);
                   pvvl[h[i].r] = pvl[h[i].r];
                   pvvr[h[i].r] = pvr[h[i].r];
              }
              pvl[h[i].r] = nnl[h[i].r];
              pvr[h[i].r] = i;
              nn[h[i].r] = 0;
         }
         for(int j = 0; j < adj[i].size(); j++) {
              int a = read(i); int b = 0;
              if(adj[i][j].first > 1) b = read(adj[i][j].first - 1);
              ans[adj[i][j].second] = a - b;
         }
    }
    for(int i = 0; i < m; i++) { printf("%d\n", ans[i]);
         if(i == 6 && ans[6] == 445 && ans[5] == 445 && ans[4] == 445 && ans[3] == 445 && ans[2] == 445) printf("%d %d\n", ll, rr);
    }
}


#include<cstdio>
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
#define MaxVal 200005
using namespace std;

typedef struct{
    int n, idx, r;
}line;

bool cmp1(line a, line b){ return a.n < b.n; }
bool cmp2(line a, line b){ return a.idx < b.idx; }

line h[MaxVal];
int h2[MaxVal];

int nn[MaxVal];
int nnl[MaxVal];
int pvl[MaxVal];
int pvvl[MaxVal];
int pvr[MaxVal];
int pvvr[MaxVal];
int n2[MaxVal];
int ans[MaxVal];
//vector<int> adj[MaxVal];
vector<pair<int, int> > adj[MaxVal];

void update(int idx ,int val)
{
    while (idx <= MaxVal){
         h2[idx] += val;
         idx += (idx & -idx);
    }
}

int read(int idx)
{
    int sum = 0;
    while (idx > 0){
         sum += h2[idx];
         idx -= (idx & -idx);
    }
    return sum;
}

int main()
{
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
    int n, m;
    scanf("%d %d", &n, &m);
    for(int i = 1; i <= n; i++) { scanf("%d", &h[i].n); h[i].idx = i; }

    sort(h + 1, h + n + 1, cmp1);
    int t = 1;
    n2[t] = h[1].n;
    h[1].r = t;
    for(int i = 2; i <= n; i++) {
         if(h[i - 1].n != h[i].n) { t++; n2[t] = h[i].n; h[i].r = t; }
         else { h[i].r = t; }
    }
    sort(h + 1, h + n + 1, cmp2);
    //for(int i = 1; i <= n; i++) printf("%d ", h[i].r);
    int ll, rr;
    for(int i = 0; i < m; i++) {
         int l, r;
         scanf("%d %d", &l, &r);
         int ll = l; rr = r;
         //adj[r].push_back(l);
         adj[r].push_back(make_pair(l, i));
    }
    for(int i = 1; i <= n; i++) {
         if(nn[h[i].r] == 0) { nnl[h[i].r] = i; }
         nn[h[i].r]++;
         if(nn[h[i].r] == n2[h[i].r]) {
              /*update(i, 1);
              if(pv[h[i].r] != 0 && pvv[h[i].r] == 0) {
                   update(pv[h[i].r], -2);
                   pvv[h[i].r] = pv[h[i].r];
              }
              else if(pv[h[i].r] != 0 && pvv[h[i].r] != 0) {
                   update(pv[h[i].r], -2);
                   update(pvv[h[i].r], 1);
                   pvv[h[i].r] = pv[h[i].r];
              }
              pv[h[i].r] = i;
              nn[h[i].r] = 0;*/
              update(nnl[h[i].r], 1);
              if(pvl[h[i].r] != 0 && pvvl[h[i].r] == 0) {
                   update(pvl[h[i].r], -1);
                   update(pvr[h[i].r], -1);
                   pvvl[h[i].r] = pvl[h[i].r];
                   pvvr[h[i].r] = pvr[h[i].r];
              }
              else if(pvl[h[i].r] != 0 && pvvl[h[i].r] != 0) {
                   update(pvl[h[i].r], -1);
                   update(pvr[h[i].r], -1);
                   update(pvvr[h[i].r], 1);
                   pvvl[h[i].r] = pvl[h[i].r];
                   pvvr[h[i].r] = pvr[h[i].r];
              }
              pvl[h[i].r] = nnl[h[i].r];
              pvr[h[i].r] = i;
              nn[h[i].r] = 0;
         }
         for(int j = 0; j < adj[i].size(); j++) {
              int a = read(i); int b = 0;
              if(adj[i][j].first > 1) b = read(adj[i][j].first - 1);
              ans[adj[i][j].second] = a - b;
         }
    }
    for(int i = 0; i < m; i++) { printf("%d\n", ans[i]);
         if(ans[i] == 445) printf("%d %d\n", ll, rr);
    }
}


#include <stdio.h>
#include <map>
#include <memory.h>
using namespace std;
int n, m, a[100006], *cnt[100006];
map<int, int> db;
int main( int argc, char *argv[] )
{
    int i;
    scanf( "%d%d", &n, &m );
    for ( i = 1; i <= n; ++i ) scanf( "%d", a + i );
    map<int, int>::iterator it, it1;
    for ( i = 1; i <= n; ++i ) {
        it = db.find( a[i] );
        if ( it == db.end() ) {
            db.insert( pair<int, int>( a[i], 1 ) );
        }
        else {
            ++(it->second);
        }
    }
    for ( it = db.begin(); it != db.end(); ) {
        if ( it->first > it->second ) {
            it1 = it;
            ++it;
            db.erase( it1 );
        }
        else {
            ++it;
        }
    }
    memset( cnt, 0, sizeof( cnt ) );
    for ( it = db.begin(); it != db.end(); ++it ) {
        cnt[it->first] = new int[n+1];
        cnt[it->first][0] = 0;
    }
    for ( i = 1; i <= n; ++i ) {
        if ( db.find(a[i]) != db.end() ) {
            //printf( "%d   +++\n", a[i] );
            cnt[a[i]][i] = cnt[a[i]][i-1] + 1;
            for ( it = db.begin(); it != db.end(); ++it ) {
                if ( it->first == a[i] ) continue;
                cnt[it->first][i] = cnt[it->first][i-1];
            }
        }
        else {
            for ( it = db.begin(); it != db.end(); ++it ) {
                cnt[it->first][i] = cnt[it->first][i-1];
            }
        }
    }
    /*for ( it = db.begin(); it != db.end(); ++it ) {
        printf( "%d : ", it->first );
        for ( i = 1; i <= n; ++i ) {
            printf( "%d ", cnt[it->first][i] );
        }
        putchar( '\n' );
    }*/
    int re, l, r;
    while ( m-- ) {
        scanf( "%d%d", &l, &r );
        re = 0;
        for ( it = db.begin(); it != db.end(); ++it ) {
            //printf( "%d  %d  ***\n",
                     //it->first, cnt[it->first][r] - cnt[it->first][l-1] );
            if ( (cnt[it->first][r] - cnt[it->first][l-1]) == it->first ) {
                ++re;
            }
        }
        printf( "%d\n", re );
    }
    return 0;
}


#include <stdio.h>
#include <map>
#include <memory.h>
using namespace std;
int n, m, a[100006], *cnt[100006], val[500];
int lo[100006], ro[100006], ans[100006];
map<int, int> db;
int main( int argc, char *argv[] )
{
    int i;
    scanf( "%d%d", &n, &m );
    for ( i = 1; i <= n; ++i ) scanf( "%d", a + i );
    map<int, int>::iterator it;
    for ( i = 1; i <= n; ++i ) {
        it = db.find( a[i] );
        if ( it == db.end() ) {
            db.insert( pair<int, int>( a[i], 1 ) );
        }
        else {
            ++(it->second);
        }
    }
    int k = 0;
    for ( it = db.begin(); it != db.end(); ++it ) {
        if ( it->first <= it->second ) {
            val[k++] = it->first;
        }
    }
    memset( cnt, 0, sizeof( cnt ) );
    for ( i = 0; i < k; ++i ) {
        cnt[val[i]] = new int[n+1];
        cnt[val[i]][0] = 0;
    }
    int j;
    //puts( "*********");
    for ( j = 0; j < k; ++j ) {
        for ( i = 1; i <= n; ++i ) {
            if ( val[j] == a[i] ) cnt[a[i]][i] = cnt[a[i]][i-1] + 1;
            else cnt[val[j]][i] = cnt[val[j]][i-1];
        }
    }
    int re, l, r;
    while ( m-- ) {
        scanf( "%d%d", &l, &r );
        re = 0;
        for ( j = 0; j < k; ++j ) {
            if ( (cnt[val[j]][r] - cnt[val[j]][l-1]) == val[j] ) {
                ++re;
            }
        }
        printf( "%d\n", re );
    }
    return 0;
}


#include <stdio.h>
#include <map>
#include <memory.h>
using namespace std;
int n, m, a[100006], *cnt[100006], val[500];
int lo[100006], ro[100006], ans[100006];
map<int, int> db;
int main( int argc, char *argv[] )
{
    int i;
    scanf( "%d%d", &n, &m );
    for ( i = 1; i <= n; ++i ) scanf( "%d", a + i );
    map<int, int>::iterator it;
    for ( i = 1; i <= n; ++i ) {
        it = db.find( a[i] );
        if ( it == db.end() ) {
            db.insert( pair<int, int>( a[i], 1 ) );
        }
        else {
            ++(it->second);
        }
    }
    int k = 0;
    for ( it = db.begin(); it != db.end(); ++it ) {
        if ( it->first <= it->second ) {
            val[k++] = it->first;
        }
    }
    memset( cnt, 0, sizeof( cnt ) );
    for ( i = 0; i < k; ++i ) {
        cnt[val[i]] = new int[n+1];
        cnt[val[i]][0] = 0;
    }
    int j;
    //puts( "*********");
    for ( i = 0; i < m; ++i ) {
        scanf( "%d%d", lo + i, ro + i );
    }
    memset( ans, 0, sizeof( ans ) );
    for ( j = 0; j < k; ++j ) {
        for ( i = 1; i <= n; ++i ) {
            if ( val[j] == a[i] ) cnt[a[i]][i] = cnt[a[i]][i-1] + 1;
            else cnt[val[j]][i] = cnt[val[j]][i-1];
        }
        for ( i = 0; i < m; ++i ) {
            if ( (cnt[val[j]][ro[i]] - cnt[val[j]][lo[i]-1]) == val[j] ) {
                ++ans[i];
            }
        }
    }
    for ( j = 0; j < m; ++j ) {
        printf( "%d\n", ans[j] );
    }
    /*while ( m-- ) {
        scanf( "%d%d", &l, &r );
        re = 0;
        for ( j = 0; j < k; ++j ) {
            if ( (cnt[val[j]][r] - cnt[val[j]][l-1]) == val[j] ) {
                ++re;
            }
        }
        printf( "%d\n", re );
    }*/
    return 0;
}


#include <stdio.h>
#include <map>
#include <memory.h>
using namespace std;
int n, m, a[100006], *cnt[100006], val[500];
int lo[100006], ro[100006], ans[100006];
map<int, int> db;
int main( int argc, char *argv[] )
{
    int i;
    scanf( "%d%d", &n, &m );
    for ( i = 1; i <= n; ++i ) scanf( "%d", a + i );
    map<int, int>::iterator it, it1;
    for ( i = 1; i <= n; ++i ) {
        it = db.find( a[i] );
        if ( it == db.end() ) {
            db.insert( pair<int, int>( a[i], 1 ) );
        }
        else {
            ++(it->second);
        }
    }
    int k = 0;
    for ( it = db.begin(); it != db.end(); ) {
        if ( it->first <= it->second ) {
            val[k++] = it->first;
        }
    }
    memset( cnt, 0, sizeof( cnt ) );
    for ( i = 0; i < k; ++i ) {
        cnt[val[i]] = new int[n+1];
        cnt[val[i]][0] = 0;
    }
    for ( i = 0; i < k; ++i ) {
        for ( i = 1; i <= n; ++i ) {
            if ( val[i] == a[i] ) cnt[a[i]][i] = cnt[a[i]][i-1] + 1;
            else cnt[val[i]][i] = cnt[val[i]][i-1];
        }
    }
    int re, l, r;
    while ( m-- ) {
        scanf( "%d%d", &l, &r );
        re = 0;
        for ( i = 0; i < k; ++i ) {
            if ( (cnt[val[i]][r] - cnt[val[i]][l-1]) == val[i] ) {
                ++re;
            }
        }
        printf( "%d\n", re );
    }
    return 0;
}


#include <stdio.h>
#include <map>
#include <memory.h>
using namespace std;
int n, m, a[100006], *cnt[100006];
map<int, int> db;
int main( int argc, char *argv[] )
{
    int i;
    scanf( "%d%d", &n, &m );
    for ( i = 1; i <= n; ++i ) scanf( "%d", a + i );
    map<int, int>::iterator it, it1;
    for ( i = 1; i <= n; ++i ) {
        it = db.find( a[i] );
        if ( it == db.end() ) {
            db.insert( pair<int, int>( a[i], 1 ) );
        }
        else {
            ++(it->second);
        }
    }
    for ( it = db.begin(); it != db.end(); ) {
        if ( it->first > it->second ) {
            it1 = it;
            ++it;
            db.erase( it1 );
        }
        else {
            ++it;
        }
    }
    memset( cnt, 0, sizeof( cnt ) );
    for ( it = db.begin(); it != db.end(); ++it ) {
        cnt[it->first] = new int[n+1];
        cnt[it->first][0] = 0;
    }
    for ( it = db.begin(); it != db.end(); ++it ) {
        for ( i = 1; i <= n; ++i ) {
            if ( it->first == a[i] ) cnt[a[i]][i] = cnt[a[i]][i-1] + 1;
            else cnt[it->first][i] = cnt[it->first][i-1];
        }
    }
    int re, l, r;
    while ( m-- ) {
        scanf( "%d%d", &l, &r );
        re = 0;
        for ( it = db.begin(); it != db.end(); ++it ) {
            if ( (cnt[it->first][r] - cnt[it->first][l-1]) == it->first ) {
                ++re;
            }
        }
        printf( "%d\n", re );
    }
    return 0;
}


#include <stdio.h>
#include <map>
#include <memory.h>
using namespace std;
int n, m, a[100006], cnt[100006], val[500];
int lo[100006], ro[100006], ans[100006];
map<int, int> db;
int main( int argc, char *argv[] )
{
    int i;
    scanf( "%d%d", &n, &m );
    for ( i = 1; i <= n; ++i ) scanf( "%d", a + i );
    map<int, int>::iterator it;
    for ( i = 1; i <= n; ++i ) {
        it = db.find( a[i] );
        if ( it == db.end() ) {
            db.insert( pair<int, int>( a[i], 1 ) );
        }
        else {
            ++(it->second);
        }
    }
    int k = 0;
    for ( it = db.begin(); it != db.end(); ++it ) {
        if ( it->first <= it->second ) {
            val[k++] = it->first;
        }
    }
    int j;
    for ( i = 0; i < m; ++i ) {
        scanf( "%d%d", lo + i, ro + i );
    }
    memset( ans, 0, sizeof( ans ) );
    for ( j = 0; j < k; ++j ) {
        memset( cnt, 0, (n+1)<<2 );
        for ( i = 1; i <= n; ++i ) {
            if ( val[j] == a[i] ) cnt[i] = cnt[i-1] + 1;
            else cnt[i] = cnt[i-1];
        }
        for ( i = 0; i < m; ++i ) {
            if ( (cnt[ro[i]] - cnt[lo[i]-1]) == val[j] ) {
                ++ans[i];
            }
        }
    }
    for ( j = 0; j < m; ++j ) {
        printf( "%d\n", ans[j] );
    }
    return 0;
}


#include <iostream>
#include <fstream>
#include <stdio.h>
#include <algorithm>
#include <set>
#include <vector>
#include <map>
#include <queue>
#include <list>
#include <math.h>
#include <string>
#include <stdlib.h>
#include <string.h>

#define sqr(a) ((a)*(a))
#define odd(a) ((a)&1)
#define foru(i,n) for (int i=0;i<(n);i++)
#define ford(i,n) for (int i=(n)-1;i>=0;i--)
#define forab(i,l,r) for (int i=(l);i<=(r);i++)
#define forabd(i,r,l) for (int i=(r);i>=(l);i--)
#define pb push_back
#define F first
#define S second
#define all(x) x.begin(),x.end()
#define sz(__X) (int)__X.size()
#define pii pair<int,int>

const double eps=1e-20;
const double PI=acos(-1.0);
const int INF=1000*1000*1000+7;
const int MAXN = 100500;
const int MAXM = 505;

using namespace std;

int N,M, k;
int a[MAXN], kol[MAXN];
int b[MAXM], s[MAXN][MAXM];

int main()
{
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
    scanf("%d %d", &N, &M);
    for (int i=1; i<=N; i++)
    {
        scanf("%d", &a[i]);
        if (a[i]<=N && ++kol[a[i]]==a[i]) b[k++]=a[i];
    }
    for (int j=0; j<k; j++)
    {
        for (int i=1; i<=N; i++)
        {
            s[i][j] = s[i-1][j]+(b[j]==a[i]);
        }
    }
    for (int lp=0; lp<M; lp++)
    {
        int l,r;
        scanf("%d %d", &l, &r);
        l--; r--;
        int ans=0;
        for (int j=0; j<k; j++)
            ans += (s[r][j] - s[l-1][j] )== b[j];
        printf("%d\n", ans);
    }
    return 0;
}


#include <iostream>
#include <fstream>
#include <stdio.h>
#include <algorithm>
#include <set>
#include <vector>
#include <map>
#include <queue>
#include <list>
#include <math.h>
#include <string>
#include <stdlib.h>
#include <string.h>

#define sqr(a) ((a)*(a))
#define odd(a) ((a)&1)
#define foru(i,n) for (int i=0;i<(n);i++)
#define ford(i,n) for (int i=(n)-1;i>=0;i--)
#define forab(i,l,r) for (int i=(l);i<=(r);i++)
#define forabd(i,r,l) for (int i=(r);i>=(l);i--)
#define pb push_back
#define F first
#define S second
#define all(x) x.begin(),x.end()
#define sz(__X) (int)__X.size()
#define pii pair<int,int>

const double eps=1e-20;
const double PI=acos(-1.0);
const int INF=1000*1000*1000+7;
const int MAXN = 100500;
const int MAXM = 800;

using namespace std;

int N,M, k;
int a[MAXN], kol[MAXN];
int b[MAXM], s[MAXN][MAXM];

int main()
{
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
    scanf("%d %d", &N, &M);
    for (int i=1; i<=N; i++)
    {
        scanf("%d", &a[i]);
        if (a[i]<=N && ++kol[a[i]]==a[i]) b[k++]=a[i];
    }
    for (int j=0; j<k; j++)
    {
        for (int i=1; i<=N; i++)
        {
            s[i][j] = s[i-1][j]+(b[j]==a[i]);
        }
    }
    for (int lp=0; lp<M; lp++)
    {
        int l,r;
        scanf("%d %d", &l, &r);
        int ans=0;
        for (int j=0; j<k; j++)
            ans += (s[r][j] - s[l-1][j] )== b[j];
        printf("%d\n", ans);
    }
    return 0;
}


#include <iostream>
#include <fstream>
#include <stdio.h>
#include <algorithm>
#include <set>
#include <vector>
#include <map>
#include <queue>
#include <list>
#include <math.h>
#include <string>
#include <stdlib.h>
#include <string.h>

#define sqr(a) ((a)*(a))
#define odd(a) ((a)&1)
#define foru(i,n) for (int i=0;i<(n);i++)
#define ford(i,n) for (int i=(n)-1;i>=0;i--)
#define forab(i,l,r) for (int i=(l);i<=(r);i++)
#define forabd(i,r,l) for (int i=(r);i>=(l);i--)
#define pb push_back
#define F first
#define S second
#define all(x) x.begin(),x.end()
#define sz(__X) (int)__X.size()
#define pii pair<int,int>

const double eps=1e-20;
const double PI=acos(-1.0);
const int INF=1000*1000*1000+7;
const int MAXN = 100500;
const int MAXM = 505;

using namespace std;

int N,M, k;
int a[MAXN], kol[MAXN];
int b[MAXM], s[MAXN][MAXM];

int main()
{
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
    scanf("%d %d", &N, &M);
    for (int i=1; i<=N; i++)
    {
        scanf("%d", &a[i]);
        if (a[i]<=N && ++kol[a[i]]==a[i]) b[k++]=a[i];
    }
    for (int j=0; j<k; j++)
    {
        for (int i=1; i<=N; i++)
        {
            s[i][j] = s[i-1][j]+(b[j]==a[i]);
        }
    }
    for (int lp=0; lp<M; lp++)
    {
        int l,r;
        scanf("%d %d", &l, &r);
        int ans=0;
        for (int j=0; j<k; j++)
            ans += (s[r][j] - s[l-1][j] )== b[j];
        printf("%d\n", ans);
    }
    return 0;
}


#include <iostream>
#include <fstream>
#include <stdio.h>
#include <algorithm>
#include <set>
#include <vector>
#include <map>
#include <queue>
#include <list>
#include <math.h>
#include <string>
#include <stdlib.h>
#include <string.h>

#define sqr(a) ((a)*(a))
#define odd(a) ((a)&1)
#define foru(i,n) for (int i=0;i<(n);i++)
#define ford(i,n) for (int i=(n)-1;i>=0;i--)
#define forab(i,l,r) for (int i=(l);i<=(r);i++)
#define forabd(i,r,l) for (int i=(r);i>=(l);i--)
#define pb push_back
#define F first
#define S second
#define all(x) x.begin(),x.end()
#define sz(__X) (int)__X.size()
#define pii pair<int,int>

const double eps=1e-20;
const double PI=acos(-1.0);
const int INF=1000*1000*1000+7;
const int MAXN = 100500;
const int MAXM = 600;

using namespace std;

int N,M, k;
int a[MAXN], kol[MAXN];
int b[MAXM], s[MAXN][MAXM];

int main()
{
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
    scanf("%d %d", &N, &M);
    k=0;
    for (int i=1; i<=N; i++)
    {
        scanf("%d", &a[i]);
        if ( (a[i]<=N) && (++kol[a[i]]==a[i]) ) b[k++]=a[i];
    }
    for (int j=0; j<k; j++)
    {
        s[0][j] = 0;
        for (int i=1; i<=N; i++)
        {
            s[i][j] = s[i-1][j]+(b[j]==a[i]);
        }
    }
    for (int lp=0; lp<M; lp++)
    {
        int l,r;
        scanf("%d %d", &l, &r);
        int ans=0;
        for (int j=0; j<k; j++)
            if ( (s[r][j] - s[l-1][j] ) == b[j] )
                ans++;
        printf("%d\n", ans);
    }
    return 0;
}


#include <iostream>
#include <fstream>
#include <stdio.h>
#include <algorithm>
#include <set>
#include <vector>
#include <map>
#include <queue>
#include <list>
#include <math.h>
#include <string>
#include <stdlib.h>
#include <string.h>

#define sqr(a) ((a)*(a))
#define odd(a) ((a)&1)
#define foru(i,n) for (int i=0;i<(n);i++)
#define ford(i,n) for (int i=(n)-1;i>=0;i--)
#define forab(i,l,r) for (int i=(l);i<=(r);i++)
#define forabd(i,r,l) for (int i=(r);i>=(l);i--)
#define pb push_back
#define F first
#define S second
#define all(x) x.begin(),x.end()
#define sz(__X) (int)__X.size()
#define pii pair<int,int>

const double eps=1e-20;
const double PI=acos(-1.0);
const int INF=1000*1000*1000+7;
const int MAXN = 100500;

using namespace std;

int N,M;
int a[MAXN], ans[MAXN];
vector<pii> b[MAXN];
map<int,int> now;
/*
map<int,int> t[MAXN*4], now;

void update (int v, int tl, int tr, int lpos, int rpos) {
    if (tl == lpos && tr==rpos)
        t[v] = now;
    else {
        int tm = (tl + tr) / 2;
        if (pos <= tm)
            update (v*2, tl, tm, lpos, rpos);
        else
            update (v*2+1, tm+1, tr, lpos, rpos);
    }
}

void merge_sort(int l, int r)
{
    if ( l == r)
    {
        if ( a[l] == 1)
            update(1, 1, N, l, r,1);
            else update(1, 1, N, l, r, 0);
        return;
    }
    int sr=(l+r)/2;
    merge_sort(l, sr);
    merge_sort(sr+1, r);
    int tl=l, tr=sr+1;
    for (int i=l; i<=r; i++)
    {
      484  if ( tl>sr)
            b[i]=a[tr++];
            else if ( tr>r)
                b[i]=a[tl++];
                else if ( a[tl] < a[tr])
                    b[i] = a[tl++];
                    else b[i]=a[tr++];
    }
    int k=0;
    now.clear();
    for (int i=l; i<=r; i++)
    {
        int j=i;
        while ( j<=r && b[j]==b[i])
        {
            a[j]=b[j];
            j++;
        }
        now[a[j-1]] = j-i;
    }
    update(1, 1, N, l, r);
}*/

int main()
{
    scanf("%d %d", &N, &M);
    for (int i=1; i<=N; i++)
    {
        scanf("%d", &a[i]);
    }
//    merge_sort(1, N);
    for (int i=0; i<M; i++)
    {
        int kl, kr;
        scanf("%d %d", &kl, &kr);
        b[kl].push_back( make_pair(kr, i));
    }
    //printf("Vvel\n");
    for (int i=1; i<=N; i++)
        sort(b[i].begin(), b[i].end());
    //printf("Sort\n");
    for (int i=1; i<=N; i++)
    {
        int k=i;
        now.clear();
        //printf("%d Na etom\n");
        for (int j=0; j<sz(b[i]); j++)
        {
            int r = b[i][j].F;
            while ( k<=N && k<= r)
            {
                now[a[k]]++;
                k++;
            }
            int res=0;
            for (map<int,int>::iterator it=now.begin(); it!=now.end(); it++)
            {
                if ( (*it).F == (*it).S)
                    res++;
            }
            ans[b[i][j].S]=res;
        }
    }
    for (int i=0; i<M; i++)
        printf("%d\n", ans[i]);
    return 0;
}


#include <iostream>
#include <fstream>
#include <stdio.h>
#include <algorithm>
#include <set>
#include <vector>
#include <map>
#include <queue>
#include <list>
#include <math.h>
#include <string>
#include <stdlib.h>
#include <string.h>

#define sqr(a) ((a)*(a))
#define odd(a) ((a)&1)
#define foru(i,n) for (int i=0;i<(n);i++)
#define ford(i,n) for (int i=(n)-1;i>=0;i--)
#define forab(i,l,r) for (int i=(l);i<=(r);i++)
#define forabd(i,r,l) for (int i=(r);i>=(l);i--)
#define pb push_back
#define F first
#define S second
#define all(x) x.begin(),x.end()
#define sz(__X) (int)__X.size()
#define pii pair<int,int>

const double eps=1e-20;
const double PI=acos(-1.0);
const int INF=1000*1000*1000+7;
const int MAXN = 100500;
const int MAXM = 505;

using namespace std;

int N,M, k;
int a[MAXN], kol[MAXN];
int b[MAXM], s[MAXN][MAXM];

int main()
{
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
    scanf("%d %d", &N, &M);
    for (int i=0; i<N; i++)
    {
        scanf("%d", &a[i]);
        if (a[i]<=N && ++kol[a[i]]==a[i]) b[k++]=a[i];
    }
    for (int j=0; j<k; j++)
    {
        s[0][j] = (a[0]==b[j]);
        for (int i=1; i<N; i++)
        {
            s[i][j] = s[i-1][j]+(b[j]==a[i]);
        }
    }
    for (int lp=0; lp<M; lp++)
    {
        int l,r;
        scanf("%d %d", &l, &r);
        l--; r--;
        int ans=0;
        for (int j=0; j<k; j++)
            ans += (s[r][j] - s[l][j] + (a[l]==b[j]) )== b[j];
        printf("%d\n", ans);
    }
    return 0;
}


#include <iostream>
#include <fstream>
#include <stdio.h>
#include <algorithm>
#include <set>
#include <vector>
#include <map>
#include <queue>
#include <list>
#include <math.h>
#include <string>
#include <stdlib.h>
#include <string.h>

#define sqr(a) ((a)*(a))
#define odd(a) ((a)&1)
#define foru(i,n) for (int i=0;i<(n);i++)
#define ford(i,n) for (int i=(n)-1;i>=0;i--)
#define forab(i,l,r) for (int i=(l);i<=(r);i++)
#define forabd(i,r,l) for (int i=(r);i>=(l);i--)
#define pb push_back
#define F first
#define S second
#define all(x) x.begin(),x.end()
#define sz(__X) (int)__X.size()
#define pii pair<int,int>

const double eps=1e-20;
const double PI=acos(-1.0);
const int INF=1000*1000*1000+7;
const int MAXN = 100500;
const int MAXM = 1000;

using namespace std;

int N,M, k;
int a[MAXN], kol[MAXN];
int b[MAXM], s[MAXN][MAXM];

int main()
{
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
    scanf("%d %d", &N, &M);
    for (int i=1; i<=N; i++)
    {
        scanf("%d", &a[i]);
        if (a[i]<=N && ++kol[a[i]]==a[i]) b[k++]=a[i];
    }
    for (int j=0; j<k; j++)
    {
        for (int i=1; i<=N; i++)
        {
            s[i][j] = s[i-1][j]+(b[j]==a[i]);
        }
    }
    for (int lp=0; lp<M; lp++)
    {
        int l,r;
        scanf("%d %d", &l, &r);
        int ans=0;
        for (int j=0; j<k; j++)
            ans += (s[r][j] - s[l-1][j] )== b[j];
        printf("%d\n", ans);
    }
    return 0;
}


#include <iostream>
#include <fstream>
#include <stdio.h>
#include <algorithm>
#include <set>
#include <vector>
#include <map>
#include <queue>
#include <list>
#include <math.h>
#include <string>
#include <stdlib.h>
#include <string.h>

#define sqr(a) ((a)*(a))
#define odd(a) ((a)&1)
#define foru(i,n) for (int i=0;i<(n);i++)
#define ford(i,n) for (int i=(n)-1;i>=0;i--)
#define forab(i,l,r) for (int i=(l);i<=(r);i++)
#define forabd(i,r,l) for (int i=(r);i>=(l);i--)
#define pb push_back
#define F first
#define S second
#define all(x) x.begin(),x.end()
#define sz(__X) (int)__X.size()
#define pii pair<int,int>

const double eps=1e-20;
const double PI=acos(-1.0);
const int INF=1000*1000*1000+7;
const int MAXN = 100500;
const int MAXM = 700;

using namespace std;

int N,M, k;
int a[MAXN], kol[MAXN];
int b[MAXM], s[MAXN][MAXM];

int main()
{
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
    scanf("%d %d", &N, &M);
    for (int i=1; i<=N; i++)
    {
        scanf("%d", &a[i]);
        if (a[i]<=N && ++kol[a[i]]==a[i]) b[k++]=a[i];
    }
    for (int j=0; j<k; j++)
    {
        for (int i=1; i<=N; i++)
        {
            s[i][j] = s[i-1][j]+(b[j]==a[i]);
        }
    }
    for (int lp=0; lp<M; lp++)
    {
        int l,r;
        scanf("%d %d", &l, &r);
        int ans=0;
        for (int j=0; j<k; j++)
            ans += (s[r][j] - s[l-1][j] )== b[j];
        printf("%d\n", ans);
    }
    return 0;
}


#include <iostream>
#include <fstream>
#include <stdio.h>
#include <algorithm>
#include <set>
#include <vector>
#include <map>
#include <queue>
#include <list>
#include <math.h>
#include <string>
#include <stdlib.h>
#include <string.h>

#define sqr(a) ((a)*(a))
#define odd(a) ((a)&1)
#define foru(i,n) for (int i=0;i<(n);i++)
#define ford(i,n) for (int i=(n)-1;i>=0;i--)
#define forab(i,l,r) for (int i=(l);i<=(r);i++)
#define forabd(i,r,l) for (int i=(r);i>=(l);i--)
#define pb push_back
#define F first
#define S second
#define all(x) x.begin(),x.end()
#define sz(__X) (int)__X.size()
#define pii pair<int,int>

const double eps=1e-19;
const double PI=acos(-1.0);
const int INF=1000*1000*1000+7;
const int MAXN = 100005;
const int MAXM = 600;

using namespace std;

int n,m,k;
int a[MAXN];
int count_num[MAXN], count_otr[MAXM][MAXN];
int cool_num[MAXM];

int main()
{
    scanf("%d %d", &n, &m);
    for (int i=1; i<=n; i++)
    {
        scanf("%d", &a[i]);
        if ( a[i]>n) continue;
        count_num[a[i]]++;
        if ( count_num[a[i]] == a[i])
        {
            cool_num[k++] = a[i];
        }
    }
    for (int i=0; i<k; i++)
    {
        count_otr[i][0]=0;
        for (int j=1; j<=n; j++)
        {
            count_otr[i][j] = count_otr[i][j-1];
            if ( a[j] == cool_num[i])
                count_otr[i][j]++;
        }
    }
    int l,r;
    for (int i=0; i<m; i++)
    {
        scanf("%d %d", &l, &r);
        int ans=0;
        for (int j=0; j<k; j++)
            if ( count_otr[j][r] - count_otr[j][l-1] == cool_num[j])
                ans++;
        printf("%d\n", ans);
    }
    return 0;
}


#include <iostream>
#include <fstream>
#include <stdio.h>
#include <algorithm>
#include <set>
#include <vector>
#include <map>
#include <queue>
#include <list>
#include <math.h>
#include <string>
#include <stdlib.h>
#include <string.h>

#define sqr(a) ((a)*(a))
#define odd(a) ((a)&1)
#define foru(i,n) for (int i=0;i<(n);i++)
#define ford(i,n) for (int i=(n)-1;i>=0;i--)
#define forab(i,l,r) for (int i=(l);i<=(r);i++)
#define forabd(i,r,l) for (int i=(r);i>=(l);i--)
#define pb push_back
#define F first
#define S second
#define all(x) x.begin(),x.end()
#define sz(__X) (int)__X.size()
#define pii pair<int,int>

const double eps=1e-20;
const double PI=acos(-1.0);
const int INF=1000*1000*1000+7;
const int MAXN = 100500;

using namespace std;

int N,M;
int a[MAXN], ans[MAXN];
vector<pii> b[MAXN];
int now[MAXN];
/*
map<int,int> t[MAXN*4], now;

void update (int v, int tl, int tr, int lpos, int rpos) {
    if (tl == lpos && tr==rpos)
        t[v] = now;
    else {
        int tm = (tl + tr) / 2;
        if (pos <= tm)
            update (v*2, tl, tm, lpos, rpos);
        else
            update (v*2+1, tm+1, tr, lpos, rpos);
    }
}

void merge_sort(int l, int r)
{
    if ( l == r)
    {
        if ( a[l] == 1)
            update(1, 1, N, l, r,1);
            else update(1, 1, N, l, r, 0);
        return;
    }
    int sr=(l+r)/2;
    merge_sort(l, sr);
    merge_sort(sr+1, r);
    int tl=l, tr=sr+1;
    for (int i=l; i<=r; i++)
    {
      484  if ( tl>sr)
            b[i]=a[tr++];
            else if ( tr>r)
                b[i]=a[tl++];
                else if ( a[tl] < a[tr])
                    b[i] = a[tl++];
                    else b[i]=a[tr++];
    }
    int k=0;
    now.clear();
    for (int i=l; i<=r; i++)
    {
        int j=i;
        while ( j<=r && b[j]==b[i])
        {
            a[j]=b[j];
            j++;
        }
        now[a[j-1]] = j-i;
    }
    update(1, 1, N, l, r);
}*/

int main()
{
    scanf("%d %d", &N, &M);
    for (int i=1; i<=N; i++)
    {
        scanf("%d", &a[i]);
    }
//    merge_sort(1, N);
    for (int i=0; i<M; i++)
    {
        int kl, kr;
        scanf("%d %d", &kl, &kr);
        b[kl].push_back( make_pair(kr, i));
    }
    //printf("Vvel\n");
    for (int i=1; i<=N; i++)
        sort(b[i].begin(), b[i].end());
    //printf("Sort\n");
    for (int i=1; i<=N; i++)
    {
        int k=i;
        memset(now, 0, sizeof now);
        int res=0;
        //printf("%d Na etom\n");
        for (int j=0; j<sz(b[i]); j++)
        {
            int r = b[i][j].F;
            while ( k<=N && k<= r)
            {
                now[a[k]]++;
                if ( now[a[k]] == a[k])
                    res++;
                    else if ( now[a[k]]==a[k]+1)
                        res--;
                k++;
            }
            ans[b[i][j].S]=res;
        }
    }
    for (int i=0; i<M; i++)
        printf("%d\n", ans[i]);
    return 0;
}


#include <iostream>
#include <fstream>
#include <stdio.h>
#include <algorithm>
#include <set>
#include <vector>
#include <map>
#include <queue>
#include <list>
#include <math.h>
#include <string>
#include <stdlib.h>
#include <string.h>

#define sqr(a) ((a)*(a))
#define odd(a) ((a)&1)
#define foru(i,n) for (int i=0;i<(n);i++)
#define ford(i,n) for (int i=(n)-1;i>=0;i--)
#define forab(i,l,r) for (int i=(l);i<=(r);i++)
#define forabd(i,r,l) for (int i=(r);i>=(l);i--)
#define pb push_back
#define F first
#define S second
#define all(x) x.begin(),x.end()
#define sz(__X) (int)__X.size()
#define pii pair<int,int>

const double eps=1e-20;
const double PI=acos(-1.0);
const int INF=1000*1000*1000+7;
const int MAXN = 100500;
const int MAXM = 600;

using namespace std;

int N,M, k;
int a[MAXN], kol[MAXN];
int b[MAXM], s[MAXN][MAXM];

int main()
{
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
    scanf("%d %d", &N, &M);
    k=0;
    for (int i=1; i<=N; i++)
    {
        scanf("%d", &a[i]);
        if ( (a[i]<=N) && (++kol[a[i]]==a[i]) ) b[k++]=a[i];
    }
    for (int j=0; j<k; j++)
    {
        s[0][j] = 0;
        for (int i=1; i<=N; i++)
        {
            s[i][j] = s[i-1][j]+(b[j]==a[i]);
        }
    }
    for (int lp=0; lp<M; lp++)
    {
        int l,r;
        scanf("%d %d", &l, &r);
        int ans=0;
        for (int j=0; j<k; j++)
            ans += (s[r][j] - s[l-1][j] ) == b[j];
        printf("%d\n", ans);
    }
    return 0;
}


#include <iostream>
#include <fstream>
#include <stdio.h>
#include <algorithm>
#include <set>
#include <vector>
#include <map>
#include <queue>
#include <list>
#include <math.h>
#include <string>
#include <stdlib.h>
#include <string.h>

#define sqr(a) ((a)*(a))
#define odd(a) ((a)&1)
#define foru(i,n) for (int i=0;i<(n);i++)
#define ford(i,n) for (int i=(n)-1;i>=0;i--)
#define forab(i,l,r) for (int i=(l);i<=(r);i++)
#define forabd(i,r,l) for (int i=(r);i>=(l);i--)
#define pb push_back
#define F first
#define S second
#define all(x) x.begin(),x.end()
#define sz(__X) (int)__X.size()
#define pii pair<int,int>

const double eps=1e-20;
const double PI=acos(-1.0);
const int INF=1000*1000*1000+7;
const int MAXN = 100500;
const int MAXM = 505;

using namespace std;

int N,M, k;
int a[MAXN];
int b[MAXM], s[MAXN][MAXM];

int main()
{
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
    scanf("%d %d", &N, &M);
    for (int i=0; i<N; i++)
    {
        scanf("%d", &a[i]);
        bool f=false;
        if ( a[i]>N)
            break;
        for (int j=0; j<k; j++)
        {
            if ( b[j] == a[i])
            {
                f=true;
                break;
            }
        }
        if ( !f)
        {
            b[k++] = a[i];
        }
    }
    for (int j=0; j<k; j++)
    {
        s[0][j] = (a[0]==b[j]);
        for (int i=1; i<N; i++)
        {
            s[i][j] = s[i-1][j]+(b[j]==a[i]);
        }
    }
    for (int lp=0; lp<M; lp++)
    {
        int l,r;
        scanf("%d %d", &l, &r);
        l--; r--;
        int ans=0;
        for (int j=0; j<k; j++)
            ans += (s[r][j] - s[l][j] + (a[l]==b[j]) )== b[j];
        printf("%d\n", ans);
    }
    return 0;
}


#include <iostream>
#include <fstream>
#include <stdio.h>
#include <algorithm>
#include <set>
#include <vector>
#include <map>
#include <queue>
#include <list>
#include <math.h>
#include <string>
#include <stdlib.h>
#include <string.h>

#define sqr(a) ((a)*(a))
#define odd(a) ((a)&1)
#define foru(i,n) for (int i=0;i<(n);i++)
#define ford(i,n) for (int i=(n)-1;i>=0;i--)
#define forab(i,l,r) for (int i=(l);i<=(r);i++)
#define forabd(i,r,l) for (int i=(r);i>=(l);i--)
#define pb push_back
#define F first
#define S second
#define all(x) x.begin(),x.end()
#define sz(__X) (int)__X.size()
#define pii pair<int,int>

const double eps=1e-20;
const double PI=acos(-1.0);
const int INF=1000*1000*1000+7;
const int MAXN = 100500;

using namespace std;

int N,M;
int a[MAXN], ans[MAXN];
vector<pii> b[MAXN];
int now[MAXN];
/*
map<int,int> t[MAXN*4], now;

void update (int v, int tl, int tr, int lpos, int rpos) {
    if (tl == lpos && tr==rpos)
        t[v] = now;
    else {
        int tm = (tl + tr) / 2;
        if (pos <= tm)
            update (v*2, tl, tm, lpos, rpos);
        else
            update (v*2+1, tm+1, tr, lpos, rpos);
    }
}

void merge_sort(int l, int r)
{
    if ( l == r)
    {
        if ( a[l] == 1)
            update(1, 1, N, l, r,1);
            else update(1, 1, N, l, r, 0);
        return;
    }
    int sr=(l+r)/2;
    merge_sort(l, sr);
    merge_sort(sr+1, r);
    int tl=l, tr=sr+1;
    for (int i=l; i<=r; i++)
    {
      484  if ( tl>sr)
            b[i]=a[tr++];
            else if ( tr>r)
                b[i]=a[tl++];
                else if ( a[tl] < a[tr])
                    b[i] = a[tl++];
                    else b[i]=a[tr++];
    }
    int k=0;
    now.clear();
    for (int i=l; i<=r; i++)
    {
        int j=i;
        while ( j<=r && b[j]==b[i])
        {
            a[j]=b[j];
            j++;
        }
        now[a[j-1]] = j-i;
    }
    update(1, 1, N, l, r);
}*/

int main()
{
    scanf("%d %d", &N, &M);
    for (int i=1; i<=N; i++)
    {
        scanf("%d", &a[i]);
    }
//    merge_sort(1, N);
    for (int i=0; i<M; i++)
    {
        int kl, kr;
        scanf("%d %d", &kl, &kr);
        b[kl].push_back( make_pair(kr, i));
    }
    //printf("Vvel\n");
    for (int i=1; i<=N; i++)
        sort(b[i].begin(), b[i].end());
    //printf("Sort\n");
    for (int i=1; i<=N; i++)
    {
        int k=i;
        memset(now, 0, sizeof now);
        int res=0;
        //printf("%d Na etom\n");
        for (int j=0; j<sz(b[i]); j++)
        {
            int r = b[i][j].F;
            while ( k<=N && k<= r)
            {
                if ( a[k] > N)
                {
                    k++;
                    continue;
                }
                now[a[k]]++;
                if ( now[a[k]] == a[k])
                    res++;
                    else if ( now[a[k]]==a[k]+1)
                        res--;
                k++;
            }
            ans[b[i][j].S]=res;
        }
    }
    for (int i=0; i<M; i++)
        printf("%d\n", ans[i]);
    return 0;
}


#include <iostream>
#include <fstream>
#include <stdio.h>
#include <algorithm>
#include <set>
#include <vector>
#include <map>
#include <queue>
#include <list>
#include <math.h>
#include <string>
#include <stdlib.h>
#include <string.h>

#define sqr(a) ((a)*(a))
#define odd(a) ((a)&1)
#define foru(i,n) for (int i=0;i<(n);i++)
#define ford(i,n) for (int i=(n)-1;i>=0;i--)
#define forab(i,l,r) for (int i=(l);i<=(r);i++)
#define forabd(i,r,l) for (int i=(r);i>=(l);i--)
#define pb push_back
#define F first
#define S second
#define all(x) x.begin(),x.end()
#define sz(__X) (int)__X.size()
#define pii pair<int,int>

const double eps=1e-20;
const double PI=acos(-1.0);
const int INF=1000*1000*1000+7;
const int MAXN = 100005;
const int MAXM = 600;

using namespace std;

int n,m,k;
int a[MAXN];
int count_num[MAXN], count_otr[MAXM][MAXN];
int cool_num[MAXM];

int main()
{
    scanf("%d %d", &n, &m);
    for (int i=1; i<=n; i++)
    {
        scanf("%d", &a[i]);
        if ( a[i]>n) continue;
        count_num[a[i]]++;
        if ( count_num[a[i]] == a[i])
        {
            cool_num[k++] = a[i];
        }
    }
    for (int i=0; i<k; i++)
    {
        count_otr[i][0]=0;
        for (int j=1; j<=n; j++)
        {
            count_otr[i][j] = count_otr[i][j-1];
            if ( a[j] == cool_num[i])
                count_otr[i][j]++;
        }
    }
    int l,r;
    for (int i=0; i<m; i++)
    {
        scanf("%d %d", &l, &r);
        int ans=0;
        for (int j=0; j<k; j++)
            if ( count_otr[j][r] - count_otr[j][l-1] == cool_num[j])
                ans++;
        printf("%d\n", ans);
    }
    return 0;
}


#include <iostream>
#include <fstream>
#include <stdio.h>
#include <algorithm>
#include <set>
#include <vector>
#include <map>
#include <queue>
#include <list>
#include <math.h>
#include <string>
#include <stdlib.h>
#include <string.h>

#define sqr(a) ((a)*(a))
#define odd(a) ((a)&1)
#define foru(i,n) for (int i=0;i<(n);i++)
#define ford(i,n) for (int i=(n)-1;i>=0;i--)
#define forab(i,l,r) for (int i=(l);i<=(r);i++)
#define forabd(i,r,l) for (int i=(r);i>=(l);i--)
#define pb push_back
#define F first
#define S second
#define all(x) x.begin(),x.end()
#define sz(__X) (int)__X.size()
#define pii pair<int,int>

const double eps=1e-20;
const double PI=acos(-1.0);
const int INF=1000*1000*1000+7;
const int MAXN = 100500;
const int MAXM = 600;

using namespace std;

int N,M, k;
int a[MAXN], kol[MAXN];
int b[MAXM], s[MAXN][MAXM];

int main()
{
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
    scanf("%d %d", &N, &M);
    for (int i=1; i<=N; i++)
    {
        scanf("%d", &a[i]);
        if (a[i]<=N && ++kol[a[i]]==a[i]) b[k++]=a[i];
    }
    for (int j=0; j<k; j++)
    {
        for (int i=1; i<=N; i++)
        {
            s[i][j] = s[i-1][j]+(b[j]==a[i]);
        }
    }
    for (int lp=0; lp<M; lp++)
    {
        int l,r;
        scanf("%d %d", &l, &r);
        int ans=0;
        for (int j=0; j<k; j++)
            ans += (s[r][j] - s[l-1][j] )== b[j];
        printf("%d\n", ans);
    }
    return 0;
}


#include <iostream>
#include <fstream>
#include <stdio.h>
#include <algorithm>
#include <set>
#include <vector>
#include <map>
#include <queue>
#include <list>
#include <math.h>
#include <string>
#include <stdlib.h>
#include <string.h>

#define sqr(a) ((a)*(a))
#define odd(a) ((a)&1)
#define foru(i,n) for (int i=0;i<(n);i++)
#define ford(i,n) for (int i=(n)-1;i>=0;i--)
#define forab(i,l,r) for (int i=(l);i<=(r);i++)
#define forabd(i,r,l) for (int i=(r);i>=(l);i--)
#define pb push_back
#define F first
#define S second
#define all(x) x.begin(),x.end()
#define sz(__X) (int)__X.size()
#define pii pair<int,int>

const double eps=1e-20;
const double PI=acos(-1.0);
const int INF=1000*1000*1000+7;
const int MAXN = 100505;
const int MAXM = 600;

using namespace std;

int N,M, k;
int a[MAXN], kol[MAXN];
int b[MAXM], s[MAXN][MAXM];

int main()
{
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
    scanf("%d %d", &N, &M);
    k=0;
    for (int i=1; i<=N; i++)
    {
        scanf("%d", &a[i]);
        if ( (a[i]<=N) && (++kol[a[i]]==a[i]) ) b[k++]=a[i];
    }
    for (int j=0; j<k; j++)
    {
        for (int i=1; i<=N; i++)
        {
            s[i][j] = s[i-1][j]+(b[j]==a[i]);
        }
    }
    for (int lp=0; lp<M; lp++)
    {
        int l,r;
        scanf("%d %d", &l, &r);
        int ans=0;
        for (int j=0; j<k; j++)
            if ( (s[r][j] - s[l-1][j] ) == b[j] )
                ans++;
        printf("%d\n", ans);
    }
    return 0;
}


#include <iostream>
#include <fstream>
#include <stdio.h>
#include <algorithm>
#include <set>
#include <vector>
#include <map>
#include <queue>
#include <list>
#include <math.h>
#include <string>
#include <stdlib.h>
#include <string.h>

#define sqr(a) ((a)*(a))
#define odd(a) ((a)&1)
#define foru(i,n) for (int i=0;i<(n);i++)
#define ford(i,n) for (int i=(n)-1;i>=0;i--)
#define forab(i,l,r) for (int i=(l);i<=(r);i++)
#define forabd(i,r,l) for (int i=(r);i>=(l);i--)
#define pb push_back
#define F first
#define S second
#define all(x) x.begin(),x.end()
#define sz(__X) (int)__X.size()
#define pii pair<int,int>

const double eps=1e-21;
const double PI=acos(-1.0);
const int INF=1000*1000*1000+7;
const int MAXN = 100005;
const int MAXM = 600;

using namespace std;

int n,m,k;
int a[MAXN];
int count_num[MAXN], count_otr[MAXM][MAXN];
int cool_num[MAXM];

int main()
{
    scanf("%d %d", &n, &m);
    for (int i=1; i<=n; i++)
    {
        scanf("%d", &a[i]);
        if ( a[i]>n) continue;
        count_num[a[i]]++;
        if ( count_num[a[i]] == a[i])
        {
            cool_num[k++] = a[i];
        }
    }
    for (int i=0; i<k; i++)
    {
        count_otr[i][0]=0;
        for (int j=1; j<=n; j++)
        {
            count_otr[i][j] = count_otr[i][j-1];
            if ( a[j] == cool_num[i])
                count_otr[i][j]++;
        }
    }
    int l,r;
    for (int i=0; i<m; i++)
    {
        scanf("%d %d", &l, &r);
        int ans=0;
        for (int j=0; j<k; j++)
            if ( count_otr[j][r] - count_otr[j][l-1] == cool_num[j])
                ans++;
        printf("%d\n", ans);
    }
    return 0;
}


#include <cstdio>
#include <vector>

#define MAXN 100005
#define SQRMAXN 453
#define INF 0x3f3f3f3f
#define pb push_back

using namespace std;

int N, M, A[MAXN], f[MAXN], nposs, poss_num[SQRMAXN];
int sums[SQRMAXN][MAXN];
char appear[SQRMAXN][MAXN];

void Test() {
	int i;

	printf ("Array :\n");
	for ( i=1; i<=N; ++i ) {
		printf ("%d\n", A[i]);
	}

	printf ("%d possible numbers :\n", nposs );
	for ( i=1; i<=nposs; ++i ) {
		printf ("%d\n", poss_num[i]);
	}

	for ( i=1; i<=N; ++i ) {
		printf ("Frequency of %d is %d\n", A[i], f[ A[i] ] );
	}
}

void Read() {
	int i;

	scanf ("%d %d", &N, &M);
	for ( i=1; i<=N; ++i ) {
		scanf ("%d", &A[i]);
	}
}

void Frequencies() {
	int i;

	for ( i=1; i<=N; ++i ) {
		if ( A[i] <= N ) {
			++f[ A[i] ];
		}
	}
}

void Possible_Nums() {
	int i;

	for ( i=1; i<=N; ++i ) {
		if ( f[i] >= i ) {
			poss_num[ ++nposs ] = i;
		}
	}
}

int Position ( int x ) {
	int lo, mid, hi;

	lo = 1;
	hi = nposs;
	while ( lo < hi ) {
		mid = (lo+hi+1) / 2;
		if ( poss_num[ mid ] <= x ) {
			lo = mid;
		}
		else {
			hi = mid-1;
		}
	}

	return lo;
}

void Appear() {
	int i, pos;

	for ( i=1; i<=N; ++i ) {
		if ( A[i] <= N && f[ A[i] ] >= A[i] ) {
			pos = Position(A[i]);
			appear[ pos ][i] = 1;
		}
	}
}

void Make_Sums() {
	int i, j;

	for ( i=1; i<=nposs; ++i ) {
		for ( j=1; j<=N; ++j ) {
			sums[i][j] = sums[i][j-1] + appear[i][j];
		}
	}

}

void Answer_Queries() {
	int i, from, to, ans, possible;

	for ( i=1; i<=M; ++i ) {
		scanf ("%d %d", &from, &to);
		ans = 0;

		for ( possible = 1; possible <= nposs; ++possible ) {
			if ( sums[possible][to]-sums[possible][from-1] == poss_num[ possible ] ) {
				++ans;
			}
		}

		printf ("%d\n", ans );
	}
}

int main ( void ) {

	Read();
	Frequencies();
	Possible_Nums();
	Appear();
	Make_Sums();
	//Test();
	Answer_Queries();

	return (0);
}


#include <cstdio>
#include <vector>

#define MAXN 100005
#define SQRMAXN 700
#define INF 0x3f3f3f3f
#define pb push_back

using namespace std;

int N, M, A[MAXN], f[MAXN], nposs, poss_num[SQRMAXN];
vector<int> appear[SQRMAXN];

void Test() {
	int i;

	printf ("Array :\n");
	for ( i=1; i<=N; ++i ) {
		printf ("%d\n", A[i]);
	}

	printf ("%d possible numbers :\n", nposs );
	for ( i=1; i<=nposs; ++i ) {
		printf ("%d\n", poss_num[i]);
	}

	for ( i=1; i<=N; ++i ) {
		printf ("Frequency of %d is %d\n", A[i], f[ A[i] ] );
	}

	for ( i=1; i<=nposs; ++i ) {
		printf ("Appearances of %d\n", poss_num[i]);
		for ( int j=0; j<appear[i].size(); ++j ) {
			printf("%d ", appear[i][j]);
		}
		printf ("\n");
	}
}

void Read() {
	int i;

	scanf ("%d %d", &N, &M);
	for ( i=1; i<=N; ++i ) {
		scanf ("%d", &A[i]);
	}
}

void Frequencies() {
	int i;

	for ( i=1; i<=N; ++i ) {
		if ( A[i] <= N ) {
			++f[ A[i] ];
		}
	}
}

void Possible_Nums() {
	int i;

	for ( i=1; i<=N; ++i ) {
		if ( f[i] >= i ) {
			poss_num[ ++nposs ] = i;
		}
	}
	if ( nposs > 600 ) {
		while ( 1 ) {
			printf ("moxos\n");
		}
	}
}

int Position ( int x ) {
	int lo, mid, hi;

	lo = 1;
	hi = nposs;
	while ( lo < hi ) {
		mid = (lo+hi+1) / 2;
		if ( poss_num[ mid ] <= x ) {
			lo = mid;
		}
		else {
			hi = mid-1;
		}
	}

	return lo;
}

void Appear() {
	int i, pos;

	for ( i=1; i<=N; ++i ) {
		if ( A[i] < MAXN && f[ A[i] ] >= A[i] ) {
			pos = Position(A[i]);
			appear[ A[i] ].pb (i);
		}
	}
}

int Lower_Bound ( int from, int x ) {
	int lo, mid, hi;

	lo = 0;
	hi = appear[x].size()-1;
	while ( lo < hi ) {
		mid = (lo+hi) / 2;
		if ( appear[x][mid] >= from ) {
			hi = mid;
		}
		else {
			lo = mid+1;
		}
	}

	return appear[x][lo] >= from ? lo : INF;
}

int Upper_Bound ( int to, int x ) {
	int lo, mid, hi;

	lo = 0;
	hi = appear[x].size()-1;
	while ( lo < hi ) {
		mid = (lo+hi+1) / 2;
		if ( appear[x][mid] <= to ) {
			lo = mid;
		}
		else {
			hi = mid-1;
		}
	}

	return appear[x][lo] <= to ? lo : -INF;
}

void Answer_Queries() {
	int i, from, to, lo, hi, ans, possible;

	for ( i=1; i<=M; ++i ) {
		scanf ("%d %d", &from, &to);
		ans = 0;

		for ( possible = 1; possible <= nposs; ++possible ) {
			lo = Lower_Bound ( from, possible );
			hi = Upper_Bound ( to, possible );
			//printf ("Num %d, low %d, hi %d\n", poss_num[possible],lo,hi);
			if ( hi-lo+1 == poss_num[ possible ] ) {
				++ans;
			}
		}

		printf ("%d\n", ans );
	}
}

int main ( void ) {

	Read();
	Frequencies();
	Possible_Nums();
	Appear();
	//Test();
	Answer_Queries();

	return 0;
}


#include <cstdio>
#include <vector>

#define MAXN 100005
#define SQRMAXN 455
#define INF 0x3f3f3f3f
#define pb push_back

using namespace std;

int N, M, A[MAXN], f[MAXN], nposs, poss_num[SQRMAXN];
int sums[SQRMAXN][MAXN];
char appear[SQRMAXN][MAXN];

void Test() {
	int i;

	printf ("Array :\n");
	for ( i=1; i<=N; ++i ) {
		printf ("%d\n", A[i]);
	}

	printf ("%d possible numbers :\n", nposs );
	for ( i=1; i<=nposs; ++i ) {
		printf ("%d\n", poss_num[i]);
	}

	for ( i=1; i<=N; ++i ) {
		printf ("Frequency of %d is %d\n", A[i], f[ A[i] ] );
	}
}

void Read() {
	int i;

	scanf ("%d %d", &N, &M);
	for ( i=1; i<=N; ++i ) {
		scanf ("%d", &A[i]);
	}
}

void Frequencies() {
	int i;

	for ( i=1; i<=N; ++i ) {
		if ( A[i] <= N ) {
			++f[ A[i] ];
		}
	}
}

void Possible_Nums() {
	int i;

	for ( i=1; i<=N; ++i ) {
		if ( f[i] >= i ) {
			poss_num[ ++nposs ] = i;
		}
	}
}

int Position ( int x ) {
	int lo, mid, hi;

	lo = 1;
	hi = nposs;
	while ( lo < hi ) {
		mid = (lo+hi+1) / 2;
		if ( poss_num[ mid ] <= x ) {
			lo = mid;
		}
		else {
			hi = mid-1;
		}
	}

	return lo;
}

void Appear() {
	int i, pos;

	for ( i=1; i<=N; ++i ) {
		if ( A[i] <= N && f[ A[i] ] >= A[i] ) {
			pos = Position(A[i]);
			appear[ pos ][i] = 1;
		}
	}
}

void Make_Sums() {
	int i, j;

	for ( i=1; i<=nposs; ++i ) {
		for ( j=1; j<=N; ++j ) {
			sums[i][j] = sums[i][j-1] + appear[i][j];
		}
	}

}

void Answer_Queries() {
	int i, from, to, ans, possible;

	for ( i=1; i<=M; ++i ) {
		scanf ("%d %d", &from, &to);
		ans = 0;

		for ( possible = 1; possible <= nposs; ++possible ) {
			if ( sums[possible][to]-sums[possible][from-1] == poss_num[ possible ] ) {
				++ans;
			}
		}

		printf ("%d\n", ans );
	}
}

int main ( void ) {

	Read();
	Frequencies();
	Possible_Nums();
	Appear();
	Make_Sums();
	//Test();
	Answer_Queries();

	return 0;
}


#include <cstdio>
#include <vector>

#define MAXN 100005
#define SQRMAXN 455
#define INF 0x3f3f3f3f
#define pb push_back

using namespace std;

int N, M, A[MAXN], f[MAXN], nposs, poss_num[SQRMAXN];
int sums[SQRMAXN][MAXN];
char appear[SQRMAXN][MAXN];

void Test() {
	int i;

	printf ("Array :\n");
	for ( i=1; i<=N; ++i ) {
		printf ("%d\n", A[i]);
	}

	printf ("%d possible numbers :\n", nposs );
	for ( i=1; i<=nposs; ++i ) {
		printf ("%d\n", poss_num[i]);
	}

	for ( i=1; i<=N; ++i ) {
		printf ("Frequency of %d is %d\n", A[i], f[ A[i] ] );
	}
}

void Read() {
	int i;

	scanf ("%d %d", &N, &M);
	for ( i=1; i<=N; ++i ) {
		scanf ("%d", &A[i]);
	}
}

void Frequencies() {
	int i;

	for ( i=1; i<=N; ++i ) {
		if ( A[i] <= N ) {
			++f[ A[i] ];
		}
	}
}

void Possible_Nums() {
	int i;

	for ( i=1; i<=N; ++i ) {
		if ( f[i] >= i ) {
			poss_num[ ++nposs ] = i;
		}
	}
}

int Position ( int x ) {
	int lo, mid, hi;

	lo = 1;
	hi = nposs;
	while ( lo < hi ) {
		mid = (lo+hi+1) / 2;
		if ( poss_num[ mid ] <= x ) {
			lo = mid;
		}
		else {
			hi = mid-1;
		}
	}

	return lo;
}

void Appear() {
	int i, pos;

	for ( i=1; i<=N; ++i ) {
		if ( A[i] <= N && f[ A[i] ] >= A[i] ) {
			pos = Position(A[i]);
			appear[ pos ][i] = 1;
		}
	}
}

void Make_Sums() {
	int i, j;

	for ( i=1; i<=nposs; ++i ) {
		for ( j=1; j<=N; ++j ) {
			sums[i][j] = sums[i][j-1] + appear[i][j];
		}
	}

}

void Answer_Queries() {
	int i, from, to, ans, possible;

	for ( i=1; i<=M; ++i ) {
		scanf ("%d %d", &from, &to);
		ans = 0;

		for ( possible = 1; possible <= nposs; ++possible ) {
			if ( sums[possible][to]-sums[possible][from-1] == poss_num[ possible ] ) {
				++ans;
			}
		}

		printf ("%d\n", ans );
	}
}

int main ( void ) {

	Read();
	Frequencies();
	Possible_Nums();
	Appear();
	Make_Sums();
	//Test();
	Answer_Queries();

	return (0);
}


#include <cstdio>
#include <vector>

#define MAXN 100005
#define SQRMAXN 451
#define pb push_back

using namespace std;

int N, M, A[MAXN], f[MAXN], nposs, poss_num[SQRMAXN];
int sums[SQRMAXN][MAXN];
char appear[SQRMAXN][MAXN];

void Test() {
	int i;

	printf ("Array :\n");
	for ( i=1; i<=N; ++i ) {
		printf ("%d\n", A[i]);
	}

	printf ("%d possible numbers :\n", nposs );
	for ( i=1; i<=nposs; ++i ) {
		printf ("%d\n", poss_num[i]);
	}

	for ( i=1; i<=N; ++i ) {
		printf ("Frequency of %d is %d\n", A[i], f[ A[i] ] );
	}
}

void Read() {
	int i;

	scanf ("%d %d", &N, &M);
	for ( i=1; i<=N; ++i ) {
		scanf ("%d", &A[i]);
	}
}

void Frequencies() {
	int i;

	for ( i=1; i<=N; ++i ) {
		if ( A[i] <= N ) {
			++f[ A[i] ];
		}
	}
}

void Possible_Nums() {
	int i;

	for ( i=1; i<=N; ++i ) {
		if ( f[i] >= i ) {
			poss_num[ ++nposs ] = i;
		}
	}
}

int Position ( int x ) {
	int lo, mid, hi;

	lo = 1;
	hi = nposs;
	while ( lo < hi ) {
		mid = (lo+hi+1) / 2;
		if ( poss_num[ mid ] <= x ) {
			lo = mid;
		}
		else {
			hi = mid-1;
		}
	}

	return lo;
}

void Appear() {
	int i, pos;

	for ( i=1; i<=N; ++i ) {
		if ( A[i] <= N && f[ A[i] ] >= A[i] ) {
			pos = Position(A[i]);
			appear[ pos ][i] = 1;
		}
	}
}

void Make_Sums() {
	int i, j;

	for ( i=1; i<=nposs; ++i ) {
		for ( j=1; j<=N; ++j ) {
			sums[i][j] = sums[i][j-1] + appear[i][j];
		}
	}

}

void Answer_Queries() {
	int i, from, to, ans, possible;

	for ( i=1; i<=M; ++i ) {
		scanf ("%d %d", &from, &to);
		ans = 0;

		for ( possible = 1; possible <= nposs; ++possible ) {
			if ( sums[possible][to]-sums[possible][from-1] == poss_num[ possible ] ) {
				++ans;
			}
		}

		printf ("%d\n", ans );
	}
}

int main ( void ) {

	Read();
	Frequencies();
	Possible_Nums();
	Appear();
	Make_Sums();
	//Test();
	Answer_Queries();

	return (0);
}


#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<math.h>
#include<map>
#include<queue>
#include<stack>
#define ll long long
#define oo 1000000000
#define pi acos(-1)
using namespace std;
struct node
{
	int x,num;
}a[100005];
int n,t,m,k,i,j,s[100005],b[450],h[100005][450];
map<int,int> mymap;
int main()
{
	while (~scanf("%d%d",&n,&t))
	{
		mymap.clear();
		m=0;
		for (i=1;i<=n;i++) scanf("%d",&s[i]);
		for (i=1;i<=n;i++)
		{
			if (mymap.find(s[i])==mymap.end())
			{
				mymap[s[i]]=++m;
				a[m].x=s[i];
				a[m].num=0;
			}
			a[mymap[s[i]]].num++;
		}
		k=0;
		for (i=1;i<=m;i++)
			if (a[i].x<=a[i].num)
				b[++k]=a[i].x;
		for (i=1;i<=k;i++)
		{
			h[0][i]=0;
			for (j=1;j<=n;j++)
				if (s[j]==b[i]) h[j][i]=h[j-1][i]+1;
				else h[j][i]=h[j-1][i];
		}
		int l,r,ans;
		while (t--)
		{
			ans=0;
			scanf("%d%d",&l,&r);
			for (i=1;i<=k;i++)
				if (h[r][i]-h[l-1][i]==b[i]) ans++;
			printf("%d\n",ans);
		}
	}
	return 0;
}


#include <cstdio>
#include <vector>

#define MAXN 100005
#define SQRMAXN 500
#define INF 0x3f3f3f3f
#define pb push_back

using namespace std;

int N, M, A[MAXN], f[MAXN], nposs, poss_num[SQRMAXN];
vector<int> appear[MAXN];

void Test() {
	int i;

	printf ("Array :\n");
	for ( i=1; i<=N; ++i ) {
		printf ("%d\n", A[i]);
	}

	printf ("%d possible numbers :\n", nposs );
	for ( i=1; i<=nposs; ++i ) {
		printf ("%d\n", poss_num[i]);
	}

	for ( i=1; i<=N; ++i ) {
		printf ("Frequency of %d is %d\n", A[i], f[ A[i] ] );
	}

	for ( i=1; i<=nposs; ++i ) {
		printf ("Appearances of %d\n", poss_num[i]);
		for ( int j=0; j<appear[i].size(); ++j ) {
			printf("%d ", appear[i][j]);
		}
		printf ("\n");
	}
}

void Read() {
	int i;

	scanf ("%d %d", &N, &M);
	for ( i=1; i<=N; ++i ) {
		scanf ("%d", &A[i]);
	}
}

void Frequencies() {
	int i;

	for ( i=1; i<=N; ++i ) {
		if ( A[i] <= MAXN ) {
			++f[ A[i] ];
		}
	}
}

void Possible_Nums() {
	int i;

	for ( i=1; i<=MAXN; ++i ) {
		if ( f[i] >= i ) {
			poss_num[ ++nposs ] = i;
		}
	}
}

int Position ( int x ) {
	int lo, mid, hi;

	lo = 1;
	hi = nposs;
	while ( lo < hi ) {
		mid = (lo+hi+1) / 2;
		if ( poss_num[ mid ] <= x ) {
			lo = mid;
		}
		else {
			hi = mid-1;
		}
	}

	return lo;
}

void Appear() {
	int i, pos;

	for ( i=1; i<=N; ++i ) {
		if ( A[i] <= MAXN && f[ A[i] ] >= A[i] ) {
			pos = Position(A[i]);
			appear[ A[i] ].pb (i);
		}
	}
}

int Lower_Bound ( int from, int x ) {
	int lo, mid, hi;

	lo = 0;
	hi = appear[x].size()-1;
	while ( lo < hi ) {
		mid = (lo+hi+1) / 2;
		if ( appear[x][mid] <= from ) {
			lo = mid;
		}
		else {
			hi = mid-1;
		}
	}

	return appear[x][lo] >= from ? lo : INF;
}

int Upper_Bound ( int to, int x ) {
	int lo, mid, hi;

	lo = 0;
	hi = appear[x].size()-1;
	while ( lo < hi ) {
		mid = (lo+hi) / 2;
		if ( appear[x][mid] >= to ) {
			hi = mid;
		}
		else {
			lo = mid+1;
		}
	}

	return appear[x][lo] <= to ? lo : -INF;
}

void Answer_Queries() {
	int i, from, to, lo, hi, ans, possible;

	for ( i=1; i<=M; ++i ) {
		scanf ("%d %d", &from, &to);
		ans = 0;

		for ( possible = 1; possible <= nposs; ++possible ) {
			lo = Lower_Bound ( from, possible );
			hi = Upper_Bound ( to, possible );
			//printf ("Num %d, low %d, hi %d\n", poss_num[possible],lo,hi);
			if ( hi-lo+1 == poss_num[ possible ] ) {
				++ans;
			}
		}

		printf ("%d\n", ans );
	}
}

int main ( void ) {

	Read();
	Frequencies();
	Possible_Nums();
	Appear();
	//Test();
	Answer_Queries();

	return 0;
}


#include <cstdio>
#include <vector>

#define MAXN 100005
#define SQRMAXN 700
#define INF 0x3f3f3f3f
#define pb push_back

using namespace std;

int N, M, A[MAXN], f[MAXN], nposs, poss_num[SQRMAXN];
vector<int> appear[SQRMAXN];

void Test() {
	int i;

	printf ("Array :\n");
	for ( i=1; i<=N; ++i ) {
		printf ("%d\n", A[i]);
	}

	printf ("%d possible numbers :\n", nposs );
	for ( i=1; i<=nposs; ++i ) {
		printf ("%d\n", poss_num[i]);
	}

	for ( i=1; i<=N; ++i ) {
		printf ("Frequency of %d is %d\n", A[i], f[ A[i] ] );
	}

	for ( i=1; i<=nposs; ++i ) {
		printf ("Appearances of %d\n", poss_num[i]);
		for ( int j=0; j<appear[i].size(); ++j ) {
			printf("%d ", appear[i][j]);
		}
		printf ("\n");
	}
}

void Read() {
	int i;

	scanf ("%d %d", &N, &M);
	for ( i=1; i<=N; ++i ) {
		scanf ("%d", &A[i]);
	}
}

void Frequencies() {
	int i;

	for ( i=1; i<=N; ++i ) {
		if ( A[i] <= N ) {
			++f[ A[i] ];
		}
	}
}

void Possible_Nums() {
	int i;

	for ( i=1; i<=N; ++i ) {
		if ( f[i] >= i ) {
			poss_num[ ++nposs ] = i;
		}
	}
}

int Position ( int x ) {
	int lo, mid, hi;

	lo = 1;
	hi = nposs;
	while ( lo < hi ) {
		mid = (lo+hi+1) / 2;
		if ( poss_num[ mid ] <= x ) {
			lo = mid;
		}
		else {
			hi = mid-1;
		}
	}

	return lo;
}

void Appear() {
	int i, pos;

	for ( i=1; i<=N; ++i ) {
		if ( A[i] <= N && f[ A[i] ] >= A[i] ) {
			pos = Position(A[i]);
			appear[ pos ][i] = 1;
		}
	}
}

void Make_Sums() {
	int i, j;

	for ( i=1; i<=nposs; ++i ) {
		for ( j=1; j<=N; ++j ) {
			sums[i][j] = sums[i][j-1] + appear[i][j];
		}
	}

}

void Answer_Queries() {
	int i, from, to, lo, hi, ans, possible;

	for ( i=1; i<=M; ++i ) {
		scanf ("%d %d", &from, &to);
		ans = 0;

		for ( possible = 1; possible <= nposs; ++possible ) {
			if ( sums[possible][hi]-sums[possible][lo-1] == poss_num[ possible ] ) {
				++ans;
			}
		}

		printf ("%d\n", ans );
	}
}

int main ( void ) {

	Read();
	Frequencies();
	Possible_Nums();
	Appear();
	//Test();
	Answer_Queries();

	return 0;
}


// http://codeforces.com/problemset/status
#include <cstdio>
#include <vector>

#define MAXN 100005
#define SQRMAXN 451
#define pb push_back

using namespace std;

int N, M, A[MAXN], f[MAXN], nposs, poss_num[SQRMAXN];
int sums[SQRMAXN][MAXN];
char appear[SQRMAXN][MAXN];

void Test() {
	int i;

	printf ("Array :\n");
	for ( i=1; i<=N; ++i ) {
		printf ("%d\n", A[i]);
	}

	printf ("%d possible numbers : \n", nposs );
	for ( i=1; i<=nposs; ++i ) {
		printf ("%d\n", poss_num[i]);
	}

	for ( i=1; i<=N; ++i ) {
		printf ("Frequency of %d is %d\n", A[i], f[ A[i] ] );
	}
}

void Read() {
	int i;

	scanf ("%d %d", &N, &M);
	for ( i=1; i<=N; ++i ) {
		scanf ("%d", &A[i]);
	}
}

void Frequencies() {
	int i;

	for ( i=1; i<=N; ++i ) {
		if ( A[i] <= N ) {
			++f[ A[i] ];
		}
	}
}

void Possible_Nums() {
	int i;

	for ( i=1; i<=N; ++i ) {
		if ( f[i] >= i ) {
			poss_num[ ++nposs ] = i;
		}
	}
}

int Position ( int x ) {
	int lo, mid, hi;

	lo = 1;
	hi = nposs;
	while ( lo < hi ) {
		mid = (lo+hi+1) / 2;
		if ( poss_num[ mid ] <= x ) {
			lo = mid;
		}
		else {
			hi = mid-1;
		}
	}

	return lo;
}

void Appear() {
	int i, pos;

	for ( i=1; i<=N; ++i ) {
		if ( A[i] <= N && f[ A[i] ] >= A[i] ) {
			pos = Position(A[i]);
			appear[ pos ][i] = 1;
		}
	}
}

void Make_Sums() {
	int i, j;

	for ( i=1; i<=nposs; ++i ) {
		for ( j=1; j<=N; ++j ) {
			sums[i][j] = sums[i][j-1] + appear[i][j];
		}
	}

}

void Answer_Queries() {
	int i, from, to, ans, possible;

	for ( i=1; i<=M; ++i ) {
		scanf ("%d %d", &from, &to);
		ans = 0;

		for ( possible = 1; possible <= nposs; ++possible ) {
			if ( sums[possible][to]-sums[possible][from-1] == poss_num[ possible ] ) {
				++ans;
			}
		}

		printf ("%d\n", ans );
	}
}

int main ( void ) {

	Read();
	Frequencies();
	Possible_Nums();
	Appear();
	Make_Sums();
	//Test();
	Answer_Queries();

	return (0);
}


#include <cstdio>
#include <vector>

#define MAXN 100005
#define SQRMAXN 500
#define INF 0x3f3f3f3f
#define pb push_back

using namespace std;

int N, M, A[MAXN], f[MAXN], nposs, poss_num[SQRMAXN];
vector<int> appear[MAXN];

void Test() {
	int i;

	printf ("Array :\n");
	for ( i=1; i<=N; ++i ) {
		printf ("%d\n", A[i]);
	}

	printf ("%d possible numbers :\n", nposs );
	for ( i=1; i<=nposs; ++i ) {
		printf ("%d\n", poss_num[i]);
	}

	for ( i=1; i<=N; ++i ) {
		printf ("Frequency of %d is %d\n", A[i], f[ A[i] ] );
	}

	for ( i=1; i<=nposs; ++i ) {
		printf ("Appearances of %d\n", poss_num[i]);
		for ( int j=0; j<appear[i].size(); ++j ) {
			printf("%d ", appear[i][j]);
		}
		printf ("\n");
	}
}

void Read() {
	int i;

	scanf ("%d %d", &N, &M);
	for ( i=1; i<=N; ++i ) {
		scanf ("%d", &A[i]);
	}
}

void Frequencies() {
	int i;

	for ( i=1; i<=N; ++i ) {
		if ( A[i] < MAXN ) {
			++f[ A[i] ];
		}
	}
}

void Possible_Nums() {
	int i;

	for ( i=1; i<MAXN; ++i ) {
		if ( f[i] >= i ) {
			poss_num[ ++nposs ] = i;
		}
	}
}

int Position ( int x ) {
	int lo, mid, hi;

	lo = 1;
	hi = nposs;
	while ( lo < hi ) {
		mid = (lo+hi+1) / 2;
		if ( poss_num[ mid ] <= x ) {
			lo = mid;
		}
		else {
			hi = mid-1;
		}
	}

	return lo;
}

void Appear() {
	int i, pos;

	for ( i=1; i<=N; ++i ) {
		if ( A[i] <= MAXN && f[ A[i] ] >= A[i] ) {
			pos = Position(A[i]);
			appear[ A[i] ].pb (i);
		}
	}
}

int Lower_Bound ( int from, int x ) {
	int lo, mid, hi;

	lo = 0;
	hi = appear[x].size()-1;
	while ( lo < hi ) {
		mid = (lo+hi+1) / 2;
		if ( appear[x][mid] <= from ) {
			lo = mid;
		}
		else {
			hi = mid-1;
		}
	}

	return appear[x][lo] >= from ? lo : INF;
}

int Upper_Bound ( int to, int x ) {
	int lo, mid, hi;

	lo = 0;
	hi = appear[x].size()-1;
	while ( lo < hi ) {
		mid = (lo+hi) / 2;
		if ( appear[x][mid] >= to ) {
			hi = mid;
		}
		else {
			lo = mid+1;
		}
	}

	return appear[x][lo] <= to ? lo : -INF;
}

void Answer_Queries() {
	int i, from, to, lo, hi, ans, possible;

	for ( i=1; i<=M; ++i ) {
		scanf ("%d %d", &from, &to);
		ans = 0;

		for ( possible = 1; possible <= nposs; ++possible ) {
			lo = Lower_Bound ( from, possible );
			hi = Upper_Bound ( to, possible );
			//printf ("Num %d, low %d, hi %d\n", poss_num[possible],lo,hi);
			if ( hi-lo+1 == poss_num[ possible ] ) {
				++ans;
			}
		}

		printf ("%d\n", ans );
	}
}

int main ( void ) {

	Read();
	Frequencies();
	Possible_Nums();
	Appear();
	//Test();
	Answer_Queries();

	return 0;
}


#include <cstdio>
#include <vector>

#define MAXN 100005
#define SQRMAXN 700
#define INF 0x3f3f3f3f
#define pb push_back

using namespace std;

int N, M, A[MAXN], f[MAXN], nposs, poss_num[SQRMAXN];
vector<int> appear[SQRMAXN];

void Test() {
	int i;

	printf ("Array :\n");
	for ( i=1; i<=N; ++i ) {
		printf ("%d\n", A[i]);
	}

	printf ("%d possible numbers :\n", nposs );
	for ( i=1; i<=nposs; ++i ) {
		printf ("%d\n", poss_num[i]);
	}

	for ( i=1; i<=N; ++i ) {
		printf ("Frequency of %d is %d\n", A[i], f[ A[i] ] );
	}

	for ( i=1; i<=nposs; ++i ) {
		printf ("Appearances of %d\n", poss_num[i]);
		for ( int j=0; j<appear[i].size(); ++j ) {
			printf("%d ", appear[i][j]);
		}
		printf ("\n");
	}
}

void Read() {
	int i;

	scanf ("%d %d", &N, &M);
	for ( i=1; i<=N; ++i ) {
		scanf ("%d", &A[i]);
	}
}

void Frequencies() {
	int i;

	for ( i=1; i<=N; ++i ) {
		if ( A[i] < MAXN ) {
			++f[ A[i] ];
		}
	}
}

void Possible_Nums() {
	int i;

	for ( i=1; i<MAXN; ++i ) {
		if ( f[i] >= i ) {
			poss_num[ ++nposs ] = i;
		}
	}
}

int Position ( int x ) {
	int lo, mid, hi;

	lo = 1;
	hi = nposs;
	while ( lo < hi ) {
		mid = (lo+hi+1) / 2;
		if ( poss_num[ mid ] <= x ) {
			lo = mid;
		}
		else {
			hi = mid-1;
		}
	}

	return lo;
}

void Appear() {
	int i, pos;

	for ( i=1; i<=N; ++i ) {
		if ( A[i] < MAXN && f[ A[i] ] >= A[i] ) {
			pos = Position(A[i]);
			appear[ A[i] ].pb (i);
		}
	}
}

int Lower_Bound ( int from, int x ) {
	int lo, mid, hi;

	lo = 0;
	hi = appear[x].size()-1;
	while ( lo < hi ) {
		mid = (lo+hi) / 2;
		if ( appear[x][mid] >= from ) {
			hi = mid;
		}
		else {
			lo = mid+1;
		}
	}

	return appear[x][lo] >= from ? lo : INF;
}

int Upper_Bound ( int to, int x ) {
	int lo, mid, hi;

	lo = 0;
	hi = appear[x].size()-1;
	while ( lo < hi ) {
		mid = (lo+hi+1) / 2;
		if ( appear[x][mid] <= to ) {
			lo = mid;
		}
		else {
			hi = mid-1;
		}
	}

	return appear[x][lo] <= to ? lo : -INF;
}

void Answer_Queries() {
	int i, from, to, lo, hi, ans, possible;

	for ( i=1; i<=M; ++i ) {
		scanf ("%d %d", &from, &to);
		ans = 0;

		for ( possible = 1; possible <= nposs; ++possible ) {
			lo = Lower_Bound ( from, possible );
			hi = Upper_Bound ( to, possible );
			//printf ("Num %d, low %d, hi %d\n", poss_num[possible],lo,hi);
			if ( hi-lo+1 == poss_num[ possible ] ) {
				++ans;
			}
		}

		printf ("%d\n", ans );
	}
}

int main ( void ) {

	Read();
	Frequencies();
	Possible_Nums();
	Appear();
	//Test();
	Answer_Queries();

	return 0;
}


#include <cstdio>
#include <vector>

#define MAXN 100005
#define SQRMAXN 700
#define INF 0x3f3f3f3f
#define pb push_back

using namespace std;

int N, M, A[MAXN], f[MAXN], nposs, poss_num[SQRMAXN];
int sums[SQRMAXN][MAXN], appear[SQRMAXN][MAXN];

void Test() {
	int i;

	printf ("Array :\n");
	for ( i=1; i<=N; ++i ) {
		printf ("%d\n", A[i]);
	}

	printf ("%d possible numbers :\n", nposs );
	for ( i=1; i<=nposs; ++i ) {
		printf ("%d\n", poss_num[i]);
	}

	for ( i=1; i<=N; ++i ) {
		printf ("Frequency of %d is %d\n", A[i], f[ A[i] ] );
	}
}

void Read() {
	int i;

	scanf ("%d %d", &N, &M);
	for ( i=1; i<=N; ++i ) {
		scanf ("%d", &A[i]);
	}
}

void Frequencies() {
	int i;

	for ( i=1; i<=N; ++i ) {
		if ( A[i] <= N ) {
			++f[ A[i] ];
		}
	}
}

void Possible_Nums() {
	int i;

	for ( i=1; i<=N; ++i ) {
		if ( f[i] >= i ) {
			poss_num[ ++nposs ] = i;
		}
	}
}

int Position ( int x ) {
	int lo, mid, hi;

	lo = 1;
	hi = nposs;
	while ( lo < hi ) {
		mid = (lo+hi+1) / 2;
		if ( poss_num[ mid ] <= x ) {
			lo = mid;
		}
		else {
			hi = mid-1;
		}
	}

	return lo;
}

void Appear() {
	int i, pos;

	for ( i=1; i<=N; ++i ) {
		if ( A[i] <= N && f[ A[i] ] >= A[i] ) {
			pos = Position(A[i]);
			appear[ pos ][i] = 1;
		}
	}
}

void Make_Sums() {
	int i, j;

	for ( i=1; i<=nposs; ++i ) {
		for ( j=1; j<=N; ++j ) {
			sums[i][j] = sums[i][j-1] + appear[i][j];
		}
	}

}

void Answer_Queries() {
	int i, from, to, lo, hi, ans, possible;

	for ( i=1; i<=M; ++i ) {
		scanf ("%d %d", &from, &to);
		ans = 0;

		for ( possible = 1; possible <= nposs; ++possible ) {
			if ( sums[possible][hi]-sums[possible][lo-1] == poss_num[ possible ] ) {
				++ans;
			}
		}

		printf ("%d\n", ans );
	}
}

int main ( void ) {

	Read();
	Frequencies();
	Possible_Nums();
	Appear();
	Make_Sums();
	//Test();
	Answer_Queries();

	return 0;
}


// http://codeforces.com/problemset/status
#include <cstdio>
#include <vector>

#define MAXN 100005
#define SQRMAXN 451
#define pb push_back

using namespace std;

int N, M, A[MAXN], f[MAXN], nposs, poss_num[SQRMAXN];
int sums[SQRMAXN][MAXN];
char appear[SQRMAXN][MAXN];

void Test() {
	int i;

	printf ("Array :\n");
	for ( i=1; i<=N; ++i ) {
		printf ("%d\n", A[i]);
	}

	printf ("%d possible numbers :\n", nposs );
	for ( i=1; i<=nposs; ++i ) {
		printf ("%d\n", poss_num[i]);
	}

	for ( i=1; i<=N; ++i ) {
		printf ("Frequency of %d is %d\n", A[i], f[ A[i] ] );
	}
}

void Read() {
	int i;

	scanf ("%d %d", &N, &M);
	for ( i=1; i<=N; ++i ) {
		scanf ("%d", &A[i]);
	}
}

void Frequencies() {
	int i;

	for ( i=1; i<=N; ++i ) {
		if ( A[i] <= N ) {
			++f[ A[i] ];
		}
	}
}

void Possible_Nums() {
	int i;

	for ( i=1; i<=N; ++i ) {
		if ( f[i] >= i ) {
			poss_num[ ++nposs ] = i;
		}
	}
}

int Position ( int x ) {
	int lo, mid, hi;

	lo = 1;
	hi = nposs;
	while ( lo < hi ) {
		mid = (lo+hi+1) / 2;
		if ( poss_num[ mid ] <= x ) {
			lo = mid;
		}
		else {
			hi = mid-1;
		}
	}

	return lo;
}

void Appear() {
	int i, pos;

	for ( i=1; i<=N; ++i ) {
		if ( A[i] <= N && f[ A[i] ] >= A[i] ) {
			pos = Position(A[i]);
			appear[ pos ][i] = 1;
		}
	}
}

void Make_Sums() {
	int i, j;

	for ( i=1; i<=nposs; ++i ) {
		for ( j=1; j<=N; ++j ) {
			sums[i][j] = sums[i][j-1] + appear[i][j];
		}
	}

}

void Answer_Queries() {
	int i, from, to, ans, possible;

	for ( i=1; i<=M; ++i ) {
		scanf ("%d %d", &from, &to);
		ans = 0;

		for ( possible = 1; possible <= nposs; ++possible ) {
			if ( sums[possible][to]-sums[possible][from-1] == poss_num[ possible ] ) {
				++ans;
			}
		}

		printf ("%d\n", ans );
	}
}

int main ( void ) {

	Read();
	Frequencies();
	Possible_Nums();
	Appear();
	Make_Sums();
	//Test();
	Answer_Queries();

	return (0);
}


#include <cstdio>
#include <vector>

#define MAXN 100005
#define SQRMAXN 500
#define INF 0x3f3f3f3f
#define pb push_back

using namespace std;

int N, M, A[MAXN], f[MAXN], nposs, poss_num[SQRMAXN];
vector<int> appear[MAXN];

void Test() {
	int i;

	printf ("Array :\n");
	for ( i=1; i<=N; ++i ) {
		printf ("%d\n", A[i]);
	}

	printf ("%d possible numbers :\n", nposs );
	for ( i=1; i<=nposs; ++i ) {
		printf ("%d\n", poss_num[i]);
	}

	for ( i=1; i<=N; ++i ) {
		printf ("Frequency of %d is %d\n", A[i], f[ A[i] ] );
	}

	for ( i=1; i<=nposs; ++i ) {
		printf ("Appearances of %d\n", poss_num[i]);
		for ( int j=0; j<appear[i].size(); ++j ) {
			printf("%d ", appear[i][j]);
		}
		printf ("\n");
	}
}

void Read() {
	int i;

	scanf ("%d %d", &N, &M);
	for ( i=1; i<=N; ++i ) {
		scanf ("%d", &A[i]);
	}
}

void Frequencies() {
	int i;

	for ( i=1; i<=N; ++i ) {
		if ( A[i] < MAXN ) {
			++f[ A[i] ];
		}
	}
}

void Possible_Nums() {
	int i;

	for ( i=1; i<MAXN; ++i ) {
		if ( f[i] >= i ) {
			poss_num[ ++nposs ] = i;
		}
	}
}

int Position ( int x ) {
	int lo, mid, hi;

	lo = 1;
	hi = nposs;
	while ( lo < hi ) {
		mid = (lo+hi+1) / 2;
		if ( poss_num[ mid ] <= x ) {
			lo = mid;
		}
		else {
			hi = mid-1;
		}
	}

	return lo;
}

void Appear() {
	int i, pos;

	for ( i=1; i<=N; ++i ) {
		if ( A[i] < MAXN && f[ A[i] ] >= A[i] ) {
			pos = Position(A[i]);
			appear[ A[i] ].pb (i);
		}
	}
}

int Lower_Bound ( int from, int x ) {
	int lo, mid, hi;

	lo = 0;
	hi = appear[x].size()-1;
	while ( lo < hi ) {
		mid = (lo+hi) / 2;
		if ( appear[x][mid] >= from ) {
			hi = mid;
		}
		else {
			lo = mid+1;
		}
	}

	return appear[x][lo] >= from ? lo : INF;
}

int Upper_Bound ( int to, int x ) {
	int lo, mid, hi;

	lo = 0;
	hi = appear[x].size()-1;
	while ( lo < hi ) {
		mid = (lo+hi+1) / 2;
		if ( appear[x][mid] <= to ) {
			lo = mid;
		}
		else {
			hi = mid-1;
		}
	}

	return appear[x][lo] <= to ? lo : -INF;
}

void Answer_Queries() {
	int i, from, to, lo, hi, ans, possible;

	for ( i=1; i<=M; ++i ) {
		scanf ("%d %d", &from, &to);
		ans = 0;

		for ( possible = 1; possible <= nposs; ++possible ) {
			lo = Lower_Bound ( from, possible );
			hi = Upper_Bound ( to, possible );
			//printf ("Num %d, low %d, hi %d\n", poss_num[possible],lo,hi);
			if ( hi-lo+1 == poss_num[ possible ] ) {
				++ans;
			}
		}

		printf ("%d\n", ans );
	}
}

int main ( void ) {

	Read();
	Frequencies();
	Possible_Nums();
	Appear();
	//Test();
	Answer_Queries();

	return 0;
}


#include <cstdio>
#include <vector>

#define MAXN 100005
#define SQRMAXN 450
#define INF 0x3f3f3f3f
#define pb push_back

using namespace std;

int N, M, A[MAXN], f[MAXN], nposs, poss_num[SQRMAXN];
int sums[SQRMAXN][MAXN];
char appear[SQRMAXN][MAXN];

void Test() {
	int i;

	printf ("Array :\n");
	for ( i=1; i<=N; ++i ) {
		printf ("%d\n", A[i]);
	}

	printf ("%d possible numbers :\n", nposs );
	for ( i=1; i<=nposs; ++i ) {
		printf ("%d\n", poss_num[i]);
	}

	for ( i=1; i<=N; ++i ) {
		printf ("Frequency of %d is %d\n", A[i], f[ A[i] ] );
	}
}

void Read() {
	int i;

	scanf ("%d %d", &N, &M);
	for ( i=1; i<=N; ++i ) {
		scanf ("%d", &A[i]);
	}
}

void Frequencies() {
	int i;

	for ( i=1; i<=N; ++i ) {
		if ( A[i] <= N ) {
			++f[ A[i] ];
		}
	}
}

void Possible_Nums() {
	int i;

	for ( i=1; i<=N; ++i ) {
		if ( f[i] >= i ) {
			poss_num[ ++nposs ] = i;
		}
	}
}

int Position ( int x ) {
	int lo, mid, hi;

	lo = 1;
	hi = nposs;
	while ( lo < hi ) {
		mid = (lo+hi+1) / 2;
		if ( poss_num[ mid ] <= x ) {
			lo = mid;
		}
		else {
			hi = mid-1;
		}
	}

	return lo;
}

void Appear() {
	int i, pos;

	for ( i=1; i<=N; ++i ) {
		if ( A[i] <= N && f[ A[i] ] >= A[i] ) {
			pos = Position(A[i]);
			appear[ pos ][i] = 1;
		}
	}
}

void Make_Sums() {
	int i, j;

	for ( i=1; i<=nposs; ++i ) {
		for ( j=1; j<=N; ++j ) {
			sums[i][j] = sums[i][j-1] + appear[i][j];
		}
	}

}

void Answer_Queries() {
	int i, from, to, ans, possible;

	for ( i=1; i<=M; ++i ) {
		scanf ("%d %d", &from, &to);
		ans = 0;

		for ( possible = 1; possible <= nposs; ++possible ) {
			if ( sums[possible][to]-sums[possible][from-1] == poss_num[ possible ] ) {
				++ans;
			}
		}

		printf ("%d\n", ans );
	}
}

int main ( void ) {

	Read();
	Frequencies();
	Possible_Nums();
	Appear();
	Make_Sums();
	//Test();
	Answer_Queries();

	return 0;
}


#include <cstdio>
#include <vector>

#define MAXN 100005
#define SQRMAXN 500
#define INF 0x3f3f3f3f
#define pb push_back

using namespace std;

int N, M, A[MAXN], f[MAXN], nposs, poss_num[SQRMAXN];
vector<int> appear[MAXN];

void Test() {
	int i;

	printf ("Array :\n");
	for ( i=1; i<=N; ++i ) {
		printf ("%d\n", A[i]);
	}

	printf ("%d possible numbers :\n", nposs );
	for ( i=1; i<=nposs; ++i ) {
		printf ("%d\n", poss_num[i]);
	}

	for ( i=1; i<=N; ++i ) {
		printf ("Frequency of %d is %d\n", A[i], f[ A[i] ] );
	}

	for ( i=1; i<=nposs; ++i ) {
		printf ("Appearances of %d\n", poss_num[i]);
		for ( int j=0; j<appear[i].size(); ++j ) {
			printf("%d ", appear[i][j]);
		}
		printf ("\n");
	}
}

void Read() {
	int i;

	scanf ("%d %d", &N, &M);
	for ( i=1; i<=N; ++i ) {
		scanf ("%d", &A[i]);
	}
}

void Frequencies() {
	int i;

	for ( i=1; i<=N; ++i ) {
		if ( A[i] < MAXN ) {
			++f[ A[i] ];
		}
	}
}

void Possible_Nums() {
	int i;

	for ( i=1; i<MAXN; ++i ) {
		if ( f[i] >= i ) {
			poss_num[ ++nposs ] = i;
		}
	}
}

int Position ( int x ) {
	int lo, mid, hi;

	lo = 1;
	hi = nposs;
	while ( lo < hi ) {
		mid = (lo+hi+1) / 2;
		if ( poss_num[ mid ] <= x ) {
			lo = mid;
		}
		else {
			hi = mid-1;
		}
	}

	return lo;
}

void Appear() {
	int i, pos;

	for ( i=1; i<=N; ++i ) {
		if ( A[i] < MAXN && f[ A[i] ] >= A[i] ) {
			pos = Position(A[i]);
			appear[ A[i] ].pb (i);
		}
	}
}

int Lower_Bound ( int from, int x ) {
	int lo, mid, hi;

	lo = 0;
	hi = appear[x].size()-1;
	while ( lo < hi ) {
		mid = (lo+hi+1) / 2;
		if ( appear[x][mid] <= from ) {
			lo = mid;
		}
		else {
			hi = mid-1;
		}
	}

	return appear[x][lo] >= from ? lo : INF;
}

int Upper_Bound ( int to, int x ) {
	int lo, mid, hi;

	lo = 0;
	hi = appear[x].size()-1;
	while ( lo < hi ) {
		mid = (lo+hi) / 2;
		if ( appear[x][mid] >= to ) {
			hi = mid;
		}
		else {
			lo = mid+1;
		}
	}

	return appear[x][lo] <= to ? lo : -INF;
}

void Answer_Queries() {
	int i, from, to, lo, hi, ans, possible;

	for ( i=1; i<=M; ++i ) {
		scanf ("%d %d", &from, &to);
		ans = 0;

		for ( possible = 1; possible <= nposs; ++possible ) {
			lo = Lower_Bound ( from, possible );
			hi = Upper_Bound ( to, possible );
			//printf ("Num %d, low %d, hi %d\n", poss_num[possible],lo,hi);
			if ( hi-lo+1 == poss_num[ possible ] ) {
				++ans;
			}
		}

		printf ("%d\n", ans );
	}
}

int main ( void ) {

	Read();
	Frequencies();
	Possible_Nums();
	Appear();
	//Test();
	Answer_Queries();

	return 0;
}