#include <bits/stdc++.h>   #pragma GCC optimize( Ofast )   #pragma GCC optimization( unroll-loops, no-stack-protector )   #pragma GCC target( avx,avx2,fma )   using namespace std;   using pii = pair<int, int>;   using pll = pair<long long, long long>;   using vb = vector<bool>;   using vi = vector<int>;   using vl = vector<long long>;   using vvb = vector<vector<bool>>;   using vvi = vector<vector<int>>;   using vvl = vector<vector<long long>>;   using vpii = vector<pair<int, int>>;   using mii = map<int, int>;   using umii = unordered_map<int, int>;   using seti = set<int>;   using useti = unordered_set<int>;   template <typename... ArgTypes>   void print(ArgTypes... args);   template <typename... ArgTypes>   void input(ArgTypes &...args);   template <>   void print() {}   template <>   void input() {}   template <typename T, typename... ArgTypes>   void print(T t, ArgTypes... args) {     cout << t;     print(args...);   }   template <typename T, typename... ArgTypes>   void input(T &t, ArgTypes &...args) {     cin >> t;     input(args...);   }   template <class T>   T OP(T a, T b) {     if (a.first > b.first) return b;     if (a.first == b.first && b.second > a.second) return b;     return a;   }   template <class T>   class SegmentTree {    private:     void propagate(int node, T val, int nodes) {       tree[node].first += val.first;       lazy[node].first += val.first;     }     T buildUtil(vector<T> &a, int node, int l, int r) {       if (l == r) {         tree[node] = a[l];         return tree[node];       }       int mid = (l + r) >> 1;       int leftNode = (node << 1) + 1;       int rightNode = leftNode + 1;       return tree[node] = OP(buildUtil(a, leftNode, l, mid),                              buildUtil(a, rightNode, mid + 1, r));     }     T queryUtil(int node, int l, int r, int ql, int qr) {       if (ql > r || qr < l) return (T)make_pair(1000000005, -1);       if (l >= ql && r <= qr) return tree[node];       int mid = (l + r) >> 1;       int leftNode = (node << 1) + 1;       int rightNode = leftNode + 1;       if (lazy[node].first) {         propagate(leftNode, lazy[node], mid - l + 1);         propagate(rightNode, lazy[node], r - mid);         lazy[node].first = 0;       }       return OP(queryUtil(leftNode, l, mid, ql, qr),                 queryUtil(rightNode, mid + 1, r, ql, qr));     }     T updateUtil(int node, int l, int r, int ql, int qr, T val) {       if (ql > r || qr < l) return tree[node];       if (l >= ql && r <= qr) {         tree[node].first += val.first;         lazy[node].first += val.first;         return tree[node];       }       int mid = (l + r) >> 1;       int leftNode = (node << 1) + 1;       int rightNode = leftNode + 1;       if (lazy[node].first) {         propagate(leftNode, lazy[node], mid - l + 1);         propagate(rightNode, lazy[node], r - mid);         lazy[node].first = 0;       }       return tree[node] = OP(updateUtil(leftNode, l, mid, ql, qr, val),                              updateUtil(rightNode, mid + 1, r, ql, qr, val));     }       public:     int n;     vector<T> tree;     vector<T> lazy;     SegmentTree(int n) {       this->n = n;       tree = vector<T>(4 * n);       lazy = vector<T>(4 * n);     }     void build(vector<T> &a) { buildUtil(a, 0, 0, n - 1); }     SegmentTree(vector<T> &a) {       this->n = a.size();       tree = vector<T>(4 * n);       lazy = vector<T>(4 * n);       build(a);     }     T query(int l, int r) { return queryUtil(0, 0, n - 1, l, r); }     void update(int l, int r, T val) { updateUtil(0, 0, n - 1, l, r, val); }   };   template <class T, class OP>   class FST {     vector<T> t;     void build() {       for (int i = n - 1; i > 0; --i) t[i] = OP()(t[i << 1], t[i << 1 | 1]);     }       public:     int n;     FST(int nn) {       n = nn;       t = vector<T>(n << 1);     }     FST(vector<T> v) {       n = v.size();       t = vector<T>(n << 1);       for (int i = 0; i < n; ++i) t[i + n] = v[i];       build();     }     void update(int p, T value) {       value += query(p, p);       for (t[p += n] = value; p > 1; p >>= 1) t[p >> 1] = OP()(t[p], t[p ^ 1]);     }     T query(int l, int r) {       r++;       T res = OP::initVal;       for (l += n, r += n; l < r; l >>= 1, r >>= 1) {         if (l & 1) res = OP()(res, t[l++]);         if (r & 1) res = OP()(res, t[--r]);       }       return res;     }   };   template <class T>   class Add {    public:     static const T initVal = T(0);     T operator()(T x, T y) { return x + y; }   };   int main() {     ios_base::sync_with_stdio(0);     cin.tie(0);     int n, q;     cin >> n >> q;     vpii a(n);     for (int i = 0; i < (n); (i)++) {       cin >> a[i].first;       a[i].second = i + 1;       a[i].first = a[i].second - a[i].first;       if (a[i].first < 0) a[i].first = 1000000005;     }     SegmentTree<pii> st(a);     vi seq(n, -1);     vi taken(n);     int parent = n;     while (1) {       auto d = st.query(0, n - 1);       if (d.first != 0) break;       seq[d.second - 1] = parent;       parent = min(parent, d.second - 1);       taken[d.second - 1] = 1;       st.update(d.second - 1, n - 1, {-1, 0});       st.update(d.second - 1, d.second - 1, {1000000005 + 1, 0});     }     FST<int, Add<int>> track(n + 3);     vector<pair<pii, pii>> queries;     for (int qq = 0; qq < (q); (qq)++) {       int x, y;       cin >> x >> y;       int l = x;       int r = n - 1 - y;       queries.push_back({{l, r}, {qq, 0}});     }     int sq = (int)sqrt(q);     sort((queries).begin(), (queries).end(),          [=](pair<pii, pii> x, pair<pii, pii> y) -> bool {            int blockX = x.first.first / sq;            int blockY = y.first.first / sq;            if (blockX < blockY) return true;            if (blockX == blockY)              return (blockX & 1) ^ (x.first.second < y.first.second);            return false;          });     int l = 0, r = 0;     if (seq[0] != -1) track.update(seq[0], 1);     for (pair<pii, pii> &qq : queries) {       int x = qq.first.first;       int y = qq.first.second;       while (l < x) {         int d = seq[l];         l++;         if (d != -1) track.update(d, -1);       }       while (l > x) {         int d = seq[l - 1];         l--;         if (d != -1) track.update(d, 1);       }       while (r < y) {         int d = seq[r + 1];         r++;         if (d != -1) track.update(d, 1);       }       while (r > y) {         int d = seq[r];         r--;         if (d != -1) track.update(d, -1);       }       int temp = 0;       if (x != 0) temp = track.query(0, x - 1);       qq.second.second = track.query(0, n + 1) - temp;     }     sort((queries).begin(), (queries).end(),          [=](pair<pii, pii> x, pair<pii, pii> y) -> bool {            return x.second.first < y.second.first;          });     for (auto qq : queries) cout << qq.second.second <<   n ;   }