#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <climits>
#define _min(_a_,_b_) ((_a_)<(_b_)?(_a_):(_b_))
#ifdef ONLINE_JUDGE
char __B[1<<15],*__S=__B,*__T=__B;
#define getchar() (__S==__T&&(__T=(__S=__B)+fread(__B,1,1<<15,stdin),__S==__T)?EOF:*__S++)
#endif
inline int getnum()
{
register char c=0;
while(!(c>='0' && c<='9'))
c=getchar();
register int a=0;
while(c>='0' && c<='9')
{
a*=10;a+=c-'0';
c=getchar();
}
return a;
}
int BlockSize,BlockNum;
int _bpos[105050],_bleft[350],_bright[350];
#define GetBlockPos(_p_) (_bpos[_p_])
#define GetBlockLeft(_w_) (_bleft[_w_])
#define GetBlockRight(_w_) (_bright[_w_])
/*#define GetBlockPos(_p_) (((_p_)-1)/BlockSize+1)
#define GetBlockLeft(_w_) (((_w_)-1)*BlockSize+1)
#define GetBlockRight(_w_) _min((_w_)*BlockSize,N)*/
int a[105050];
int gans[350][350],gbucket[350][105050];
//inline void AddNum(int&ans,int bucket[],register int a,register int offset=0)
#define AddNum(_ans,_bucket,_a,_offset) \
{ \
_bucket[_a]++; \
if((_offset+_bucket[_a])%2==0) \
_ans++; \
else if(_offset+(_bucket[_a])!=1) \
_ans--; \
}
//inline void DelNum(int&ans,int bucket[],register int a,register int offset=0)
#define DelNum(_ans,_bucket,_a,_offset) \
{ \
_bucket[_a]--; \
if((_offset+_bucket[_a])%2!=0) \
_ans--; \
else if(_offset+_bucket[_a]) \
_ans++; \
}
int main()
{
register int N=getnum(),C=getnum(),M=getnum(),T=getnum();
for(register int i=1;i<=N;i++)
a[i]=getnum();
BlockSize=__builtin_sqrt(N),BlockNum=N/BlockSize+(N%BlockSize!=0);
_bleft[1]=1;
for(register int i=1,tb=1;i<=N;i++)
{
_bpos[i]=tb;
if(i%BlockSize == 0)
_bright[tb++]=i,_bleft[tb]=i+1;
}
for(register int i=1;i<=N;i++)
{
register int tb=GetBlockPos(i),tbp=GetBlockPos(i-1);
if(tb != tbp)
memcpy(&gbucket[tb][0],&gbucket[tbp][0],sizeof(int)*(C+1)),gans[1][tb]=gans[1][tbp];
AddNum(gans[1][tb],gbucket[tb],a[i],0);
}
for(register int i=2;i<=BlockNum;i++)
{
register int lpos=GetBlockLeft(i);
static int tbucket[105050];
register int tans=0;
for(register int j=lpos;j<=N;j++)
{
AddNum(tans,tbucket,a[j],0);
register int tb=GetBlockPos(j),tbn=GetBlockPos(j+1);
if(tb != tbn)
gans[i][tb]=tans;
}
gans[i][BlockNum]=tans;
for(register int j=lpos;j<=N;j++)
DelNum(tans,tbucket,a[j],0);
}
register int lastans=0;
for(register int i=1;i<=M;i++)
{
register int l=getnum(),r=getnum();
l=(l+T*lastans)%N+1,r=(r+T*lastans)%N+1;
if(l>r)
l^=r^=l^=r;
register int lb=GetBlockPos(l)+1,rb=GetBlockPos(r)-1;
static int tbucket[105050];
register int tans=gans[lb][rb];
if(lb>rb)
{
for(register int i=l;i<=r;i++)
AddNum(tans,tbucket,a[i],0);
printf("%d\n",lastans=tans);
for(register int i=l;i<=r;i++)
DelNum(tans,tbucket,a[i],0);
continue;
}
register int lrpos=GetBlockRight(lb-1),rlpos=GetBlockLeft(rb+1);
for(register int i=l;i<=lrpos;i++)
AddNum(tans,tbucket,a[i],gbucket[rb][a[i]]-gbucket[lb-1][a[i]]);
for(register int i=rlpos;i<=r;i++)
AddNum(tans,tbucket,a[i],gbucket[rb][a[i]]-gbucket[lb-1][a[i]]);
printf("%d\n",lastans=tans);
for(register int i=l;i<=lrpos;i++)
DelNum(tans,tbucket,a[i],0);
for(register int i=rlpos;i<=r;i++)
DelNum(tans,tbucket,a[i],0);
}
return 0;
}