#include<bits/stdc++.h>
#define forUp(i,a,b) for(int i=(a);i<=(b);++i)
#define forUP(i,a,b) for(int i=(a);i<(b);++i)
#define forDown(i,a,b) for(int i=(a);i>=(b);--i)
#define forG(i,u,v) for(int i=head[u],v=to[i];i;i=nxt[i],v=to[i])
#define pb emplace_back
using ll=long long;using ull=unsigned long long;using uint=unsigned int;using db=double;using ld=long db;using pii=std::pair<int,int>;using pdi=std::pair<db,int>;using vl=__int128;using uvl=unsigned __int128;
constexpr int INF=0x3f3f3f3f,MINF=0xcfcfcfcf;constexpr long long INFLL=0x3f3f3f3f3f3f3f3f,MINFLL=0xcfcfcfcfcfcfcfcf;constexpr double INFDB=1e50,eps=1e-9;
template<class _Tp>void chkMax(_Tp &x,const _Tp &y){x<y?x=y:0;}template<class _Tp>void chkMin(_Tp &x,const _Tp &y){x>y?x=y:0;}
constexpr int N=4e5+10,M=1.2e7+10;int __test_num=1,__test_id;using namespace std;void __init();
int n,m,q,t,u[N],v[N],l,r,ans;
int fa[N],son[N][2],val[N],mn[N];bool rev[N];
bool nroot(int node){return son[fa[node]][0]==node||son[fa[node]][1]==node;}
void pushup(int node){
if(!node)return;
mn[node]=node;
if(son[node][0]&&val[mn[son[node][0]]]<val[mn[node]])mn[node]=mn[son[node][0]];
if(son[node][1]&&val[mn[son[node][1]]]<val[mn[node]])mn[node]=mn[son[node][1]];
}
void modifyRev(int node){
rev[node]^=1;
swap(son[node][0],son[node][1]);
}
void pushdown(int node){
if(rev[node]){
if(son[node][0])modifyRev(son[node][0]);
if(son[node][1])modifyRev(son[node][1]);
rev[node]=0;
}
}
void rotate(int node){
int father=fa[node],grand=fa[father],dir=son[father][1]==node,tmp=son[node][!dir];
if(nroot(father))son[grand][son[grand][1]==father]=node;
son[node][!dir]=father,son[father][dir]=tmp;
if(tmp)fa[tmp]=father;
fa[father]=node,fa[node]=grand;
pushup(father);pushup(node);
}
void clearTag(int node){
if(nroot(node))clearTag(fa[node]);
pushdown(node);
}
void splay(int node){
clearTag(node);
while(nroot(node)){
int father=fa[node],grand=fa[father];
if(nroot(father))rotate((son[father][0]==node)^(son[grand][0]==father)?node:father);
rotate(node);
}
pushup(node);
}
void access(int node){for(int tmp=0;node;node=fa[tmp=node])splay(node),son[node][1]=tmp,pushup(node);}
void makeRoot(int node){
access(node);splay(node);
modifyRev(node);
}
int findRoot(int node){
access(node);splay(node);
while(son[node][0])pushdown(node),node=son[node][0];
splay(node);
return node;
}
void split(int node1,int node2){
makeRoot(node1);
access(node2);splay(node2);
}
void link(int node1,int node2){
makeRoot(node1);
if(findRoot(node2)!=node1)fa[node1]=node2;
}
void cut(int node1,int node2){
makeRoot(node1);
if(findRoot(node2)==node1&&fa[node2]==node1&&!son[node2][0]){
fa[node2]=son[node1][1]=0;
pushup(node1);
}
}
int tot,root[N],lson[M],rson[M],sum[M];
void update(int &cur,int l,int r,int pos,int x){
int node=++tot;
lson[node]=lson[cur],rson[node]=rson[cur],sum[node]=sum[cur]+x,cur=node;
if(l==r)return;
int mid=l+r>>1;
if(pos<=mid)update(lson[cur],l,mid,pos,x);
else update(rson[cur],mid+1,r,pos,x);
}
int query(int cur,int l,int r,int L,int R){
if(L<=l&&r<=R)return sum[cur];
int mid=l+r>>1,ans=0;
if(L<=mid)ans+=query(lson[cur],l,mid,L,R);
if(mid<R)ans+=query(rson[cur],mid+1,r,L,R);
return ans;
}
void __solve(int __test_id){
scanf("%d%d%d%d",&n,&m,&q,&t);
forUp(i,1,m)scanf("%d%d",&u[i],&v[i]);
forUp(i,1,n)val[i]=INF,mn[i]=i;
forUp(i,1,m)val[i+n]=i,mn[i+n]=i+n;
forUp(i,1,m){
root[i]=root[i-1];
if(u[i]==v[i])continue;
if(findRoot(u[i])==findRoot(v[i])){
split(u[i],v[i]);
int tmp=mn[v[i]]-n;
cut(u[tmp],tmp+n);
cut(tmp+n,v[tmp]);
update(root[i],1,m,tmp,-1);
}
link(u[i],i+n);
link(i+n,v[i]);
update(root[i],1,m,i,1);
}
while(q--){
scanf("%d%d",&l,&r);
if(t)l=(l+ans)%m+1,r=(r+ans)%m+1;
if(l>r)swap(l,r);
printf("%d\n",ans=(n-query(root[r],1,m,l,r)));
}
}
int main(){
__init();
forUp(i,1,__test_num)__solve(i);
return 0;
}
void __init(){
//const string __file_name="test";freopen((__file_name+".in").c_str(),"r",stdin);freopen((__file_name+".out").c_str(),"w",stdout);
//scanf("%d",&__test_num);
}