#include <iostream>
#include <vector>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
#define os tree<ll, null_type,less_equal<ll>, rb_tree_tag,tree_order_statistics_node_update>
using namespace std;
#define ll long long
const ll N = (1<<20) + 1;
os seg[N<<1], st[N>>1];
ll segSum[N<<1], vl[N], v[N], Nxt[N], Len[N], deg[N], Ans[N], a[N];
vector<pair<ll, ll>> Quer[N];
vector<ll> vc;
multiset<pair<ll, ll>> ms;
ll n, m, l, c, q, Add;
void insert(ll i, ll v1, ll v2, ll tp, ll cur = 1, ll st = 1, ll en = N){
if (i >= en or i < st)
return;
if (tp == 1)
seg[cur].insert(v2 - Add), segSum[cur] += v1;
else{
auto u = seg[cur].upper_bound(v2 - Add);
if (u == seg[cur].end() or *u > v2 - Add)
u = prev(u);
seg[cur].erase(u);
segSum[cur] -= v1;
}
if (en - st == 1)
return;
ll lc = cur << 1, rc = lc | 1, mid = (st + en) >> 1;
insert(i, v1, v2, tp, lc, st, mid);
insert(i, v1, v2, tp, rc, mid, en);
}
ll get(ll K, ll l, ll r, ll r1, ll cur = 1, ll st = 1, ll en = N){
if (l >= en or r <= st)
return 0;
if (l <= st and r >= en){
if (seg[cur].size() == 0)
return 0;
return K * seg[cur].size() - segSum[cur] + seg[cur].order_of_key(r1 - Add + 1);
}
ll lc = cur << 1, rc = lc | 1, mid = (st + en) >> 1;
return get(K, l, r, r1, lc, st, mid) + get(K, l, r, r1, rc, mid, en);
}
void Clear(ll cur = 1, ll st = 1, ll en = N){
if (seg[cur].size() == 0)
return;
seg[cur].clear();
segSum[cur] = 0;
if (en - st == 1)
return;
ll lc = cur << 1, rc = lc | 1, mid = (st + en) >> 1;
Clear(lc, st, mid);
Clear(rc, mid, en);
}
ll getId(ll u){
return upper_bound(begin(vc), end(vc), u) - begin(vc);
}
void solveCycle(ll vr){
ll s = 0, Cl = 0;
for (ll i=0; vr != v[0];i++){
v[i] = vr;
s++, Cl += Len[vr];
vr = Nxt[vr];
deg[v[i]] = 0;
}
for (ll i=0;i<s;i++){
for (auto [T, id] : Quer[v[i]])
vc.push_back(T / Cl);
for (ll j : st[v[i]]){
ll T = j + vl[v[i]];
vc.push_back(T / Cl), vc.push_back(T / Cl + 1);
}
}
sort(begin(vc), end(vc));
vc.resize(unique(begin(vc), end(vc)) - begin(vc));
for (ll i=s-1, sum = 0;i>=0;i--){
sum += Len[v[i]];
for (ll j : st[v[i]]){
ll T = j + vl[v[i]] + sum;
ll k = T / Cl, r = T % Cl;
insert(getId(k), k, r, 1);
ms.insert({r, k});
}
}
for (ll i=0;i<s;i++){
for (ll j : st[v[i]]){
ll T = j + vl[v[i]];
ll k = T / Cl, r = T % Cl;
ms.erase(ms.find({r - Add, k + 1}));
ms.insert({r - Add, k});
insert(getId(k+1), k+1, r, -1);
insert(getId(k), k, r, 1);
}
for (auto [T, id] : Quer[v[i]]){
ll k = T / Cl, r = T % Cl, j = getId(k);
Ans[id] = get(k, 1, j+1, r);
}
Add += Len[v[i]];
while (ms.size() > 0 and (*rbegin(ms)).first + Add >= Cl){
auto [r, k] = *rbegin(ms);
ms.erase(prev(end(ms)));
r += Add;
insert(getId(k), k, r, -1);
insert(getId(k+1), k+1, r - Cl, 1);
ms.insert({r - Cl - Add, k+1});
}
}
Clear();
ms.clear();
Add = 0;
vc.clear();
}
void solvePart2(){
for (ll i=1;i<=n;i++){
if (deg[i] == 1){
solveCycle(i);
}
}
}
int main(){
ios_base::sync_with_stdio(false); cin.tie(NULL);
cin>>n>>m>>l>>c;
for (ll i=1;i<=n;i++)
cin>>a[i], a[i+n] = l + a[i];
for (ll i=n+1, it = 1;i<=n+n;i++){
ll k = c % l;
while (it < i and a[i] - a[it+1] >= k)
it++;
Nxt[i - n] = it - n * (it > n);
deg[Nxt[i - n]]++;
Len[i - n] = a[i] - a[it] + (c / l) * l;
}
for (ll i=1, it = 0, b;i<=m;i++){
cin>>b;
while (a[it+1] <= b)
it++;
if (it == 0)
st[n].insert(l - a[n] + b);
else
st[it].insert(b - a[it]);
}
cin>>q;
for (ll i=1;i<=q;i++){
ll id, T;
cin>>id>>T;
Quer[id].push_back({T, i});
}
vector<ll> lfs;
for (ll i=1;i<=n;i++){
if (deg[i] == 0)
lfs.push_back(i);
}
while (lfs.size() > 0){
int i = lfs.back();
lfs.pop_back();
for (auto [T, id] : Quer[i])
Ans[id] = st[i].order_of_key(T - vl[i] + 1);
ll j = Nxt[i];
vl[i] += Len[i];
if (st[j].size() < st[i].size())
swap(st[i], st[j]), swap(vl[i], vl[j]);
for (ll k : st[i])
st[j].insert(k + vl[i] - vl[j]);
deg[j]--;
if (deg[j] == 0)
lfs.push_back(j);
}
solvePart2();
for (ll i=1;i<=q;i++)
cout<<Ans[i]<<'\n';
}