Problem: There is an infinite pond that can be represented with a number line. There are n rocks in the pond, numbered from 1 to n. The i-th rock is located at an integer coordinate a_i. The coordinates of the rocks are pairwise distinct. The rocks are numbered in the increasing order of the coordinate, so a_1 < a_2 < ... < a_n.

A robot frog sits on the rock number s. The frog is programmable. It has a base jumping distance parameter d. There also is a setting for the jumping distance range. If the jumping distance range is set to some integer k, then the frog can jump from some rock to any rock at a distance from d - k to d + k inclusive in any direction. The distance between two rocks is an absolute difference between their coordinates.

You are assigned a task to implement a feature for the frog. Given two integers i and k determine if the frog can reach a rock number i from a rock number s performing a sequence of jumps with the jumping distance range set to k. The sequence can be arbitrarily long or empty.

You will be given q testcases for that feature, the j-th testcase consists of two integers i and k. Print "Yes" if the i-th rock is reachable and "No" otherwise.

You can output "YES" and "NO" in any case (for example, strings "yEs", "yes", "Yes" and 'YES"' will be recognized as a positive answer).

Input

The first line contains four integers n, q, s and d (1 ≤ n, q ≤ 2 ⋅ 10^5; 1 ≤ s ≤ n; 1 ≤ d ≤ 10^6) — the number of rocks, the number of testcases, the starting rock and the base jumping distance parameter.

The second line contains n integers a_1, a_2, ..., a_n (1 ≤ a_i ≤ 10^6) — the coordinates of the rocks. The coordinates of the rocks are pairwise distinct. The rocks are numbered in the increasing order of distance from the land, so a_1 < a_2 < ... < a_n.

Each of the next q lines contains two integers i and k (1 ≤ i ≤ n; 1 ≤ k ≤ 10^6) — the parameters to the testcase.

Output

For each of the testcases print an answer. If there is a sequence of jumps from a rock number s to a rock number i with the jumping distance range set to k, then print "Yes". Otherwise, print "No".

Examples

Input


7 4 4 5
1 5 10 13 20 22 28
4 1
7 2
7 3
3 2


Output


Yes
No
Yes
Yes


Input


10 8 6 11
1 2 4 7 8 9 11 13 19 20
2 13
5 8
8 1
6 15
1 15
2 7
7 6
8 9


Output


Yes
Yes
No
Yes
Yes
Yes
Yes
Yes


Input


6 9 6 6
1 2 4 9 18 19
2 17
1 18
5 4
2 11
5 17
6 8
4 3
3 3
6 6


Output


Yes
Yes
Yes
Yes
Yes
Yes
No
No
Yes


Input


4 1 1 10
1 8 10 19
2 1


Output


Yes

Note

Explanation of the first example:

In the first testcase the destination rock is the same as the starting rock, thus no jumps are required to reach it.

In the second testcase the frog can jump any distance in the range [5 - 2; 5 + 2]. Thus, it can reach rock number 5 (by jumping 7 to the right) and rock number 3 (by jumping 3 to the left). From rock number 3 it can reach rock number 2 (by jumping 5 to the left). From rock number 2 it can reach rock number 1 (by jumping 4 to the left). However, there is no way to reach rock number 7.

In the third testcase the frog can jump any distance in the range [5 - 3; 5 + 3]. Thus, it can reach rock number 7 by jumping to rock 5 first and to 7 afterwards.

The fourth testcase is shown in the explanation for the second testcase.

Solution (in CPP):

Solution:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <vector>
#include <set>
#include <algorithm>
#include <cassert>

using namespace std;

using ll = long long;

#define pii pair<int, int>
#define vi vector<int>
#define pb push_back
#define sz(v) ((int) (v).size())
#define all(x) (x).begin(), (x).end()
#define mp make_pair
#define fs first
#define sc second
#define next hunext

const int N = 2e5 + 100;
const int inf = 1e9;

struct td {
    int x, y, val, sz, l, r;
    int min_val, min_x, max_x;
    int min_upd, max_upd, min_const_upd;
};

int a[N], dp[N];
td d[N];

void init() {
    
}

td init_node(int x, int val) {
    td n;
    n.x = n.min_x = n.max_x = x;
    n.y = rand();
    n.val = n.min_val = val;
    n.sz = 1;
    n.l = n.r = -1;
    n.min_upd = inf;
    n.max_upd = -inf;
    n.min_const_upd = inf;
    return n;
}

void push(int v) {
    if (v == -1) {
        return;
    }
    d[v].val = min(d[v].val, d[v].min_upd - d[v].x);
    d[v].val = min(d[v].val, d[v].x - d[v].max_upd);
    d[v].val = min(d[v].val, d[v].min_const_upd);
    d[v].min_val = min(d[v].min_val, d[v].min_upd - d[v].max_x);
    d[v].min_val = min(d[v].min_val, d[v].min_x - d[v].max_upd);
    d[v].min_val = min(d[v].min_val, d[v].min_const_upd);
    if (d[v].l != -1) {
        d[d[v].l].min_upd = min(d[d[v].l].min_upd, d[v].min_upd);
        d[d[v].l].max_upd = max(d[d[v].l].max_upd, d[v].max_upd);
        d[d[v].l].min_const_upd = min(d[d[v].l].min_const_upd, d[v].min_const_upd);
    }
    if (d[v].r != -1) {
        d[d[v].r].min_upd = min(d[d[v].r].min_upd, d[v].min_upd);
        d[d[v].r].max_upd = max(d[d[v].r].max_upd, d[v].max_upd);
        d[d[v].r].min_const_upd = min(d[d[v].r].min_const_upd, d[v].min_const_upd);
    }
    d[v].min_upd = inf;
    d[v].max_upd = -inf;
    d[v].min_const_upd = inf;
}

