#include <bits/stdc++.h>
using namespace std;
const int maxn = 3e5 + 10;
const int inf = 0x3f3f3f3f;
struct node {
  int l, r, sum;
} tree[maxn << 2];
int ans[maxn], a[maxn];
vector<pair<int, int> > q[maxn];
void build(int root, int l, int r) {
  tree[root].l = l;
  tree[root].r = r;
  tree[root].sum = 0;
  if (l == r) return;
  int mid = (l + r) >> 1;
  build(root << 1, l, mid);
  build(root << 1 | 1, mid + 1, r);
}
void update(int root, int x) {
  if (tree[root].l == tree[root].r) {
    tree[root].sum++;
    return;
  }
  int mid = (tree[root].l + tree[root].r) >> 1;
  if (x <= mid)
    update(root << 1, x);
  else
    update(root << 1 | 1, x);
  tree[root].sum = tree[root << 1].sum + tree[root << 1 | 1].sum;
}
int que_k(int k, int x) {
  if (tree[k].l == tree[k].r) return tree[k].l;
  if (tree[k << 1 | 1].sum >= x)
    return que_k(k << 1 | 1, x);
  else
    return que_k(k << 1, x - tree[k << 1 | 1].sum);
}
int que(int root, int l, int r) {
  if (l <= tree[root].l && tree[root].r <= r) return tree[root].sum;
  int mid = (tree[root].l + tree[root].r) >> 1;
  if (l > mid)
    return que(root << 1 | 1, l, r);
  else if (r <= mid)
    return que(root << 1, l, r);
  else
    return que(root << 1, l, mid) + que(root << 1 | 1, mid + 1, r);
}
int main() {
  int n, m, l, r;
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= n; i++) {
    scanf("%d", &a[i]);
    a[i] = i - a[i];
    if (a[i] < 0) a[i] = inf;
  }
  for (int i = 1; i <= m; i++) {
    scanf("%d%d", &l, &r);
    l++;
    r = n - r;
    q[r].emplace_back(l, i);
  }
  build(1, 1, n);
  int num = 0;
  for (int i = 1; i <= n; i++) {
    if (a[i] == 0)
      update(1, i), num++;
    else if (num >= a[i])
      update(1, que_k(1, a[i])), num++;
    for (pair<int, int> t : q[i]) ans[t.second] = que(1, t.first, n);
  }
  for (int i = 1; i <= m; i++) printf("%d\n", ans[i]);
}
