#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
typedef long long ll;
using namespace __gnu_pbds;
using namespace std;
template <typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
template <typename TY>
struct MultiOrderedSet {
ordered_set<pair<TY, int>> os;
int cnt = 0;
void insert(TY x) {
os.insert({x, cnt++});
}
void erase(TY x) {
int idx = os.order_of_key({x,-1});
assert(idx < os.size());
os.erase(*os.find_by_order(idx));
}
TY first() { return os.begin()->first; }
TY last() { return os.rbegin()->first; }
void clear() {
while(os.size()) os.erase(*os.begin());
}
int size() { return os.size(); }
bool empty() { return os.empty(); }
int order_of_key(TY x) {
return os.order_of_key({x, -1});
}
TY find_by_order(ll x) {
return os.find_by_order(x)->first;
}
};
struct Query {
ll v, t, i;
};
ll M = 200'010;
vector<vector<pair<ll, ll>>> g(M);
vector<vector<ll>> mine(M);
vector<pair<ll, ll>> nxt(M, {-1, 0}), cykl(M, {-1, 0});
vector<ll> depth(M), vis(M), ans(M), root(M), roots, P(M, 0), on_cycle(M), path;
vector<Query> queries(M);
void meduza_dfs(ll v) {
path.push_back(v);
vis[v] = 1;
auto[u,d] = nxt[v];
if(vis[u]==2) {
root[v] = root[u];
vis[v] = 2;
} else if(vis[u]==1) {
P[v] = depth[v] - depth[u] + d;
root[v] = v;
roots.push_back(v);
ll idx = path.size()-1;
while(path[idx] != u) {
on_cycle[path[idx]] = 1;
idx--;
}
on_cycle[u] = 1;
cykl[v] = nxt[v];
nxt[v].first = -1;
} else {
depth[u] = depth[v] + d;
meduza_dfs(u);
root[v] = root[u];
}
vis[v] = 2;
path.pop_back();
}
ll base = 1<<19;
vector<ll> Tree(2*base);
void update(ll x, ll val) {
x += base;
Tree[x] += val;
x/=2;
while(x > 0) {
Tree[x] = Tree[x+x] + Tree[x+x+1];
x/=2;
}
}
ll query(ll a, ll b) {
a+=base-1;
b+=base+1;
ll ans = 0;
while(a/2 != b/2) {
if(a%2==0) ans += Tree[a+1];
if(b%2==1) ans += Tree[b-1];
a/=2; b/=2;
}
return ans;
}
ll cnt = 1;
vector<ll> pre(M), post(M);
void pre_dfs(ll v) {
pre[v] = cnt++;
for(auto[u,k] : g[v]) {
depth[u] = depth[v] + k;
pre_dfs(u);
}
post[v] = cnt++;
}
int main() {
ios_base::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
ll n, m, L, C;
cin >> n >> m >> L >> C;
vector<ll> ludzie(n), jablka(m);
for(ll i=0; i<n; ++i) cin >> ludzie[i];
for(ll i=0; i<m; ++i) cin >> jablka[i];
ll q; cin >> q;
for(ll i=0; i<q; ++i) {
ll v, t;
cin >> v >> t;
queries[i] = {v-1, t, i};
}
auto dist = [&](ll a, ll b) {
if(a<=b) return b-a;
else return L + b - a;
};
auto dist_emp = [&](ll x, ll y) {
if(x==y) return L;
return dist(ludzie[x], ludzie[y]);
};
ll Pan = n-1;
ll idx = 0;
for(ll i=0; i<m; ++i) {
while(idx < n && ludzie[idx] <= jablka[i]) {
Pan = idx;
idx++;
}
mine[Pan].push_back(dist(ludzie[Pan], jablka[i]));
}
for(ll i=0; i<n; ++i) sort(mine[i].begin(), mine[i].end());
ll iterator = 0;
ll cl = (C%L ? C%L : L);
ll d_it = 0;
ll d_mine = L;
for(ll i=0; i<n; ++i) {
int d_nxt = dist_emp(iterator, (iterator+1)%n);
while(d_mine - (d_it + d_nxt) >= cl) {
iterator = (iterator+1)%n;
d_it += d_nxt;
d_nxt = dist_emp(iterator, (iterator+1)%n);
}
ll D = d_mine - d_it;
if(C > L) {
if(cl!=L) D += L*(C/L);
else D += L*(C/L) - L;
}
nxt[i] = {iterator, D};
d_mine += dist_emp(i, (i+1)%n);
}
for(ll i=0; i<n; ++i) if(!vis[i]) meduza_dfs(i);
for(ll i=0; i<n; ++i) if(nxt[i].first!=-1) g[nxt[i].first].push_back({i, nxt[i].second});
for(auto r : roots) {
depth[r] = 0;
pre_dfs(r);
}
vector<vector<pair<ll, ll>>> zap1(n); // zap1[v][..] = {T, q_idx}
vector<pair<ll, pair<ll, ll>>> zap2; // zap2[..] = {T + depth, {q_idx, v}}
for(ll idx=0; idx<q; ++idx) {
auto[v,t,i] = queries[idx];
zap2.push_back({t + depth[v], {i, v}});
if(on_cycle[v]) {
if(t >= P[root[v]]-depth[v]) zap1[root[v]].push_back({t-P[root[v]]+depth[v], i});
}
}
for(ll i=0; i<n; ++i) {
for(auto a : mine[i]) zap2.push_back({a + depth[i], {-1, i}});
}
sort(zap2.begin(), zap2.end());
for(auto[T, stat] : zap2) {
auto[q_idx, v] = stat;
if(q_idx==-1) update(pre[v], 1);
else ans[q_idx] += query(pre[v], post[v]);
}
vector<vector<ll>> child(n);
for(ll i=0; i<n; ++i) {
for(auto a : mine[i]) {
child[root[i]].push_back(a + depth[i]);
}
}
for(auto r : roots) {
sort(child[r].begin(), child[r].end());
vector<int> prefix(child[r].size()+1);
vector<vector<pair<int, int>>> quer(child[r].size()+1);
ll D = P[r];
for(int i=1; i<=child[r].size(); ++i) prefix[i] = prefix[i-1] + (child[r][i-1]/D);
for(auto[T, q_idx] : zap1[r]) {
ll res = 0;
int ile = upper_bound(child[r].begin(), child[r].end(), T) - child[r].begin();
if(!ile) continue;
ans[q_idx] += ile * (T/D);
ans[q_idx] -= prefix[ile];
quer[ile].push_back({T%D, q_idx});
}
MultiOrderedSet<ll> os;
for(int i=0; i<n; ++i) {
os.insert(child[r][i]%D);
for(auto[x, q_idx] : quer[i+1]) {
ans[q_idx] += os.order_of_key(x+1);
}
}
}
for(ll i=0; i<q; ++i) cout << ans[i] << "\n";
return 0;
}