#include<bits/stdc++.h>
using namespace std;
const int siz = 3e5;
int n,m,q,t,lastans;
struct node{int from,to,w;} edge[500005];
int root[500005];
namespace shiro
{
#define mid (l+r>>1)
int cnt;
struct node{int ls,rs,sum;} tr[500005<<2];
void pushup(int k){tr[k].sum = tr[tr[k].ls].sum+tr[tr[k].rs].sum;}
void build(int &k,int l,int r)
{
k = ++cnt;
if (l == r) return ;
build(tr[k].ls,l,mid);
build(tr[k].rs,mid+1,r);
}
int insert(int k,int l,int r,int x,int a)
{
int u = ++cnt;
tr[u] = tr[k];
if (l == r)
{
tr[u].sum += a;
return u;
}
if (x <= mid) tr[u].ls = insert(tr[u].ls,l,mid,x,a);
else tr[u].rs = insert(tr[u].rs,mid+1,r,x,a);
pushup(u);
return u;
}
int query(int rt,int l,int r,int x,int y)
{
int res = 0;
if (l >= x && r <= y)
return tr[rt].sum;
if (x <= mid) res += query(tr[rt].ls,l,mid,x,y);
if (y > mid) res += query(tr[rt].rs,mid+1,r,x,y);
return res;
}
}
namespace elia
{
int stk[5000005],top;
struct Splay{int ch[2],val,mi,fa,rev;} tr[5000005];
bool isroot(int x){return tr[tr[x].fa].ch[0]!=x&tr[tr[x].fa].ch[1]!=x;}
void pushup(int x)
{
tr[x].mi = x;
tr[x].mi = tr[tr[tr[x].ch[0]].mi].val<tr[tr[x].mi].val?tr[tr[x].ch[0]].mi:tr[x].mi;
tr[x].mi = tr[tr[tr[x].ch[1]].mi].val<tr[tr[x].mi].val?tr[tr[x].ch[1]].mi:tr[x].mi;
}
void pushdown(int x)
{
if (tr[x].rev)
{
tr[x].rev ^= 1;
swap(tr[x].ch[0],tr[x].ch[1]);
if (tr[x].ch[0]) tr[tr[x].ch[0]].rev ^= 1;
if (tr[x].ch[1]) tr[tr[x].ch[1]].rev ^= 1;
}
}
void rotate(int x)
{
int y = tr[x].fa,z = tr[y].fa,pd = tr[y].ch[1]==x;
if (!isroot(y)) tr[z].ch[tr[z].ch[1]==y] = x; tr[x].fa = z;
tr[y].ch[pd] = tr[x].ch[pd^1]; tr[tr[x].ch[pd^1]].fa = y;
tr[x].ch[pd^1] = y; tr[y].fa = x;
pushup(y); pushup(x);
}
void splay(int x)
{
int u = x;
stk[++top] = u;
while (!isroot(u)) stk[++top] = u=tr[u].fa;
while (top) pushdown(stk[top--]);
while (!isroot(x))
{
int y = tr[x].fa,z = tr[y].fa;
if (!isroot(y)) (tr[y].ch[0]==x)^(tr[z].ch[0]==y)?rotate(x):rotate(y);
rotate(x);
}
}
void access(int x){for(int y=0;x;y=x,x=tr[x].fa) splay(x),tr[x].ch[1]=y,pushup(x);}
void makeroot(int x){access(x); splay(x); tr[x].rev ^= 1;}
int findroot(int x){access(x); splay(x); while(tr[x].ch[0]) x=tr[x].ch[0]; return x;}
void split(int x,int y){makeroot(x); access(y); splay(y);}
void link(int x,int y){makeroot(x); tr[x].fa = y;}
void cut(int x,int y){split(x,y); if(tr[y].ch[0]==x) tr[x].fa=tr[y].ch[0]=0;}
void change(int x,int v){makeroot(x); tr[x].val=v; pushup(x);}
void add(int id){link(edge[id].from,id+siz); link(id+siz,edge[id].to); change(id+siz,edge[id].w);}
void del(int id){cut(edge[id].from,id+siz); cut(id+siz,edge[id].to);}
void sol(int id)
{
split(edge[id].from,edge[id].to);
int pos = tr[edge[id].to].mi;
root[id] = shiro::insert(root[id],1,m,pos-siz,-1);
del(pos-siz);
}
}
void modify(int id)
{
root[id] = shiro::insert(root[id],1,m,id,1);
if (elia::findroot(edge[id].from) == elia::findroot(edge[id].to))
elia::sol(id);
elia::add(id);
}
int main()
{
cin >> n >> m >> q >> t;
for (int i = 0; i <= 5000000; i++) elia::tr[i].mi = i,elia::tr[i].val = 2e9;
shiro::build(root[0],1,m);
for (int i = 1; i <= m; i++)
{
cin >> edge[i].from >> edge[i].to;
edge[i].w = i;
root[i] = root[i-1];
if (edge[i].from == edge[i].to)
continue;
modify(i);
}
int l,r;
while (q--)
{
cin >> l >> r;
if (t) l = (l+lastans)%m+1,r = (r+lastans)%m+1;
if (l > r) swap(l,r);
lastans = n-shiro::query(root[r],1,m,l,r);
cout << lastans << '\n';
}
return 0;
}