void calc(int v) {
    if (v == -1) {
        return;
    }
    d[v].min_val = d[v].val;
    d[v].min_x = d[v].x;
    d[v].max_x = d[v].x;
    d[v].sz = 1;
    if (d[v].l != -1) {
        push(d[v].l);
        d[v].min_val = min(d[v].min_val, d[d[v].l].min_val);
        d[v].min_x = min(d[v].min_x, d[d[v].l].min_x);
        d[v].max_x = max(d[v].max_x, d[d[v].l].max_x);
        d[v].sz += d[d[v].l].sz;
    }
    if (d[v].r != -1) {
        push(d[v].r);
        d[v].min_val = min(d[v].min_val, d[d[v].r].min_val);
        d[v].min_x = min(d[v].min_x, d[d[v].r].min_x);
        d[v].max_x = max(d[v].max_x, d[d[v].r].max_x);
        d[v].sz += d[d[v].r].sz;
    }
}

int merge(int l, int r) {
    push(l);
    push(r);
    if (l == -1) {
        return r;
    }
    if (r == -1) {
        return l;
    }
    int v;
    if (d[l].y > d[r].y) {
        d[l].r = merge(d[l].r, r);
        v = l;
    } else {
        d[r].l = merge(l, d[r].l);
        v = r;
    }
    calc(v);
    return v;
}

void split_x(int v, int x, int& l, int& r) {
    push(v);
    if (v == -1) {
        l = r = -1;
        return;
    }
    if (d[v].x <= x) {
        split_x(d[v].r, x, d[v].r, r);
        l = v;
    } else {
        split_x(d[v].l, x, l, d[v].l);
        r = v;
    }
    calc(v);
}

void split_sz(int v, int sz, int& l, int& r) {
    push(v);
    if (v == -1) {
        l = r = -1;
        return;
    }
    if ((d[v].l != -1 ? d[d[v].l].sz : 0) + 1 <= sz) {
        split_sz(d[v].r, sz - (d[v].l != -1 ? d[d[v].l].sz : 0) - 1, d[v].r, r);
        l = v;
    } else {
        split_sz(d[v].l, sz, l, d[v].l);
        r = v;
    }
    calc(v);
}

int find_min_val(int v) {
    push(v);
    if (v == -1) {
        return -1;
    }
    if (d[v].val == d[v].min_val) {
        return (d[v].l != -1 ? d[d[v].l].sz : 0) + 1;
    }
    if (d[v].l != -1) {
        push(d[v].l);
        if (d[d[v].l].min_val == d[v].min_val) {
            return find_min_val(d[v].l);
        }
    }
    assert(d[v].r != -1);
    push(d[v].r);
    assert(d[d[v].r].min_val == d[v].min_val);
    return (d[v].l != -1 ? d[d[v].l].sz : 0) + 1 + find_min_val(d[v].r);
}

void solve() {
    int n, q, s, dd;
    scanf("%d %d %d %d", &n, &q, &s, &dd);
    --s;
    int root = -1;
    for (int i = 0; i < n; ++i) {
        scanf("%d", a + i);
        d[i] = init_node(a[i], (i == s ? 0 : inf));
        root = merge(root, i);
    }
    while (root != -1) {
        int pos = find_min_val(root);
        int l, tmp, r;
        split_sz(root, pos, tmp, r);
        split_sz(tmp, pos - 1, l, tmp);
        root = merge(l, r);
        int x = d[tmp].x;
        int ind = lower_bound(a, a + n, x) - a;
        assert(ind < n && a[ind] == x);
        dp[ind] = d[tmp].val;
        //cerr << ind << " " << dp[ind] << endl;
        if (x - dd + dp[ind] >= x + dd - dp[ind]) {
            int v1, v2, v3;
            split_x(root, x - dd - dp[ind] - 1, v1, root);
            split_x(root, x + dd + dp[ind], v2, v3);
            
            if (v1 != -1) {
                d[v1].min_upd = x - dd;
            }
            if (v2 != -1) {
                d[v2].min_const_upd = dp[ind];
            }
            if (v3 != -1) {
                d[v3].max_upd = x + dd;
            }
            
            root = merge(merge(v1, v2), v3);
        } else {
            int v1, v2, v3, v4, v5;
            split_x(root, x - dd - dp[ind] - 1, v1, root);
            split_x(root, x - dd + dp[ind], v2, root);
            split_x(root, x + dd - dp[ind] - 1, v3, root);
            split_x(root, x + dd + dp[ind], v4, v5);
            
            if (v1 != -1) {
                d[v1].min_upd = x - dd;
            }
            if (v2 != -1) {
                d[v2].min_const_upd = dp[ind];
            }
            if (v3 != -1) {
                d[v3].max_upd = x - dd;
                d[v3].min_upd = x + dd;
            }
            if (v4 != -1) {
                d[v4].min_const_upd = dp[ind];
            }
            if (v5 != -1) {
                d[v5].max_upd = x + dd;
            }
            
            root = merge(merge(v1, v2), merge(v3, v4));
            root = merge(root, v5);
        }
    }
    for (int i = 0; i < q; ++i) {
        int pos, k;
        scanf("%d %d", &pos, &k);
        --pos;
        if (dp[pos] <= k) {
            puts("YES");
        } else {
            puts("NO");
        }
    }
}

int main() {
#ifdef LOCAL42
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#endif
    init();
    int t = 1;
    //scanf("%d", &t);
    for (int i = 0; i < t; ++i) {
        solve();
    }
    return 0;
}