#include <bits/stdc++.h>
#define err(args...) {}
#ifdef DEBUG
#include "_debug.cpp"
#endif
using namespace std;
using ll = long long;
template <typename T> using lim = numeric_limits<T>;
template <typename T> istream& operator>>(istream& is, vector<T>& a) { for(T& x : a) { is >> x; } return is; }
template <typename Iter, typename T> int gt(Iter L, Iter R, T v) { return upper_bound(L, R, v) - L; }
template <typename Iter, typename T> int ge(Iter L, Iter R, T v) { return lower_bound(L, R, v) - L; }
template <typename Iter, typename T> int lt(Iter L, Iter R, T v) { return lower_bound(L, R, v) - L - 1; }
template <typename Iter, typename T> int le(Iter L, Iter R, T v) { return upper_bound(L, R, v) - L - 1; }
template <typename Bst, typename T> typename Bst::const_iterator gt(const Bst& bst, T v) { return bst.upper_bound(v); }
template <typename Bst, typename T> typename Bst::const_iterator ge(const Bst& bst, T v) { return bst.lower_bound(v); }
template <typename Bst, typename T> typename Bst::const_iterator lt(const Bst& bst, T v) { return bst.lower_bound(v) == bst.begin() ? bst.end() : --bst.lower_bound(v); }
template <typename Bst, typename T> typename Bst::const_iterator le(const Bst& bst, T v) { return bst.upper_bound(v) == bst.begin() ? bst.end() : --bst.upper_bound(v); }
template <bool Directed> struct graph {
    int n;
    vector<vector<int>> adj;
    graph(int n) : n(n), adj(n + 1) {}
    void add_edge(int u, int v) {
        adj[u].push_back(v);
        if(not Directed) adj[v].push_back(u);
    }
};
template <bool Directed> void dfs(graph<Directed>& g, int root,
const function<void(int, int)>& pre = [](int u, int from) {},
const function<void(int, int)>& pos = [](int u, int from) {}) {
    vector<bool> vis(g.n + 1);
    function<void(int, int)> dfs = [&](int u, int from) {
        vis[u] = true;
        pre(u, from);
        for(int v : g.adj[u]) {
            if(not vis[v]) {
                dfs(v, u);
            }
        }
        pos(u, from);
    };
    dfs(root, 0);
}
struct binary_lift {
    vector<int> lg, depth;
    vector<vector<int>> p;
    binary_lift(graph<0>& g, int root) : lg(g.n + 1), depth(g.n + 1), p(g.n + 1) {
        lg[0] = -1, lg[1] = 0;
        for(int i = 2; i <= g.n; i++) {
            lg[i] = lg[i / 2] + 1;
        }
        dfs(g, root, [&](int u, int from) {
            if(from) {
                p[u].push_back(from);
                depth[u] = depth[from] + 1;
                build_ancestors(u);
            }
        });
    }
    void build_ancestors(int u) {
        for(int pow2 = 1; pow2 <= lg[depth[u]]; pow2++) {
            p[u].push_back(p[p[u][pow2 - 1]][pow2 - 1]);
        }
    }
    int kth_ancestor(int u, int k) {
        return k == 0 ? u : kth_ancestor(p[u][lg[k & -k]], k - (k & -k));
    }
    int lca(int u, int v) {
        if(depth[u] > depth[v]) swap(u, v);
        v = kth_ancestor(v, depth[v] - depth[u]);
        for(int pow2 = lg[depth[u]]; pow2 >= 0; pow2--) {
            if((1 << pow2) <= depth[u] and p[u][pow2] != p[v][pow2]) {
                u = p[u][pow2], v = p[v][pow2];
            }
        }
        return u == v ? u : p[u][0];
    }
    int dist(int u, int v) {
        return depth[u] + depth[v] - 2 * depth[lca(u, v)];
    }
};
template <typename T> T bsearch(T L, T R, const function<bool(T)>& can, bool left_feasible = true) {
    T& feasible = left_feasible ? L : R;
    T& infeasible = left_feasible ? R : L;
    while(R - L > 1) {
        T M = L + (R - L) / 2;
        (can(M) ? feasible : infeasible) = M;
    }
    return feasible;
}
int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    int n;
    cin >> n;
    vector<int> x(n + 1, lim<int>::min());
    for(int i = 1; i <= n; i++) {
        cin >> x[i];
    }
    int L;
    cin >> L;
    vector<int> succ_right(n + 1), cost_right(n + 1);
    graph<0> g_right(n);
    for(int i = n; i >= 1; i--) {
        succ_right[i] = le(x.begin(), x.end(), x[i] + L);
        cost_right[i] = cost_right[succ_right[i]] + 1;
        if(i < n) g_right.add_edge(i, succ_right[i]);
    }
    auto lca_right = binary_lift(g_right, n);
    vector<int> succ_left(n + 1), cost_left(n + 1);
    graph<0> g_left(n);
    for(int i = 1; i <= n; i++) {
        succ_left[i] = ge(x.begin(), x.end(), x[i] - L);
        cost_left[i] = cost_left[succ_left[i]] + 1;
        if(i > 1) g_left.add_edge(i, succ_left[i]);
    }
    auto lca_left = binary_lift(g_left, 1);
    int q;
    cin >> q;
    while(q--) {
        int a, b;
        cin >> a >> b;
        if(a < b) {
            int k = bsearch<int>(0, cost_right[a], [&](int k) {
                return lca_right.kth_ancestor(a, k) <= b;
            });
            cout << k + (lca_right.kth_ancestor(a, k) != b) << endl;
        } else {
            int k = bsearch<int>(0, cost_left[a], [&](int k) {
                return lca_left.kth_ancestor(a, k) >= b;
            });
            cout << k + (lca_left.kth_ancestor(a, k) != b) << endl;
        }
    }
    return 0;
}


Measured memory_bytes: 49280