#include <bits/stdc++.h>
using namespace std;
const int MAXN = 3e5;
int N, Q, A[MAXN + 10], dp[MAXN + 10];
int tree[MAXN * 4 + 10];
void update2(int node, int tl, int tr, int y) {
  tree[node]++;
  if (tl == tr) return;
  int mid = tl + tr >> 1;
  if (y <= mid)
    update2(node * 2, tl, mid, y);
  else
    update2(node * 2 + 1, mid + 1, tr, y);
}
int query2(int node, int tl, int tr, int k) {
  if (tl == tr) return tl;
  int val = tree[node * 2 + 1];
  int mid = tl + tr >> 1;
  if (val >= k)
    return query2(node * 2 + 1, mid + 1, tr, k);
  else
    return query2(node * 2, tl, mid, k - val);
}
struct Data {
  int l, r, p;
};
Data B[MAXN + 10];
int tree2[MAXN + 10];
void update(int i) {
  for (; i <= N; i += (i & -i)) tree2[i]++;
}
int query(int i) {
  int ret = 0;
  for (; i > 0; i -= (i & -i)) ret += tree2[i];
  return ret;
}
int query(int l, int r) { return query(r) - query(l - 1); }
int ans[MAXN + 10];
int main() {
  scanf("%d%d", &N, &Q);
  for (int i = 1; i <= N; i++) scanf("%d", &A[i]);
  vector<pair<int, int> > V;
  for (int i = 1; i <= N; i++) {
    A[i] = i - A[i];
    if (A[i] < 0)
      ;
    else if (A[i] == 0) {
      dp[i] = i;
      update2(1, 0, N, dp[i]);
    } else {
      dp[i] = query2(1, 0, N, A[i]);
      update2(1, 0, N, dp[i]);
    }
    if (A[i] >= 0) V.push_back({dp[i], i});
  }
  sort(V.begin(), V.end());
  for (int i = 1; i <= Q; i++) {
    scanf("%d%d", &B[i].l, &B[i].r), B[i].p = i;
    B[i].l++;
    B[i].r = N - B[i].r;
  }
  sort(B + 1, B + Q + 1,
       [&](const Data &p, const Data &q) { return p.l < q.l; });
  for (int i = Q, j = V.size() - 1; i >= 1; i--) {
    for (; j >= 0 && V[j].first >= B[i].l; j--) {
      update(V[j].second);
    }
    ans[B[i].p] = query(B[i].l, B[i].r);
  }
  for (int i = 1; i <= Q; i++) printf("%d\n", ans[i]);
}
