#include<bits/stdc++.h>
using namespace std;
#define next Next
#define int long long
#define mid (l+r)/2
const int N=1e6+5;
int n,m,k,d,ans,l,r,top1,top2,ansL,ansR,a[N],zuo[N],zhan1[N],zhan2[N];
int mi[N*4],ma[N*4],tree[N*4],tag1[N*4],tag2[N*4];
map<int,int>gs;
/*char buf[1<<21],*p1=buf,*p2=buf;
inline int gc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}*/
#define gc getchar
inline int read()
{
	int ret=0,f=0;char c=gc();
	while(!isdigit(c)){if(c=='-')f=1;c=gc();}
	while(isdigit(c)){ret=ret*10+c-48;c=gc();}
	if(f)return -ret;return ret;
}
void pushup(int nod)
{
	mi[nod]=min(mi[nod*2],mi[nod*2+1]);
	ma[nod]=max(ma[nod*2],ma[nod*2+1]);
	tree[nod]=min(tree[nod*2],tree[nod*2+1]);
}
void pushdown(int nod)
{
	mi[nod*2]+=tag1[nod];tag1[nod*2]+=tag1[nod];
	mi[nod*2+1]+=tag1[nod];tag1[nod*2+1]+=tag1[nod];
	tag1[nod]=0;
	ma[nod*2]+=tag2[nod];tag2[nod*2]+=tag2[nod];
	ma[nod*2+1]+=tag2[nod];tag2[nod*2+1]+=tag2[nod];
	tag2[nod]=0;
}
void build(int nod,int l,int r)
{
	if(l==r)
	{
		tree[nod]=l;
		mi[nod]=ma[nod]=a[l];
		return;
	}
	build(nod*2,l,mid);
	build(nod*2+1,mid+1,r);
	pushup(nod);
}
int find(int nod,int l,int r,int x)
{
	if(l==r)return l;
	pushdown(nod);
	if(tree[nod*2]<=x)return find(nod*2,l,mid,x);
	else return find(nod*2+1,mid+1,r,x);
}
void del(int nod,int l,int r,int x)
{
	if(l==r){tree[nod]=1e15;return;}
	if(x<=mid)del(nod*2,l,mid,x);
	else del(nod*2+1,mid+1,r,x);
	pushup(nod);
}
void change1(int nod,int l,int r,int L,int R,int val)
{
	if(l==L&&r==R)
	{
		mi[nod]+=val;
		tag1[nod]+=val;
		tree[nod]-=val;
		return;
	}
	pushdown(nod);
	if(R<=mid)change1(nod*2,l,mid,L,R,val);
	else if(L>mid)change1(nod*2+1,mid+1,r,L,R,val);
	else{
		change1(nod*2,l,mid,L,mid,val);
		change1(nod*2+1,mid+1,r,mid+1,R,val);
	}
	pushup(nod);
}
void change2(int nod,int l,int r,int L,int R,int val)
{
	if(l==L&&r==R)
	{
		ma[nod]+=val;
		tag2[nod]+=val;
		tree[nod]+=val;
		return;
	}
	pushdown(nod);
	if(R<=mid)change2(nod*2,l,mid,L,R,val);
	else if(L>mid)change2(nod*2+1,mid+1,r,L,R,val);
	else{
		change2(nod*2,l,mid,L,mid,val);
		change2(nod*2+1,mid+1,r,mid+1,R,val);
	}
	pushup(nod);
}
signed main()
{
	n=read();k=read();d=read();
	for(int i=1;i<=n;i++)a[i]=read()+1e9;
	if(!d)
    {
        for(int i=1,j;i<=n;)
        {
            j=i;
            while(j<n&&a[j+1]==a[i])j++;
            if(j-i+1>ans){ans=j-i+1;ansL=i;ansR=j;}
            i=j+1;
        }
        printf("%lld %lld\n",ansL,ansR);
        return 0;
    }
	for(int i=1;i<=n;)
    {
        int j=i;
		zuo[i]=i;
        while(j<n&&a[j+1]%d==a[i]%d){j++;zuo[j]=i;}
        i=j+1;
    }
    r=1;
    build(1,1,n);
    while(l<n)
    {
        l++;gs[a[l]]++;
        while(gs[a[l]]>1||zuo[l]!=zuo[r])
		{
			del(1,1,n,r);
			gs[a[r]]--;
			r++;
		}
        while(top1>0&&a[l]<=a[zhan1[top1]])
        {
            change1(1,1,n,zhan1[top1-1]+1,zhan1[top1],a[l]/d-a[zhan1[top1]]/d);
            top1--;
        }
        zhan1[++top1]=l;
        while(top2>0&&a[l]>=a[zhan2[top2]])
        {
            change2(1,1,n,zhan2[top2-1]+1,zhan2[top2],a[l]/d-a[zhan2[top2]]/d);
            top2--;
        }
        zhan2[++top2]=l;
        int L=find(1,1,n,l+k);
        if(L>=r&&l-L+1>ans)
		{
			ans=l-L+1;
			ansL=L;ansR=l;
		}
    }
    printf("%lld %lld\n",ansL,ansR);
    return 0;
}
/*
*/


#include<bits/stdc++.h>
using namespace std;
#define next Next
#define int long long
#define mid (l+r)/2
const int N=1e6+5;
int n,m,k,d,ans,l,r,top1,top2,ansL,ansR,a[N],zuo[N],zhan1[N],zhan2[N];
int mi[N*4],ma[N*4],tree[N*4],tag1[N*4],tag2[N*4];
map<int,int>gs;
/*char buf[1<<21],*p1=buf,*p2=buf;
inline int gc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}*/
#define gc getchar
inline int read()
{
	int ret=0,f=0;char c=gc();
	while(!isdigit(c)){if(c=='-')f=1;c=gc();}
	while(isdigit(c)){ret=ret*10+c-48;c=gc();}
	if(f)return -ret;return ret;
}
void pushup(int nod)
{
	mi[nod]=min(mi[nod*2],mi[nod*2+1]);
	ma[nod]=max(ma[nod*2],ma[nod*2+1]);
	tree[nod]=min(tree[nod*2],tree[nod*2+1]);
}
void pushdown(int nod)
{
	mi[nod*2]+=tag1[nod];tag1[nod*2]+=tag1[nod];
	mi[nod*2+1]+=tag1[nod];tag1[nod*2+1]+=tag1[nod];
	tag1[nod]=0;
	ma[nod*2]+=tag2[nod];tag2[nod*2]+=tag2[nod];
	ma[nod*2+1]+=tag2[nod];tag2[nod*2+1]+=tag2[nod];
	tag2[nod]=0;
}
void build(int nod,int l,int r)
{
	if(l==r)
	{
		tree[nod]=l;
		mi[nod]=ma[nod]=a[l];
		return;
	}
	build(nod*2,l,mid);
	build(nod*2+1,mid+1,r);
	pushup(nod);
}
int find(int nod,int l,int r,int x)
{
	if(l==r)return l;
	pushdown(nod);
	if(tree[nod*2]<=x)return find(nod*2,l,mid,x);
	else return find(nod*2+1,mid+1,r,x);
}
void del(int nod,int l,int r,int x)
{
	if(l==r){tree[nod]=1e15;return;}
	if(x<=mid)del(nod*2,l,mid,x);
	else del(nod*2+1,mid+1,r,x);
	pushup(nod);
}
void change1(int nod,int l,int r,int L,int R,int val)
{
	if(l==L&&r==R)
	{
		mi[nod]+=val;
		tag1[nod]+=val;
		tree[nod]-=val;
		return;
	}
	pushdown(nod);
	if(R<=mid)change1(nod*2,l,mid,L,R,val);
	else if(L>mid)change1(nod*2+1,mid+1,r,L,R,val);
	else{
		change1(nod*2,l,mid,L,mid,val);
		change1(nod*2+1,mid+1,r,mid+1,R,val);
	}
	pushup(nod);
}
void change2(int nod,int l,int r,int L,int R,int val)
{
	if(l==L&&r==R)
	{
		ma[nod]+=val;
		tag2[nod]+=val;
		tree[nod]+=val;
		return;
	}
	pushdown(nod);
	if(R<=mid)change2(nod*2,l,mid,L,R,val);
	else if(L>mid)change2(nod*2+1,mid+1,r,L,R,val);
	else{
		change2(nod*2,l,mid,L,mid,val);
		change2(nod*2+1,mid+1,r,mid+1,R,val);
	}
	pushup(nod);
}
signed main()
{
	n=read();k=read();d=read();
	for(int i=1;i<=n;i++)a[i]=read()+1e9;
	if(!d)
    {
        for(int i=1,j;i<=n;)
        {
            j=i;
            while(j<n&&a[j+1]==a[i])j++;
            if(j-i+1>ans){ans=j-i+1;ansL=i;ansR=j;}
            i=j+1;
        }
        printf("%lld %lld\n",ansL,ansR);
        return 0;
    }
	for(int i=1;i<=n;)
    {
        int j=i;
		zuo[i]=i;
        while(j<n&&a[j+1]%d==a[i]%d){j++;zuo[j]=i;}
        i=j+1;
    }
    r=1;
    build(1,1,n);
    while(l<n)
    {
        l++;gs[a[l]]++;
        while(gs[a[l]]>1||zuo[l]!=zuo[r]){del(1,1,n,r);gs[a[r]]--;r++;}
        while(top1>0&&a[l]<=a[zhan1[top1]]);
        {
            change1(1,1,n,zhan1[top1-1]+1,zhan1[top1],a[l]/d-a[zhan1[top1]]/d);
            top1--;
        }
        zhan1[++top1]=l;
        while(top2>0&&a[l]>=a[zhan2[top2]])
        {
            change2(1,1,n,zhan2[top2-1]+1,zhan2[top2],a[l]/d-a[zhan2[top2]]/d);
            top2--;
        }
        zhan2[++top2]=l;
        int L=find(1,1,n,l+k);
        if(L>=r&&l-L+1>ans){ans=l-L+1;ansL=L;ansR=l;}
    }
    printf("%lld %lld\n",ansL,ansR);
    return 0;
}
/*
*/


#include<bits/stdc++.h>
using namespace std;
#define next Next
#define int long long
#define mid (l+r)/2
const int N=1e6+5;
int n,m,k,d,ans,l,r,top1,top2,ansL,ansR,a[N],zuo[N],zhan1[N],zhan2[N];
int mi[N*4],ma[N*4],tree[N*4],tag1[N*4],tag2[N*4];
map<int,int>gs;
/*char buf[1<<21],*p1=buf,*p2=buf;
inline int gc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}*/
#define gc getchar
inline int read()
{
	int ret=0,f=0;char c=gc();
	while(!isdigit(c)){if(c=='-')f=1;c=gc();}
	while(isdigit(c)){ret=ret*10+c-48;c=gc();}
	if(f)return -ret;return ret;
}
void pushup(int nod)
{
	mi[nod]=min(mi[nod*2],mi[nod*2+1]);
	ma[nod]=max(ma[nod*2],ma[nod*2+1]);
	tree[nod]=min(tree[nod*2],tree[nod*2+1]);
}
void pushdown(int nod)
{
	mi[nod*2]+=tag1[nod];tag1[nod*2]+=tag1[nod];
	mi[nod*2+1]+=tag1[nod];tag1[nod*2+1]+=tag1[nod];
	tag1[nod]=0;
	ma[nod*2]+=tag2[nod];tag2[nod*2]+=tag2[nod];
	ma[nod*2+1]+=tag2[nod];tag2[nod*2+1]+=tag2[nod];
	tag2[nod]=0;
}
void build(int nod,int l,int r)
{
	if(l==r)
	{
		tree[nod]=l;
		mi[nod]=ma[nod]=a[l];
		return;
	}
	build(nod*2,l,mid);
	build(nod*2+1,mid+1,r);
	pushup(nod);
}
int find(int nod,int l,int r,int x)
{
	if(l==r)return l;
	pushdown(nod);
	if(tree[nod*2]<=x)return find(nod*2,l,mid,x);
	else return find(nod*2+1,mid+1,r,x);
}
void del(int nod,int l,int r,int x)
{
	if(l==r){tree[nod]=1e15;return;}
	if(x<=mid)del(nod*2,l,mid,x);
	else del(nod*2+1,mid+1,r,x);
	pushup(nod);
}
void change1(int nod,int l,int r,int L,int R,int val)
{
	if(l==L&&r==R)
	{
		mi[nod]+=val;
		tag1[nod]+=val;
		tree[nod]-=val;
		return;
	}
	pushdown(nod);
	if(R<=mid)change1(nod*2,l,mid,L,R,val);
	else if(L>mid)change1(nod*2+1,mid+1,r,L,R,val);
	else{
		change1(nod*2,l,mid,L,mid,val);
		change1(nod*2+1,mid+1,r,mid+1,R,val);
	}
	pushup(nod);
}
void change2(int nod,int l,int r,int L,int R,int val)
{
	if(l==L&&r==R)
	{
		ma[nod]+=val;
		tag2[nod]+=val;
		tree[nod]+=val;
		return;
	}
	pushdown(nod);
	if(R<=mid)change2(nod*2,l,mid,L,R,val);
	else if(L>mid)change2(nod*2+1,mid+1,r,L,R,val);
	else{
		change2(nod*2,l,mid,L,mid,val);
		change2(nod*2+1,mid+1,r,mid+1,R,val);
	}
	pushup(nod);
}
signed main()
{
	n=read();k=read();d=read();
	for(int i=1;i<=n;i++)a[i]=read()+1e9;
	if(!d)
    {
        for(int i=1,j;i<=n;)
        {
            j=i;
            while(j<n&&a[j+1]==a[i])j++;
            if(j-i+1>ans){ans=j-i+1;ansL=i;ansR=j;}
            i=j+1;
        }
        printf("%lld %lld\n",ansL,ansR);
        return 0;
    }
	for(int i=1;i<=n;)
    {
        int j=i;
		zuo[i]=i;
        while(j<n&&a[j+1]%d==a[i]%d){j++;zuo[j]=i;}
        i=j+1;
    }
    r=1;
    build(1,1,n);
    while(l<n)
    {
        l++;gs[a[l]]++;
        while(gs[a[l]]>1||zuo[l]!=zuo[r])
		{
			del(1,1,n,r);
			gs[a[r]]--;
			r++;
		}
        while(top1>0&&a[l]<=a[zhan1[top1]])
        {
            change1(1,1,n,zhan1[top1-1]+1,zhan1[top1],a[l]/d-a[zhan1[top1]]/d);
            top1--;
        }
        zhan1[++top1]=l;
        while(top2>0&&a[l]>=a[zhan2[top2]])
        {
            change2(1,1,n,zhan2[top2-1]+1,zhan2[top2],a[l]/d-a[zhan2[top2]]/d);
            top2--;
        }
        zhan2[++top2]=l;
        int L=find(1,1,n,l+k);
        if(L>=r&&l-L+1>ans)
		{
			ans=l-L+1;
			ansL=L;ansR=l;
		}
    }
/*
    while(l<n)
    {
        l++;gs[a[l]]++;
        while(gs[a[l]]>1||zuo[l]!=zuo[r])
		{
			del(1,1,n,r);
			gs[a[r]]--;
			r++;
		}
        while(top1>0&&a[l]<=a[zhan1[top1]])
        {
            change1(1,1,n,zhan1[top1-1]+1,zhan1[top1],a[l]/d-a[zhan1[top1]]/d);
            top1--;
        }
        zhan1[++top1]=l;
        while(top2>0&&a[l]>=a[zhan2[top2]])
        {
            change2(1,1,n,zhan2[top2-1]+1,zhan2[top2],a[l]/d-a[zhan2[top2]]/d);
            top2--;
        }
        zhan2[++top2]=l;
        int L=find(1,1,n,l+k);
        if(L>=r&&l-L+1>ans)
		{
			ans=l-L+1;
			ansL=L;ansR=l;
		}
    }
*/
    printf("%lld %lld\n",ansL,ansR);
    return 0;
}
/*
*/


#include<bits/stdc++.h>
using namespace std;
#define next Next
#define int long long
#define mid (l+r)/2
const int N=1e6+5;
int n,m,k,d,ans,l,r,top1,top2,ansL,ansR,a[N],zuo[N],zhan1[N],zhan2[N];
int mi[N*4],ma[N*4],tree[N*4],tag1[N*4],tag2[N*4];
map<int,int>gs;
/*char buf[1<<21],*p1=buf,*p2=buf;
inline int gc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}*/
#define gc getchar
inline int read()
{
	int ret=0,f=0;char c=gc();
	while(!isdigit(c)){if(c=='-')f=1;c=gc();}
	while(isdigit(c)){ret=ret*10+c-48;c=gc();}
	if(f)return -ret;return ret;
}
void pushup(int nod)
{
	mi[nod]=min(mi[nod*2],mi[nod*2+1]);
	ma[nod]=max(ma[nod*2],ma[nod*2+1]);
	tree[nod]=min(tree[nod*2],tree[nod*2+1]);
}
void pushdown(int nod)
{
	mi[nod*2]+=tag1[nod];tag1[nod*2]+=tag1[nod];
	mi[nod*2+1]+=tag1[nod];tag1[nod*2+1]+=tag1[nod];
	tree[nod*2]-=tag1[nod];tree[nod*2+1]-=tag1[nod];
	ma[nod*2]+=tag2[nod];tag2[nod*2]+=tag2[nod];
	ma[nod*2+1]+=tag2[nod];tag2[nod*2+1]+=tag2[nod];
	tree[nod*2]+=tag2[nod];tree[nod*2+1]+=tag2[nod];tag1[nod]=0;tag2[nod]=0;
}
void build(int nod,int l,int r)
{
	if(l==r)
	{
		tree[nod]=l;
		mi[nod]=ma[nod]=a[l];
		return;
	}
	build(nod*2,l,mid);
	build(nod*2+1,mid+1,r);
	pushup(nod);
}
int find(int nod,int l,int r,int x)
{
	if(l==r)return l;
	pushdown(nod);
	if(tree[nod*2]<=x)return find(nod*2,l,mid,x);
	else return find(nod*2+1,mid+1,r,x);
}
void del(int nod,int l,int r,int x)
{
	if(l==r){tree[nod]=1e15;return;}
	pushdown(nod);
	if(x<=mid)del(nod*2,l,mid,x);
	else del(nod*2+1,mid+1,r,x);
	pushup(nod);
}
void change1(int nod,int l,int r,int L,int R,int val)
{
	if(L<=l&&r<=R)
	{
		mi[nod]+=val;
		tag1[nod]+=val;
		tree[nod]-=val;
		return;
	}
	pushdown(nod);
	if(R<=mid)change1(nod*2,l,mid,L,R,val);
	else if(L>mid)change1(nod*2+1,mid+1,r,L,R,val);
	else{
		change1(nod*2,l,mid,L,mid,val);
		change1(nod*2+1,mid+1,r,mid+1,R,val);
	}
	pushup(nod);
}
void change2(int nod,int l,int r,int L,int R,int val)
{
	if(L<=l&&r<=R)
	{
		ma[nod]+=val;
		tag2[nod]+=val;
		tree[nod]+=val;
		return;
	}
	pushdown(nod);
	if(R<=mid)change2(nod*2,l,mid,L,R,val);
	else if(L>mid)change2(nod*2+1,mid+1,r,L,R,val);
	else{
		change2(nod*2,l,mid,L,mid,val);
		change2(nod*2+1,mid+1,r,mid+1,R,val);
	}
	pushup(nod);
}
signed main()
{
	n=read();k=read();d=read();
	for(int i=1;i<=n;i++)a[i]=read()+1e9;
	if(!d)
    {
        for(int i=1,j;i<=n;)
        {
            j=i;
            while(j<n&&a[j+1]==a[i])j++;
            if(j-i+1>ans){ans=j-i+1;ansL=i;ansR=j;}
            i=j+1;
        }
        printf("%lld %lld\n",ansL,ansR);
        return 0;
    }
	for(int i=1;i<=n;)
    {
        int j=i;
		zuo[i]=i;
        while(j<n&&a[j+1]%d==a[i]%d){j++;zuo[j]=i;}
        i=j+1;
    }
    r=1;
    build(1,1,n);
    while(l<n)
    {
        l++;gs[a[l]]++;
        while(gs[a[l]]>1||zuo[l]!=zuo[r])
		{
			del(1,1,n,r);
			gs[a[r]]--;
			r++;
		}
        while(top1>0&&a[l]<=a[zhan1[top1]])
        {
            change1(1,1,n,zhan1[top1-1]+1,zhan1[top1],a[l]/d-a[zhan1[top1]]/d);
            top1--;
        }
        zhan1[++top1]=l;
        while(top2>0&&a[l]>=a[zhan2[top2]])
        {
            change2(1,1,n,zhan2[top2-1]+1,zhan2[top2],a[l]/d-a[zhan2[top2]]/d);
            top2--;
        }
        zhan2[++top2]=l;
        int L=find(1,1,n,l+k);
        if(L>=r&&l-L+1>ans)
		{
			ans=l-L+1;
			ansL=L;ansR=l;
		}
    }
    printf("%lld %lld\n",ansL,ansR);
    return 0;
}
/*
*/


#include<bits/stdc++.h>
using namespace std;
#define next Next
#define int long long
#define mid (l+r)/2
const int N=1e6+5;
int n,m,k,d,ans,l,r,top1,top2,ansL,ansR,a[N],zuo[N],gs[N],zhan1[N],zhan2[N];
int mi[N*4],ma[N*4],tree[N*4],tag1[N*4],tag2[N*4];
/*char buf[1<<21],*p1=buf,*p2=buf;
inline int gc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}*/
#define gc getchar
inline int read()
{
	int ret=0,f=0;char c=gc();
	while(!isdigit(c)){if(c=='-')f=1;c=gc();}
	while(isdigit(c)){ret=ret*10+c-48;c=gc();}
	if(f)return -ret;return ret;
}
void pushup(int nod)
{
	mi[nod]=min(mi[nod*2],mi[nod*2+1]);
	ma[nod]=max(ma[nod*2],ma[nod*2+1]);
	tree[nod]=min(tree[nod*2],tree[nod*2+1]);
}
void pushdown(int nod)
{
	mi[nod*2]+=tag1[nod];tag1[nod*2]+=tag1[nod];
	mi[nod*2+1]+=tag1[nod];tag1[nod*2+1]+=tag1[nod];
	tag1[nod]=0;
	ma[nod*2]+=tag2[nod];tag2[nod*2]+=tag2[nod];
	ma[nod*2+1]+=tag2[nod];tag2[nod*2+1]+=tag2[nod];
	tag2[nod]=0;
}
void build(int nod,int l,int r)
{
	if(l==r)
	{
		tree[nod]=l;
		mi[nod]=ma[nod]=a[l];
		return;
	}
	build(nod*2,l,mid);
	build(nod*2+1,mid+1,r);
	pushup(nod);
}
int find(int nod,int l,int r,int x)
{
	if(l==r)return l;
	pushdown(nod);
	if(tree[nod*2]<=x)return find(nod*2,l,mid,x);
	else return find(nod*2+1,mid+1,r,x);
}
void del(int nod,int l,int r,int x)
{
	if(l==r){tree[nod]=1e15;return;}
	if(x<=mid)del(nod*2,l,mid,x);
	else del(nod*2+1,mid+1,r,x);
	pushup(nod);
}
void change1(int nod,int l,int r,int L,int R,int val)
{
	if(l==L&&r==R)
	{
		mi[nod]+=val;
		tag1[nod]+=val;
		tree[nod]-=val;
		return;
	}
	pushdown(nod);
	if(R<=mid)change1(nod*2,l,mid,L,R,val);
	else if(L>mid)change1(nod*2+1,mid+1,r,L,R,val);
	else{
		change1(nod*2,l,mid,L,mid,val);
		change1(nod*2+1,mid+1,r,mid+1,R,val);
	}
	pushup(nod);
}
void change2(int nod,int l,int r,int L,int R,int val)
{
	if(l==L&&r==R)
	{
		ma[nod]+=val;
		tag2[nod]+=val;
		tree[nod]+=val;
		return;
	}
	pushdown(nod);
	if(R<=mid)change2(nod*2,l,mid,L,R,val);
	else if(L>mid)change2(nod*2+1,mid+1,r,L,R,val);
	else{
		change2(nod*2,l,mid,L,mid,val);
		change2(nod*2+1,mid+1,r,mid+1,R,val);
	}
	pushup(nod);
}
signed main()
{
	n=read();k=read();d=read();
	for(int i=1;i<=n;i++)a[i]=read()+1000000000;
	if(!d)
    {
        for(int i=1,j;i<=n;)
        {
            j=i;
            while(j<n&&a[j+1]==a[i])j++;
            if(j-i+1>ans){ans=j-i+1;ansL=i;ansR=j;}
            i=j+1;
        }
        printf("%lld %lld\n",ansL,ansR);
        return 0;
    }
	for(int i=1;i<=n;)
    {
        int j=i;
		zuo[i]=i;
        while(j<n&&a[j+1]%d==a[i]%d){j++;zuo[j]=i;}
        i=j+1;
    }
    build(1,1,n);
    while(l<n)
    {
        l++;gs[a[l]]++;
        while(gs[a[l]]>1||zuo[l]!=zuo[r])
		{
			del(1,1,n,r);
			gs[a[r]]--;
			r++;
		}
        while(top1>0&&a[l]<=a[zhan1[top1]])
        {
            change1(1,1,n,zhan1[top1-1]+1,zhan1[top1],a[l]/d-a[zhan1[top1]]/d);
            top1--;
        }
        zhan1[++top1]=l;
        while(top2>0&&a[l]>=a[zhan2[top2]])
        {
            change2(1,1,n,zhan2[top2-1]+1,zhan2[top2],a[l]/d-a[zhan2[top2]]/d);
            top2--;
        }
        zhan2[++top2]=l;
        int L=find(1,1,n,l+k);
        if(L>=r&&l-L+1>ans)
		{
			ans=l-L+1;
			ansL=L;ansR=l;
		}
    }
    printf("%lld %lld\n",ansL,ansR);
    return 0;
}
/*
*/


#include<bits/stdc++.h>
using namespace std;
#define next Next
#define int long long
#define mid (l+r)/2
const int N=1e6+5;
int n,m,k,d,ans,l,r,top1,top2,ansL,ansR,a[N],zuo[N],zhan1[N],zhan2[N];
int mi[N*4],ma[N*4],tree[N*4],tag1[N*4],tag2[N*4];
map<int,int>gs;
/*char buf[1<<21],*p1=buf,*p2=buf;
inline int gc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}*/
#define gc getchar
inline int read()
{
	int ret=0,f=0;char c=gc();
	while(!isdigit(c)){if(c=='-')f=1;c=gc();}
	while(isdigit(c)){ret=ret*10+c-48;c=gc();}
	if(f)return -ret;return ret;
}
void pushup(int nod)
{
	mi[nod]=min(mi[nod*2],mi[nod*2+1]);
	ma[nod]=max(ma[nod*2],ma[nod*2+1]);
	tree[nod]=min(tree[nod*2],tree[nod*2+1]);
}
void pushdown(int nod)
{
	mi[nod*2]+=tag1[nod];tag1[nod*2]+=tag1[nod];
	mi[nod*2+1]+=tag1[nod];tag1[nod*2+1]+=tag1[nod];
	tag1[nod]=0;
	ma[nod*2]+=tag2[nod];tag2[nod*2]+=tag2[nod];
	ma[nod*2+1]+=tag2[nod];tag2[nod*2+1]+=tag2[nod];
	tag2[nod]=0;
}
void build(int nod,int l,int r)
{
	if(l==r)
	{
		tree[nod]=l;
		mi[nod]=ma[nod]=a[l];
		return;
	}
	build(nod*2,l,mid);
	build(nod*2+1,mid+1,r);
	pushup(nod);
}
int find(int nod,int l,int r,int x)
{
	if(l==r)return l;
	pushdown(nod);
	if(tree[nod*2]<=x)return find(nod*2,l,mid,x);
	else return find(nod*2+1,mid+1,r,x);
}
void del(int nod,int l,int r,int x)
{
	if(l==r){tree[nod]=1e15;return;}
	if(x<=mid)del(nod*2,l,mid,x);
	else del(nod*2+1,mid+1,r,x);
	pushup(nod);
}
void change1(int nod,int l,int r,int L,int R,int val)
{
	if(l==L&&r==R)
	{
		mi[nod]+=val;
		tag1[nod]+=val;
		tree[nod]-=val;
		return;
	}
	pushdown(nod);
	if(R<=mid)change1(nod*2,l,mid,L,R,val);
	else if(L>mid)change1(nod*2+1,mid+1,r,L,R,val);
	else{
		change1(nod*2,l,mid,L,mid,val);
		change1(nod*2+1,mid+1,r,mid+1,R,val);
	}
	pushup(nod);
}
void change2(int nod,int l,int r,int L,int R,int val)
{
	if(l==L&&r==R)
	{
		ma[nod]+=val;
		tag2[nod]+=val;
		tree[nod]+=val;
		return;
	}
	pushdown(nod);
	if(R<=mid)change2(nod*2,l,mid,L,R,val);
	else if(L>mid)change2(nod*2+1,mid+1,r,L,R,val);
	else{
		change2(nod*2,l,mid,L,mid,val);
		change2(nod*2+1,mid+1,r,mid+1,R,val);
	}
	pushup(nod);
}
signed main()
{
	n=read();k=read();d=read();
	for(int i=1;i<=n;i++)a[i]=read()+1e9;
	if(!d)
    {
        for(int i=1,j;i<=n;)
        {
            j=i;
            while(j<n&&a[j+1]==a[i])j++;
            if(j-i+1>ans){ans=j-i+1;ansL=i;ansR=j;}
            i=j+1;
        }
        printf("%lld %lld\n",ansL,ansR);
        return 0;
    }
	for(int i=1;i<=n;)
    {
        int j=i;
		zuo[i]=i;
        while(j<n&&a[j+1]%d==a[i]%d){j++;zuo[j]=i;}
        i=j+1;
    }
    build(1,1,n);
    while(l<n)
    {
        l++;gs[a[l]]++;
        while(gs[a[l]]>1||zuo[l]!=zuo[r])
		{
			del(1,1,n,r);
			gs[a[r]]--;
			r++;
		}
        while(top1>0&&a[l]<=a[zhan1[top1]])
        {
            change1(1,1,n,zhan1[top1-1]+1,zhan1[top1],a[l]/d-a[zhan1[top1]]/d);
            top1--;
        }
        zhan1[++top1]=l;
        while(top2>0&&a[l]>=a[zhan2[top2]])
        {
            change2(1,1,n,zhan2[top2-1]+1,zhan2[top2],a[l]/d-a[zhan2[top2]]/d);
            top2--;
        }
        zhan2[++top2]=l;
        int L=find(1,1,n,l+k);
        if(L>=r&&l-L+1>ans)
		{
			ans=l-L+1;
			ansL=L;ansR=l;
		}
    }
    printf("%lld %lld\n",ansL,ansR);
    return 0;
}
/*
*/


#include <iostream>
#include <cstdint>
#include <vector>
#include <algorithm>
#include <utility>
#include <cassert>
#include <map>

const uint32_t MAX_N = 1U << 18;
const int64_t INF = 1e16;

template <size_t N>
class SegmentTree {
private:
	int64_t v[2 * N]; //the max val
	int64_t lazy[N];

	uint32_t depth;

	void update_node(uint32_t n, int64_t u) {
		v[n] += u;
		if (n < N) {
			lazy[n] += u;
		}
	}
	void recalc_node(uint32_t n) {
		v[n] = std::max(v[n * 2], v[n * 2 + 1]) + lazy[n];
	}
	void prop_lazy(uint32_t n) {
		if (lazy[n]) {
			update_node(n * 2, lazy[n]);
			update_node(n * 2 + 1, lazy[n]);
			lazy[n] = 0;
		}

	}

	void push_lazy(uint32_t n) {
		for (uint32_t i = depth;i > 0;i--) {
			uint32_t c = n >> i;
			if (c == 0) {
				continue;
			}
			prop_lazy(c);
		}
	}
	void push_updates(uint32_t n) {
		for (n >>= 1;n > 0;n >>= 1) {
			recalc_node(n);
		}
	}

public:
	SegmentTree() {
		std::fill(v, v + 2 * N, 0);
		std::fill(lazy, lazy + N, 0);

		uint32_t t = (2 * N - 1) >> 1;
		depth = 0;
		while (t > 0) {
			depth++;
			t >>= 1;
		}
		//std::cerr << "N is " << N << " depth is " << depth << "\n";
	}

	void clear_prefix(uint32_t len) {
		for (uint32_t i = 0;i < len;i++) {
			uint32_t j = N + i;
			v[j] = 0;
			while (j > 1) {
				j >>= 1;
				v[j] = lazy[j] = 0;
			}
		}
	}
	void update(uint32_t l, uint32_t r, int64_t upd) {
		uint32_t oL = l += N;
		uint32_t oR = r += N;

		for(;l < r;l >>= 1, r >>= 1) {
			if (l & 1) {
				update_node(l++, upd);
			}
			if (r & 1) {
				update_node(--r, upd);
			}
		}

		push_updates(oL);
		push_updates(oR - 1);
	}
	int64_t query(uint32_t l, uint32_t r) {
		uint32_t oL = l += N;
		uint32_t oR = r += N;

		push_lazy(oL);
		push_lazy(oR - 1);

		int64_t ans = -INF;
		for(;l < r;l >>= 1, r >>= 1) {
			if (l & 1) {
				ans = std::max(ans, v[l++]);
			}
			if (r & 1) {
				ans = std::max(ans, v[--r]);
			}
		}
		return ans;
	}

	void set_val(uint32_t n, int64_t u) {

		//std::cerr << "start\n";
		n += N;

		push_lazy(n);

		//std::cerr << "mid\n";
		v[n] = u;
		push_updates(n);

		//std::cerr << "end\n";
	}
	//the index of the last >= Q number
	uint32_t pref_len_greq(int64_t q) {
		uint32_t n = 1;
		uint32_t sz = N;
		uint32_t ans = 0;

		//assert(v[n] >= q);

		while (sz > 1) {
			prop_lazy(n);
			if (v[n * 2 + 1] >= q) {
				ans += sz / 2;
				n = n * 2 + 1;
			} else {
				n = n * 2;
			}
			sz /= 2;
		}

		//assert(query(ans, ans + 1) >= q);
		//assert(query(ans + 1, N) < q);

		return ans;
	}
};

SegmentTree<MAX_N> seg;

std::vector<int32_t> nums;
typedef std::pair<uint32_t, uint32_t> AnsT;
int64_t k, d;

void input() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);

	uint32_t n;
	std::cin >> n >> k >> d;

	nums.resize(n);
	for (int32_t &i : nums) {
		std::cin >> i;
	}
}

struct StEntry {
	int32_t val;
	uint32_t l, r;
};

AnsT solve(std::vector<int32_t> v) {//with a constant mod d
	if (d == 0) {
		return {v.size(), 0};
	}
	std::vector<StEntry> maxSt;
	std::vector<StEntry> minSt;

	AnsT ans = {0, 0};

	std::map<int32_t, uint32_t> lastI;
	uint32_t destrI = v.size();
	//std::cerr << "hi\n";

	for (uint32_t i = v.size() - 1;i < v.size();i--) {

		seg.set_val(i, (i + k) * d + 10);

		uint32_t maxR = i + 1;

		while ((!maxSt.empty()) && (maxSt.back().val <= v[i])) {
			const StEntry &e = maxSt.back();

			seg.update(e.l, e.r, e.val);
			assert(e.r > maxR);
			maxR = e.r;

			maxSt.pop_back();

		}

		seg.update(i, maxR, -v[i]);
		maxSt.push_back({v[i], i, maxR});

		uint32_t minR = i + 1;
		while ((!minSt.empty()) && (minSt.back().val >= v[i])) {
			const StEntry &e = minSt.back();
			seg.update(e.l, e.r, -e.val);
			minR = e.r;

			minSt.pop_back();
		}
		seg.update(i, minR, v[i]);
		minSt.push_back({v[i], i, minR});

		auto it = lastI.find(v[i]);
		if (it != lastI.end()) {
			seg.update(it->second, destrI, -INF);
			destrI = std::min(destrI, it->second);
		}
		lastI[v[i]] = i;

		int64_t q = (int64_t) (i) * d + 10;
		uint32_t j = seg.pref_len_greq(q);

		AnsT curAns = {j - i + 1, i};
		if (curAns.first >= ans.first) {
			ans = curAns;
		}
	}
	seg.clear_prefix(v.size());
	return ans;
}

uint32_t mod_sgn(int32_t v) {
	return d == 0 ? v + (uint32_t) (1.1e9) : (v % d + d) % d;
}

int main() {
	input();
	AnsT ans = {1, 0};
	for (uint32_t i = 0;i < nums.size();) {
		uint32_t l = 1;
		uint32_t mod = mod_sgn(nums[i]);

		while ((i + l < nums.size()) && (mod_sgn(nums[i + l]) == mod)) {
			l++;
		}
		//std::cerr << i << " " << l << "\n";
		AnsT curAns = solve(std::vector<int32_t>(
			nums.begin() + i,
			nums.begin() + i + l
		));
		if (curAns.first > ans.first) {
			ans = {curAns.first, curAns.second + i};
		}

		i += l;
	}

	std::cout << ans.second + 1 << " ";
	std::cout << ans.first + ans.second << "\n";
}


#include <iostream>
#include <cstdint>
#include <vector>
#include <algorithm>
#include <utility>
#include <cassert>
#include <map>

const uint32_t MAX_N = 1U << 18;
const int64_t INF = 1e16;

template <size_t N>
class SegmentTree {
private:
	int64_t v[2 * N]; //the max val
	int64_t lazy[N];

	uint32_t depth;

	void update_node(uint32_t n, int64_t u) {
		v[n] += u;
		if (n < N) {
			lazy[n] += u;
		}
	}
	void recalc_node(uint32_t n) {
		v[n] = std::max(v[n * 2], v[n * 2 + 1]) + lazy[n];
	}
	void prop_lazy(uint32_t n) {
		if (lazy[n]) {
			update_node(n * 2, lazy[n]);
			update_node(n * 2 + 1, lazy[n]);
			lazy[n] = 0;
		}

	}

	void push_lazy(uint32_t n) {
		for (uint32_t i = depth;i > 0;i--) {
			uint32_t c = n >> i;
			if (c == 0) {
				continue;
			}
			prop_lazy(c);
		}
	}
	void push_updates(uint32_t n) {
		for (n >>= 1;n > 0;n >>= 1) {
			recalc_node(n);
		}
	}

public:
	SegmentTree() {
		std::fill(v, v + 2 * N, 0);
		std::fill(lazy, lazy + N, 0);

		uint32_t t = (2 * N - 1) >> 1;
		depth = 0;
		while (t > 0) {
			depth++;
			t >>= 1;
		}
		//std::cerr << "N is " << N << " depth is " << depth << "\n";
	}

	void clear_prefix(uint32_t len) {
		for (uint32_t i = 0;i < len;i++) {
			uint32_t j = N + i;
			v[j] = 0;
			while (j > 1) {
				j >>= 1;
				v[j] = lazy[j] = 0;
			}
		}
	}
	void update(uint32_t l, uint32_t r, int64_t upd) {
		uint32_t oL = l += N;
		uint32_t oR = r += N;

		for(;l < r;l >>= 1, r >>= 1) {
			if (l & 1) {
				update_node(l++, upd);
			}
			if (r & 1) {
				update_node(--r, upd);
			}
		}

		push_updates(oL);
		push_updates(oR - 1);
	}
	void set_val(uint32_t n, int64_t u) {

		//std::cerr << "start\n";
		n += N;

		push_lazy(n);

		//std::cerr << "mid\n";
		v[n] = u;
		push_updates(n);

		//std::cerr << "end\n";
	}
	//the length of the longest prefix, ending with a >= Q number
	uint32_t pref_len_greq(int64_t q) {
		uint32_t n = 1;
		uint32_t sz = N;
		uint32_t ans = 0;

		while (sz > 1) {
			prop_lazy(n);
			if (v[n * 2 + 1] >= q) {
				ans += sz / 2;
				n = n * 2 + 1;
			} else {
				n = n * 2;
			}
			sz /= 2;
		}
		return ans;
	}
};

SegmentTree<MAX_N> seg;

std::vector<int32_t> nums;
typedef std::pair<uint32_t, uint32_t> AnsT;
int64_t k, d;

void input() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);

	uint32_t n;
	std::cin >> n >> k >> d;

	nums.resize(n);
	for (int32_t &i : nums) {
		std::cin >> i;
	}
}

struct StEntry {
	int32_t val;
	uint32_t l, r;
};

AnsT solve(std::vector<int32_t> v) {//with a constant mod d
	if (d == 0) {
		return {v.size(), 0};
	}
	std::vector<StEntry> maxSt;
	std::vector<StEntry> minSt;

	AnsT ans = {0, 0};

	std::map<int32_t, uint32_t> lastI;
	uint32_t destrI = v.size();
	//std::cerr << "hi\n";

	for (uint32_t i = v.size() - 1;i < v.size();i--) {

		seg.set_val(i, (i + k) * d + 10);

		uint32_t maxR = i + 1;

		while ((!maxSt.empty()) && (maxSt.back().val <= v[i])) {
			const StEntry &e = maxSt.back();

			seg.update(e.l, e.r, e.val);
			assert(e.r > maxR);
			maxR = e.r;

			maxSt.pop_back();

		}

		seg.update(i, maxR, -v[i]);
		maxSt.push_back({v[i], i, maxR});

		uint32_t minR = i + 1;
		while ((!minSt.empty()) && (minSt.back().val >= v[i])) {
			const StEntry &e = minSt.back();
			seg.update(e.l, e.r, -e.val);
			minR = e.r;

			minSt.pop_back();
		}
		seg.update(i, minR, v[i]);
		minSt.push_back({v[i], i, minR});

		auto it = lastI.find(v[i]);
		if (it != lastI.end()) {
			seg.update(it->second, destrI, -INF);
			destrI = it->second;
		}
		lastI[v[i]] = i;

		int64_t q = (int64_t) (i) * d + 10;
		uint32_t j = seg.pref_len_greq(q);

		AnsT curAns = {j - i + 1, i};
		if (curAns.first >= ans.first) {
			ans = curAns;
		}
	}
	seg.clear_prefix(v.size());
	return ans;
}

uint32_t mod_sgn(int32_t v) {
	return d == 0 ? v + (uint32_t) (1.1e9) : (v % d + d) % d;
}

int main() {
	input();
	AnsT ans = {1, 0};
	for (uint32_t i = 0;i < nums.size();) {
		uint32_t l = 1;
		uint32_t mod = mod_sgn(nums[i]);

		while ((i + l < nums.size()) && (mod_sgn(nums[i + l]) == mod)) {
			l++;
		}
		//std::cerr << i << " " << l << "\n";
		AnsT curAns = solve(std::vector<int32_t>(
			nums.begin() + i,
			nums.begin() + i + l
		));
		if (curAns.first > ans.first) {
			ans = {curAns.first, curAns.second + i};
		}

		i += l;
	}

	std::cout << ans.second + 1 << " ";
	std::cout << ans.first + ans.second << "\n";
}


#include <iostream>
#include <cstdint>
#include <vector>
#include <algorithm>
#include <utility>
#include <cassert>
#include <map>

const uint32_t MAX_N = 1U << 18;
const int64_t INF = 1e16;

template <size_t N>
class SegmentTree {
private:
	int64_t v[2 * N]; //the max val
	int64_t lazy[N];

	uint32_t depth;

	void update_node(uint32_t n, int64_t u) {
		v[n] += u;
		if (n < N) {
			lazy[n] += u;
		}
	}
	void recalc_node(uint32_t n) {
		v[n] = std::max(v[n * 2], v[n * 2 + 1]) + lazy[n];
	}
	void prop_lazy(uint32_t n) {
		if (lazy[n]) {
			update_node(n * 2, lazy[n]);
			update_node(n * 2 + 1, lazy[n]);
			lazy[n] = 0;
		}

	}

	void push_lazy(uint32_t n) {
		for (uint32_t i = depth;i > 0;i--) {
			uint32_t c = n >> i;
			if (c == 0) {
				continue;
			}
			prop_lazy(c);
		}
	}
	void push_updates(uint32_t n) {
		for (n >>= 1;n > 0;n >>= 1) {
			recalc_node(n);
		}
	}

public:
	SegmentTree() {
		std::fill(v, v + 2 * N, 0);
		std::fill(lazy, lazy + N, 0);

		uint32_t t = (2 * N - 1) >> 1;
		depth = 0;
		while (t > 0) {
			depth++;
			t >>= 1;
		}
		//std::cerr << "N is " << N << " depth is " << depth << "\n";
	}

	void clear_prefix(uint32_t len) {
		for (uint32_t i = 0;i < len;i++) {
			uint32_t j = N + i;
			v[j] = 0;
			while (j > 1) {
				j >>= 1;
				v[j] = lazy[j] = 0;
			}
		}
	}
	void update(uint32_t l, uint32_t r, int64_t upd) {
		uint32_t oL = l += N;
		uint32_t oR = r += N;

		for(;l < r;l >>= 1, r >>= 1) {
			if (l & 1) {
				update_node(l++, upd);
			}
			if (r & 1) {
				update_node(--r, upd);
			}
		}

		push_updates(oL);
		push_updates(oR - 1);
	}
	int64_t query(uint32_t l, uint32_t r) {
		uint32_t oL = l += N;
		uint32_t oR = r += N;

		push_lazy(oL);
		push_lazy(oR - 1);

		int64_t ans = -INF;
		for(;l < r;l >>= 1, r >>= 1) {
			if (l & 1) {
				ans = std::max(ans, v[l++]);
			}
			if (r & 1) {
				ans = std::max(ans, v[--r]);
			}
		}
		return ans;
	}

	void set_val(uint32_t n, int64_t u) {

		//std::cerr << "start\n";
		n += N;

		push_lazy(n);

		//std::cerr << "mid\n";
		v[n] = u;
		push_updates(n);

		//std::cerr << "end\n";
	}
	//the index of the last >= Q number
	uint32_t pref_len_greq(int64_t q) {
		uint32_t n = 1;
		uint32_t sz = N;
		uint32_t ans = 0;

		assert(v[n] >= q);

		while (sz > 1) {
			prop_lazy(n);
			if (v[n * 2 + 1] >= q) {
				ans += sz / 2;
				n = n * 2 + 1;
			} else {
				n = n * 2;
			}
			sz /= 2;
		}

		assert(query(ans, ans + 1) >= q);
		assert(query(ans + 1, N) < q);

		return ans;
	}
};

SegmentTree<MAX_N> seg;

std::vector<int32_t> nums;
typedef std::pair<uint32_t, uint32_t> AnsT;
int64_t k, d;

void input() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);

	uint32_t n;
	std::cin >> n >> k >> d;

	nums.resize(n);
	for (int32_t &i : nums) {
		std::cin >> i;
	}
}

struct StEntry {
	int32_t val;
	uint32_t l, r;
};

AnsT solve(std::vector<int32_t> v) {//with a constant mod d
	if (d == 0) {
		return {v.size(), 0};
	}
	std::vector<StEntry> maxSt;
	std::vector<StEntry> minSt;

	AnsT ans = {0, 0};

	std::map<int32_t, uint32_t> lastI;
	uint32_t destrI = v.size();
	//std::cerr << "hi\n";

	for (uint32_t i = v.size() - 1;i < v.size();i--) {

		seg.set_val(i, (i + k) * d + 10);

		uint32_t maxR = i + 1;

		while ((!maxSt.empty()) && (maxSt.back().val <= v[i])) {
			const StEntry &e = maxSt.back();

			seg.update(e.l, e.r, e.val);
			assert(e.r > maxR);
			maxR = e.r;

			maxSt.pop_back();

		}

		seg.update(i, maxR, -v[i]);
		maxSt.push_back({v[i], i, maxR});

		uint32_t minR = i + 1;
		while ((!minSt.empty()) && (minSt.back().val >= v[i])) {
			const StEntry &e = minSt.back();
			seg.update(e.l, e.r, -e.val);
			minR = e.r;

			minSt.pop_back();
		}
		seg.update(i, minR, v[i]);
		minSt.push_back({v[i], i, minR});

		auto it = lastI.find(v[i]);
		if (it != lastI.end()) {
			seg.update(it->second, destrI, -INF);
			destrI = std::min(destrI, it->second);
		}
		lastI[v[i]] = i;

		int64_t q = (int64_t) (i) * d + 10;
		uint32_t j = seg.pref_len_greq(q);

		AnsT curAns = {j - i + 1, i};
		if (curAns.first >= ans.first) {
			ans = curAns;
		}
	}
	seg.clear_prefix(v.size());
	return ans;
}

uint32_t mod_sgn(int32_t v) {
	return d == 0 ? v + (uint32_t) (1.1e9) : (v % d + d) % d;
}

int main() {
	input();
	AnsT ans = {1, 0};
	for (uint32_t i = 0;i < nums.size();) {
		uint32_t l = 1;
		uint32_t mod = mod_sgn(nums[i]);

		while ((i + l < nums.size()) && (mod_sgn(nums[i + l]) == mod)) {
			l++;
		}
		//std::cerr << i << " " << l << "\n";
		AnsT curAns = solve(std::vector<int32_t>(
			nums.begin() + i,
			nums.begin() + i + l
		));
		if (curAns.first > ans.first) {
			ans = {curAns.first, curAns.second + i};
		}

		i += l;
	}

	std::cout << ans.second + 1 << " ";
	std::cout << ans.first + ans.second << "\n";
}


#include <iostream>
#include <cstdint>
#include <vector>
#include <algorithm>
#include <utility>
#include <cassert>
#include <map>

const uint32_t MAX_N = 1U << 18;
const int64_t INF = 1e17;

template <size_t N>
class SegmentTree {
private:
	int64_t v[2 * N]; //the max val
	int64_t lazy[N];

	uint32_t depth;

	void update_node(uint32_t n, int64_t u) {
		v[n] += u;
		if (n < N) {
			lazy[n] += u;
		}
	}
	void recalc_node(uint32_t n) {
		v[n] = std::max(v[n * 2], v[n * 2 + 1]) + lazy[n];
	}
	void prop_lazy(uint32_t n) {
		if (lazy[n]) {
			update_node(n * 2, lazy[n]);
			update_node(n * 2 + 1, lazy[n]);
			lazy[n] = 0;
		}

	}

	void push_lazy(uint32_t n) {
		for (uint32_t i = depth;i > 0;i--) {
			uint32_t c = n >> i;
			if (c == 0) {
				continue;
			}
			prop_lazy(c);
		}
	}
	void push_updates(uint32_t n) {
		for (n >>= 1;n > 0;n >>= 1) {
			recalc_node(n);
		}
	}

public:
	SegmentTree() {
		std::fill(v, v + 2 * N, 0);
		std::fill(lazy, lazy + N, 0);

		uint32_t t = (2 * N - 1) >> 1;
		depth = 0;
		while (t > 0) {
			depth++;
			t >>= 1;
		}
		//std::cerr << "N is " << N << " depth is " << depth << "\n";
	}

	void clear_prefix(uint32_t len) {
		for (uint32_t i = 0;i < len;i++) {
			uint32_t j = N + i;
			v[j] = 0;
			while (j > 1) {
				j >>= 1;
				v[j] = lazy[j] = 0;
			}
		}
	}
	void update(uint32_t l, uint32_t r, int64_t upd) {
		uint32_t oL = l += N;
		uint32_t oR = r += N;

		for(;l < r;l >>= 1, r >>= 1) {
			if (l & 1) {
				update_node(l++, upd);
			}
			if (r & 1) {
				update_node(--r, upd);
			}
		}

		push_updates(oL);
		push_updates(oR - 1);
	}
	int64_t query(uint32_t l, uint32_t r) {
		uint32_t oL = l += N;
		uint32_t oR = r += N;

		push_lazy(oL);
		push_lazy(oR - 1);

		int64_t ans = -INF;
		for(;l < r;l >>= 1, r >>= 1) {
			if (l & 1) {
				ans = std::max(ans, v[l++]);
			}
			if (r & 1) {
				ans = std::max(ans, v[--r]);
			}
		}
		return ans;
	}

	void set_val(uint32_t n, int64_t u) {

		//std::cerr << "start\n";
		n += N;

		push_lazy(n);

		//std::cerr << "mid\n";
		v[n] = u;
		push_updates(n);

		//std::cerr << "end\n";
	}
	//the index of the last >= Q number
	uint32_t pref_len_greq(int64_t q) {
		uint32_t n = 1;
		uint32_t sz = N;
		uint32_t ans = 0;

		assert(v[n] >= q);

		while (sz > 1) {
			prop_lazy(n);
			if (v[n * 2 + 1] >= q) {
				ans += sz / 2;
				n = n * 2 + 1;
			} else {
				n = n * 2;
			}
			sz /= 2;
		}

		assert(query(ans, ans + 1) >= q);
		assert(query(ans + 1, N) < q);

		return ans;
	}
};

SegmentTree<MAX_N> seg;

std::vector<int32_t> nums;
typedef std::pair<uint32_t, uint32_t> AnsT;
int64_t k, d;

void input() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);

	uint32_t n;
	std::cin >> n >> k >> d;

	nums.resize(n);
	for (int32_t &i : nums) {
		std::cin >> i;
	}
}

struct StEntry {
	int32_t val;
	uint32_t l, r;
};

AnsT solve(std::vector<int32_t> v) {//with a constant mod d
	if (d == 0) {
		return {v.size(), 0};
	}
	std::vector<StEntry> maxSt;
	std::vector<StEntry> minSt;

	AnsT ans = {0, 0};

	std::map<int32_t, uint32_t> lastI;
	uint32_t destrI = v.size();
	//std::cerr << "hi\n";

	for (uint32_t i = v.size() - 1;i < v.size();i--) {

		seg.set_val(i, (i + k) * d + 10);

		uint32_t maxR = i + 1;

		while ((!maxSt.empty()) && (maxSt.back().val <= v[i])) {
			const StEntry &e = maxSt.back();

			seg.update(e.l, e.r, e.val);
			assert(e.r > maxR);
			maxR = e.r;

			maxSt.pop_back();

		}

		seg.update(i, maxR, -v[i]);
		maxSt.push_back({v[i], i, maxR});

		uint32_t minR = i + 1;
		while ((!minSt.empty()) && (minSt.back().val >= v[i])) {
			const StEntry &e = minSt.back();
			seg.update(e.l, e.r, -e.val);
			minR = e.r;

			minSt.pop_back();
		}
		seg.update(i, minR, v[i]);
		minSt.push_back({v[i], i, minR});

		auto it = lastI.find(v[i]);
		if (it != lastI.end()) {
			seg.update(it->second, destrI, -INF);
			destrI = it->second;
		}
		lastI[v[i]] = i;

		int64_t q = (int64_t) (i) * d + 10;
		uint32_t j = seg.pref_len_greq(q);

		AnsT curAns = {j - i + 1, i};
		if (curAns.first >= ans.first) {
			ans = curAns;
		}
	}
	seg.clear_prefix(v.size());
	return ans;
}

uint32_t mod_sgn(int32_t v) {
	return d == 0 ? v + (uint32_t) (1.1e9) : (v % d + d) % d;
}

int main() {
	input();
	AnsT ans = {1, 0};
	for (uint32_t i = 0;i < nums.size();) {
		uint32_t l = 1;
		uint32_t mod = mod_sgn(nums[i]);

		while ((i + l < nums.size()) && (mod_sgn(nums[i + l]) == mod)) {
			l++;
		}
		//std::cerr << i << " " << l << "\n";
		AnsT curAns = solve(std::vector<int32_t>(
			nums.begin() + i,
			nums.begin() + i + l
		));
		if (curAns.first > ans.first) {
			ans = {curAns.first, curAns.second + i};
		}

		i += l;
	}

	std::cout << ans.second + 1 << " ";
	std::cout << ans.first + ans.second << "\n";
}


#include <iostream>
#include <cstdint>

int main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);

	uint32_t n;
	std::cin >> n;

	uint64_t triangCnt = 0;
	uint64_t leftS = 0;

	for (uint32_t i = 0;i < n;i++) {
		uint64_t curS;
		std::cin >> curS;

		uint64_t curD = std::min(curS / 2, leftS);
		triangCnt += curD;
		curS -= 2 * curD;
		leftS -= curD;

		uint64_t curT = curS / 3;
		triangCnt += curT;
		curS -= curT * 3;
		leftS += curS;
	}
	std::cout << triangCnt << "\n";
}


#include <iostream>
#include <cstdint>
#include <vector>
#include <algorithm>
#include <utility>
#include <map>

const uint32_t MAX_N = 1U << 18;
const int64_t INF = 1e16;

template <size_t N>
class SegmentTree {
private:
	int64_t v[2 * N]; //the max val
	int64_t lazy[N];

	uint32_t depth;

	void update_node(uint32_t n, int64_t u) {
		v[n] += u;
		if (n < N) {
			lazy[n] += u;
		}
	}
	void recalc_node(uint32_t n) {
		v[n] = std::max(v[n * 2], v[n * 2 + 1]) + lazy[n];
	}
	void prop_lazy(uint32_t n) {
		if (lazy[n]) {
			update_node(n * 2, lazy[n]);
			update_node(n * 2 + 1, lazy[n]);
			lazy[n] = 0;
		}

	}

	void push_lazy(uint32_t n) {
		for (uint32_t i = depth;i > 0;i--) {
			uint32_t c = n >> i;
			if (c == 0) {
				continue;
			}
			prop_lazy(c);
		}
	}
	void push_updates(uint32_t n) {
		for (n >>= 1;n > 0;n >>= 1) {
			recalc_node(n);
		}
	}

public:
	SegmentTree() {
		std::fill(v, v + 2 * N, 0);
		std::fill(lazy, lazy + N, 0);

		uint32_t t = (2 * N - 1) >> 1;
		depth = 0;
		while (t > 0) {
			depth++;
			t >>= 1;
		}
		//std::cerr << "N is " << N << " depth is " << depth << "\n";
	}

	void clear_prefix(uint32_t len) {
		for (uint32_t i = 0;i < len;i++) {
			uint32_t j = N + i;
			v[j] = 0;
			while (j > 1) {
				j >>= 1;
				v[j] = lazy[j] = 0;
			}
		}
	}
	void update(uint32_t l, uint32_t r, int64_t upd) {
		uint32_t oL = l += N;
		uint32_t oR = r += N;

		for(;l < r;l >>= 1, r >>= 1) {
			if (l & 1) {
				update_node(l++, upd);
			}
			if (r & 1) {
				update_node(--r, upd);
			}
		}

		push_updates(oL);
		push_updates(oR - 1);
	}
	void set_val(uint32_t n, int64_t u) {

		//std::cerr << "start\n";
		n += N;

		push_lazy(n);

		//std::cerr << "mid\n";
		v[n] = u;
		push_updates(n);

		//std::cerr << "end\n";
	}
	//the length of the longest prefix, ending with a >= Q number
	uint32_t pref_len_greq(int64_t q) {
		uint32_t n = 1;
		uint32_t sz = N;
		uint32_t ans = 0;

		while (sz > 1) {
			prop_lazy(n);
			if (v[n * 2 + 1] >= q) {
				ans += sz / 2;
				n = n * 2 + 1;
			} else {
				n = n * 2;
			}
			sz /= 2;
		}
		return ans;
	}
};

SegmentTree<MAX_N> seg;

std::vector<int32_t> nums;
typedef std::pair<uint32_t, uint32_t> AnsT;
int64_t k, d;

void input() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);

	uint32_t n;
	std::cin >> n >> k >> d;

	nums.resize(n);
	for (int32_t &i : nums) {
		std::cin >> i;
	}
}

struct StEntry {
	int32_t val;
	uint32_t l, r;
};

AnsT solve(std::vector<int32_t> v) {//with a constant mod d
	if (d == 0) {
		return {v.size(), 0};
	}
	std::vector<StEntry> maxSt;
	std::vector<StEntry> minSt;

	AnsT ans = {0, 0};

	std::map<int32_t, uint32_t> lastI;
	uint32_t destrI = v.size();
	//std::cerr << "hi\n";

	for (uint32_t i = v.size() - 1;i < v.size();i--) {

		seg.set_val(i, (i + k) * d + 1);

		uint32_t maxR = i + 1;

		while ((!maxSt.empty()) && (maxSt.back().val <= v[i])) {
			const StEntry &e = maxSt.back();

			seg.update(e.l, e.r, e.val);
			maxR = e.r;

			maxSt.pop_back();

		}

		seg.update(i, maxR, -v[i]);
		maxSt.push_back({v[i], i, maxR});

		uint32_t minR = i + 1;
		while ((!minSt.empty()) && (minSt.back().val >= v[i])) {
			const StEntry &e = minSt.back();
			seg.update(e.l, e.r, -e.val);
			minR = e.r;

			minSt.pop_back();
		}
		seg.update(i, minR, v[i]);

		auto it = lastI.find(v[i]);
		if (it != lastI.end()) {
			seg.update(it->second, destrI, -INF);
			destrI = it->second;
		}
		lastI[v[i]] = i;

		int64_t q = (int64_t) (i) * d + 1;
		uint32_t j = seg.pref_len_greq(q);

		AnsT curAns = {j - i + 1, i};
		if (curAns.first >= ans.first) {
			ans = curAns;
		}
	}
	seg.clear_prefix(v.size());
	return ans;
}

uint32_t mod_sgn(int32_t v) {
	return d == 0 ? v + (uint32_t) (1.1e9) : (v % d + d) % d;
}

int main() {
	input();
	AnsT ans = {1, 0};
	for (uint32_t i = 0;i < nums.size();) {
		uint32_t l = 1;
		uint32_t mod = mod_sgn(nums[i]);

		while ((i + l < nums.size()) && (mod_sgn(nums[i + l]) == mod)) {
			l++;
		}
		//std::cerr << i << " " << l << "\n";
		AnsT curAns = solve(std::vector<int32_t>(
			nums.begin() + i,
			nums.begin() + i + l
		));
		if (curAns.first > ans.first) {
			ans = {curAns.first, curAns.second + i};
		}

		i += l;
	}

	std::cout << ans.second + 1 << " ";
	std::cout << ans.first + ans.second << "\n";
}


#include <iostream>
#include <cstdint>
#include <vector>
#include <algorithm>
#include <utility>
#include <map>

const uint32_t MAX_N = 1U << 18;
const int64_t INF = 1e16;

template <size_t N>
class SegmentTree {
private:
	int64_t v[2 * N]; //the max val
	int64_t lazy[N];

	uint32_t depth;

	void update_node(uint32_t n, int64_t u) {
		v[n] += u;
		if (n < N) {
			lazy[n] += u;
		}
	}
	void recalc_node(uint32_t n) {
		v[n] = std::max(v[n * 2], v[n * 2 + 1]) + lazy[n];
	}
	void prop_lazy(uint32_t n) {
		if (lazy[n]) {
			update_node(n * 2, lazy[n]);
			update_node(n * 2 + 1, lazy[n]);
			lazy[n] = 0;
		}

	}

	void push_lazy(uint32_t n) {
		for (uint32_t i = depth;i > 0;i--) {
			uint32_t c = n >> i;
			if (c == 0) {
				continue;
			}
			prop_lazy(c);
		}
	}
	void push_updates(uint32_t n) {
		for (n >>= 1;n > 0;n >>= 1) {
			recalc_node(n);
		}
	}

public:
	SegmentTree() {
		std::fill(v, v + 2 * N, 0);
		std::fill(lazy, lazy + N, 0);

		uint32_t t = (2 * N - 1) >> 1;
		depth = 0;
		while (t > 0) {
			depth++;
			t >>= 1;
		}
		//std::cerr << "N is " << N << " depth is " << depth << "\n";
	}

	void clear_prefix(uint32_t len) {
		for (uint32_t i = 0;i < len;i++) {
			uint32_t j = N + i;
			v[j] = 0;
			while (j > 1) {
				j >>= 1;
				v[j] = lazy[j] = 0;
			}
		}
	}
	void update(uint32_t l, uint32_t r, int64_t upd) {
		uint32_t oL = l += N;
		uint32_t oR = r += N;

		for(;l < r;l >>= 1, r >>= 1) {
			if (l & 1) {
				update_node(l++, upd);
			}
			if (r & 1) {
				update_node(--r, upd);
			}
		}

		push_updates(oL);
		push_updates(oR - 1);
	}
	void set_val(uint32_t n, int64_t u) {

		//std::cerr << "start\n";
		n += N;

		push_lazy(n);

		//std::cerr << "mid\n";
		v[n] = u;
		push_updates(n);

		//std::cerr << "end\n";
	}
	//the length of the longest prefix, ending with a >= Q number
	uint32_t pref_len_greq(int64_t q) {
		uint32_t n = 1;
		uint32_t sz = N;
		uint32_t ans = 0;

		while (sz > 1) {
			prop_lazy(n);
			if (v[n * 2 + 1] >= q) {
				ans += sz / 2;
				n = n * 2 + 1;
			} else {
				n = n * 2;
			}
			sz /= 2;
		}
		return ans;
	}
};

SegmentTree<MAX_N> seg;

std::vector<int32_t> nums;
typedef std::pair<uint32_t, uint32_t> AnsT;
int64_t k, d;

void input() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);

	uint32_t n;
	std::cin >> n >> k >> d;

	nums.resize(n);
	for (int32_t &i : nums) {
		std::cin >> i;
	}
}

struct StEntry {
	int32_t val;
	uint32_t l, r;
};

AnsT solve(std::vector<int32_t> v) {//with a constant mod d
	std::vector<StEntry> maxSt;
	std::vector<StEntry> minSt;

	AnsT ans = {0, 0};

	std::map<int32_t, uint32_t> lastI;
	uint32_t destrI = v.size();
	//std::cerr << "hi\n";

	for (uint32_t i = v.size() - 1;i < v.size();i--) {

		seg.set_val(i, (i + k) * d + 1);

		uint32_t maxR = i + 1;

		while ((!maxSt.empty()) && (maxSt.back().val <= v[i])) {
			const StEntry &e = maxSt.back();

			seg.update(e.l, e.r, e.val);
			maxR = e.r;

			maxSt.pop_back();

		}

		seg.update(i, maxR, -v[i]);
		maxSt.push_back({v[i], i, maxR});

		uint32_t minR = i + 1;
		while ((!minSt.empty()) && (minSt.back().val >= v[i])) {
			const StEntry &e = minSt.back();
			seg.update(e.l, e.r, -e.val);
			minR = e.r;

			minSt.pop_back();
		}
		seg.update(i, minR, v[i]);

		auto it = lastI.find(v[i]);
		if (it != lastI.end()) {
			seg.update(it->second, destrI, -INF);
			destrI = it->second;
		}
		lastI[v[i]] = i;

		int64_t q = (int64_t) (i) * d + 1;
		uint32_t j = seg.pref_len_greq(q);

		AnsT curAns = {j - i + 1, i};
		if (curAns.first >= ans.first) {
			ans = curAns;
		}
	}
	seg.clear_prefix(v.size());
	return ans;
}

int main() {
	input();
	AnsT ans = {1, 0};
	for (uint32_t i = 0;i < nums.size();) {
		uint32_t l = 1;
		int32_t mod = (nums[i] % d + d) % d;

		while ((i + l < nums.size()) && ((nums[i + l] % d + d) % d == mod)) {
			l++;
		}
		//std::cerr << i << " " << l << "\n";
		AnsT curAns = solve(std::vector<int32_t>(
			nums.begin() + i,
			nums.begin() + i + l
		));
		if (curAns.first > ans.first) {
			ans = {curAns.first, curAns.second + i};
		}

		i += l;
	}

	std::cout << ans.second + 1 << " ";
	std::cout << ans.first + ans.second << "\n";
}


#include <iostream>
#include <cstdint>
#include <vector>
#include <algorithm>
#include <utility>
#include <cassert>
#include <map>

const uint32_t MAX_N = 1U << 18;
const int64_t INF = 1e17;

template <size_t N>
class SegmentTree {
private:
	int64_t v[2 * N]; //the max val
	int64_t lazy[N];

	uint32_t depth;

	void update_node(uint32_t n, int64_t u) {
		v[n] += u;
		if (n < N) {
			lazy[n] += u;
		}
	}
	void recalc_node(uint32_t n) {
		v[n] = std::max(v[n * 2], v[n * 2 + 1]) + lazy[n];
	}
	void prop_lazy(uint32_t n) {
		if (lazy[n]) {
			update_node(n * 2, lazy[n]);
			update_node(n * 2 + 1, lazy[n]);
			lazy[n] = 0;
		}

	}

	void push_lazy(uint32_t n) {
		for (uint32_t i = depth;i > 0;i--) {
			uint32_t c = n >> i;
			if (c == 0) {
				continue;
			}
			prop_lazy(c);
		}
	}
	void push_updates(uint32_t n) {
		for (n >>= 1;n > 0;n >>= 1) {
			recalc_node(n);
		}
	}

public:
	SegmentTree() {
		std::fill(v, v + 2 * N, 0);
		std::fill(lazy, lazy + N, 0);

		uint32_t t = (2 * N - 1) >> 1;
		depth = 0;
		while (t > 0) {
			depth++;
			t >>= 1;
		}
		//std::cerr << "N is " << N << " depth is " << depth << "\n";
	}

	void clear_prefix(uint32_t len) {
		for (uint32_t i = 0;i < len;i++) {
			uint32_t j = N + i;
			v[j] = 0;
			while (j > 1) {
				j >>= 1;
				v[j] = lazy[j] = 0;
			}
		}
	}
	void update(uint32_t l, uint32_t r, int64_t upd) {
		uint32_t oL = l += N;
		uint32_t oR = r += N;

		for(;l < r;l >>= 1, r >>= 1) {
			if (l & 1) {
				update_node(l++, upd);
			}
			if (r & 1) {
				update_node(--r, upd);
			}
		}

		push_updates(oL);
		push_updates(oR - 1);
	}
	int64_t query(uint32_t l, uint32_t r) {
		uint32_t oL = l += N;
		uint32_t oR = r += N;

		push_lazy(oL);
		push_lazy(oR - 1);

		int64_t ans = -INF;
		for(;l < r;l >>= 1, r >>= 1) {
			if (l & 1) {
				ans = std::max(ans, v[l++]);
			}
			if (r & 1) {
				ans = std::max(ans, v[--r]);
			}
		}
		return ans;
	}

	void set_val(uint32_t n, int64_t u) {

		//std::cerr << "start\n";
		n += N;

		push_lazy(n);

		//std::cerr << "mid\n";
		v[n] = u;
		push_updates(n);

		//std::cerr << "end\n";
	}
	//the index of the last >= Q number
	uint32_t pref_len_greq(int64_t q) {
		uint32_t n = 1;
		uint32_t sz = N;
		uint32_t ans = 0;

		assert(v[n] >= q);

		while (sz > 1) {
			prop_lazy(n);
			if (v[n * 2 + 1] >= q) {
				ans += sz / 2;
				n = n * 2 + 1;
			} else {
				n = n * 2;
			}
			sz /= 2;
		}

		assert(query(ans, ans + 1) == q);
		assert(query(ans + 1, N) < q);

		return ans;
	}
};

SegmentTree<MAX_N> seg;

std::vector<int32_t> nums;
typedef std::pair<uint32_t, uint32_t> AnsT;
int64_t k, d;

void input() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);

	uint32_t n;
	std::cin >> n >> k >> d;

	nums.resize(n);
	for (int32_t &i : nums) {
		std::cin >> i;
	}
}

struct StEntry {
	int32_t val;
	uint32_t l, r;
};

AnsT solve(std::vector<int32_t> v) {//with a constant mod d
	if (d == 0) {
		return {v.size(), 0};
	}
	std::vector<StEntry> maxSt;
	std::vector<StEntry> minSt;

	AnsT ans = {0, 0};

	std::map<int32_t, uint32_t> lastI;
	uint32_t destrI = v.size();
	//std::cerr << "hi\n";

	for (uint32_t i = v.size() - 1;i < v.size();i--) {

		seg.set_val(i, (i + k) * d + 10);

		uint32_t maxR = i + 1;

		while ((!maxSt.empty()) && (maxSt.back().val <= v[i])) {
			const StEntry &e = maxSt.back();

			seg.update(e.l, e.r, e.val);
			assert(e.r > maxR);
			maxR = e.r;

			maxSt.pop_back();

		}

		seg.update(i, maxR, -v[i]);
		maxSt.push_back({v[i], i, maxR});

		uint32_t minR = i + 1;
		while ((!minSt.empty()) && (minSt.back().val >= v[i])) {
			const StEntry &e = minSt.back();
			seg.update(e.l, e.r, -e.val);
			minR = e.r;

			minSt.pop_back();
		}
		seg.update(i, minR, v[i]);
		minSt.push_back({v[i], i, minR});

		auto it = lastI.find(v[i]);
		if (it != lastI.end()) {
			seg.update(it->second, destrI, -INF);
			destrI = it->second;
		}
		lastI[v[i]] = i;

		int64_t q = (int64_t) (i) * d + 10;
		uint32_t j = seg.pref_len_greq(q);

		AnsT curAns = {j - i + 1, i};
		if (curAns.first >= ans.first) {
			ans = curAns;
		}
	}
	seg.clear_prefix(v.size());
	return ans;
}

uint32_t mod_sgn(int32_t v) {
	return d == 0 ? v + (uint32_t) (1.1e9) : (v % d + d) % d;
}

int main() {
	input();
	AnsT ans = {1, 0};
	for (uint32_t i = 0;i < nums.size();) {
		uint32_t l = 1;
		uint32_t mod = mod_sgn(nums[i]);

		while ((i + l < nums.size()) && (mod_sgn(nums[i + l]) == mod)) {
			l++;
		}
		//std::cerr << i << " " << l << "\n";
		AnsT curAns = solve(std::vector<int32_t>(
			nums.begin() + i,
			nums.begin() + i + l
		));
		if (curAns.first > ans.first) {
			ans = {curAns.first, curAns.second + i};
		}

		i += l;
	}

	std::cout << ans.second + 1 << " ";
	std::cout << ans.first + ans.second << "\n";
}


#include<cstdio>
#include<algorithm>
#include<map>
#include<utility>

using namespace std;

#define F first
#define S second

const int MAXN = 2e5 + 10;
const int INF = 1e8;
const int C = 1e9;

int n, k, d, arr[MAXN];
int prv[MAXN];
int weed[4 * MAXN], nut[4 * MAXN];
map<int, int>	mp;
pair<int, int>	f[MAXN], g[MAXN];

void plant(int v, int b, int e){
	weed[v] = INF;
	if (e - b == 1)	return;

	int mid = b+e>>1;
	plant(v<<1, b, mid);
	plant(v<<1^1, mid, e);
}

void absorb(int v){
	if (!nut[v])	return;
	nut[v<<1] += nut[v];
	nut[v<<1^1] += nut[v];
	weed[v<<1] += nut[v];
	weed[v<<1^1] += nut[v];
	nut[v] = 0;
}

void modify(int v, int b, int e, int pos, int val){
	if (e - b == 1){
		weed[v] = val;
		return;
	}

	int mid = b+e>>1;
	absorb(v);
	if (pos < mid)
		modify(v<<1, b, mid, pos, val);
	else
		modify(v<<1^1, mid, e, pos, val);
	weed[v] = min(weed[v<<1], weed[v<<1^1]);
}

void water(int v, int b, int e, int l, int r, int val){
	if (l <= b && e <= r){
		weed[v] += val;
		nut[v] += val;
		return;
	}
	if (r <= b || e <= l)	return;

	int mid = b+e>>1;
	absorb(v);
	water(v<<1, b, mid, l, r, val);
	water(v<<1^1, mid, e, l, r, val);
	weed[v] = min(weed[v<<1], weed[v<<1^1]);
}

int smoke(int v, int b, int e){
	if (e - b == 1)
		return b;

	int mid = b+e>>1;
	absorb(v);
	if (weed[v<<1] <= k)
		return smoke(v<<1, b, mid);
	return smoke(v<<1^1, mid, e);
}

int main(){
	scanf("%d %d %d", &n, &k, &d);
	for (int i = 0; i < n; i++)	scanf("%d", &arr[i]), arr[i] += INF;

	if (!d){
		int l = 0, r = 0;
		int tl = 0, tr = 0;
		for (int i = 0; i < n; i++){
			if (i && arr[i] ^ arr[i - 1])	tl = tr = i;

			tr++;
			if (r - l < tr - tl)
				l = tl, r = tr;
		}
		printf("%d %d\n", l + 1, r);
	}

	else{
		for (int i = 0; i < n; i++){
			if (mp.count(arr[i]))
				prv[i] = mp[arr[i]] + 1;
			else
				prv[i] = 0;

			mp[arr[i]] = i;
		}
		mp.clear();

		int l = 0, r = 0;
		int tl = 0, hmin = 0, tmin = 0, hmax = 0, tmax = 0;
		plant(1, 0, n);
		for (int i = 0; i < n; i++){
			if (tl < prv[i]){
				for (; tl < prv[i]; tl++)
					modify(1, 0, n, tl, INF);

				while (hmin < tmin && f[hmin].S <= tl)	hmin++;
				while (hmax < tmax && g[hmax].S <= tl)	hmax++;
			}

			if (i && arr[i - 1] % d ^ arr[i] % d){
				water(1, 0, n, tl, i, INF);
				tl = i, hmin = tmin, hmax = tmax;
			}

			//Next Chapter->
			int v = arr[i]/d;
			while (hmin < tmin && f[tmin - 1].F > v)
				tmin--, water(1, 0, n, hmin==tmin?tl:f[tmin-1].S, f[tmin].S, f[tmin].F - v);
			while (hmax < tmax && g[tmax - 1].F < v)
				tmax--, water(1, 0, n, hmax==tmax?tl:g[tmax-1].S, g[tmax].S, v - g[tmax].F);

			f[tmin++] = {v, i + 1};
			g[tmax++] = {v, i + 1};

			modify(1, 0, n, i, 1);
			water(1, 0, n, tl, i + 1, -1);
			int x = smoke(1, 0, n);
			if (i + 1 - x > r - l)
				l = x, r = i + 1;
		}
		printf("%d %d\n", l + 1, r);
	}
	return 0;
}


#include<cstdio>
#include<algorithm>
#include<map>
#include<utility>

using namespace std;

typedef long long ll;

#define F first
#define S second

const ll MAXN = 2e5 + 10;
const ll INF = 1e8;
const ll C = 1e9;

ll n, k, d, arr[MAXN];
ll prv[MAXN];
ll weed[4 * MAXN], nut[4 * MAXN];
map<ll, ll>	mp;
pair<ll, ll>	f[MAXN], g[MAXN];

void plant(ll v, ll b, ll e){
	weed[v] = INF;
	if (e - b == 1)	return;

	ll mid = b+e>>1;
	plant(v<<1, b, mid);
	plant(v<<1^1, mid, e);
}

void absorb(ll v){
	if (!nut[v])	return;
	nut[v<<1] += nut[v];
	nut[v<<1^1] += nut[v];
	weed[v<<1] += nut[v];
	weed[v<<1^1] += nut[v];
	nut[v] = 0;
}

void modify(ll v, ll b, ll e, ll pos, ll val){
	if (e - b == 1){
		weed[v] = val;
		return;
	}

	ll mid = b+e>>1;
	absorb(v);
	if (pos < mid)
		modify(v<<1, b, mid, pos, val);
	else
		modify(v<<1^1, mid, e, pos, val);
	weed[v] = min(weed[v<<1], weed[v<<1^1]);
}

void water(ll v, ll b, ll e, ll l, ll r, ll val){
	if (l <= b && e <= r){
		weed[v] += val;
		nut[v] += val;
		return;
	}
	if (r <= b || e <= l)	return;

	ll mid = b+e>>1;
	absorb(v);
	water(v<<1, b, mid, l, r, val);
	water(v<<1^1, mid, e, l, r, val);
	weed[v] = min(weed[v<<1], weed[v<<1^1]);
}

ll smoke(ll v, ll b, ll e){
	if (e - b == 1)
		return b;

	ll mid = b+e>>1;
	absorb(v);
	if (weed[v<<1] <= k)
		return smoke(v<<1, b, mid);
	return smoke(v<<1^1, mid, e);
}

int main(){
	scanf("%I64d %I64d %I64d", &n, &k, &d);
	for (ll i = 0; i < n; i++)	scanf("%I64d", &arr[i]), arr[i] += C;

	if (!d){
		ll l = 0, r = 0;
		ll tl = 0, tr = 0;
		for (ll i = 0; i < n; i++){
			if (i && arr[i] ^ arr[i - 1])	tl = tr = i;

			tr++;
			if (r - l < tr - tl)
				l = tl, r = tr;
		}
		printf("%I64d %I64d\n", l + 1, r);
	}

	else{
		for (ll i = 0; i < n; i++){
			if (mp.count(arr[i]))
				prv[i] = mp[arr[i]] + 1;
			else
				prv[i] = 0;

			mp[arr[i]] = i;
		}
		mp.clear();

		ll l = 0, r = 0;
		ll tl = 0, hmin = 0, tmin = 0, hmax = 0, tmax = 0;
		plant(1, 0, n);
		for (ll i = 0; i < n; i++){
			if (tl < prv[i]){
				for (; tl < prv[i]; tl++)
					modify(1, 0, n, tl, INF);

				while (hmin < tmin && f[hmin].S <= tl)	hmin++;
				while (hmax < tmax && g[hmax].S <= tl)	hmax++;
			}

			if (i && arr[i - 1] % d ^ arr[i] % d){
				water(1, 0, n, tl, i, INF);
				tl = i, hmin = tmin, hmax = tmax;
			}

			//Next Chapter->
			ll v = arr[i]/d;
			while (hmin < tmin && f[tmin - 1].F > v)
				tmin--, water(1, 0, n, hmin==tmin?tl:f[tmin-1].S, f[tmin].S, f[tmin].F - v);
			while (hmax < tmax && g[tmax - 1].F < v)
				tmax--, water(1, 0, n, hmax==tmax?tl:g[tmax-1].S, g[tmax].S, v - g[tmax].F);

			f[tmin++] = {v, i + 1};
			g[tmax++] = {v, i + 1};

			modify(1, 0, n, i, 1);
			water(1, 0, n, tl, i + 1, -1);
			ll x = smoke(1, 0, n);
			if (i + 1 - x > r - l)
				l = x, r = i + 1;
		}
		printf("%I64d %I64d\n", l + 1, r);
	}
	return 0;
}


#include<cstdio>
#include<algorithm>
#include<map>
#include<utility>

using namespace std;

typedef long long ll;

#define F first
#define S second

const ll MAXN = 2e5 + 10;
const ll INF = 1e8;
const ll C = 1e9;

ll n, k, d, arr[MAXN];
ll prv[MAXN];
ll weed[4 * MAXN], nut[4 * MAXN];
map<ll, ll>	mp;
pair<ll, ll>	f[MAXN], g[MAXN];

void plant(ll v, ll b, ll e){
	weed[v] = INF;
	if (e - b == 1)	return;

	ll mid = b+e>>1;
	plant(v<<1, b, mid);
	plant(v<<1^1, mid, e);
}

void absorb(ll v){
	if (!nut[v])	return;
	nut[v<<1] += nut[v];
	nut[v<<1^1] += nut[v];
	weed[v<<1] += nut[v];
	weed[v<<1^1] += nut[v];
	nut[v] = 0;
}

void modify(ll v, ll b, ll e, ll pos, ll val){
	if (e - b == 1){
		weed[v] = val;
		return;
	}

	ll mid = b+e>>1;
	absorb(v);
	if (pos < mid)
		modify(v<<1, b, mid, pos, val);
	else
		modify(v<<1^1, mid, e, pos, val);
	weed[v] = min(weed[v<<1], weed[v<<1^1]);
}

void water(ll v, ll b, ll e, ll l, ll r, ll val){
	if (l <= b && e <= r){
		weed[v] += val;
		nut[v] += val;
		return;
	}
	if (r <= b || e <= l)	return;

	ll mid = b+e>>1;
	absorb(v);
	water(v<<1, b, mid, l, r, val);
	water(v<<1^1, mid, e, l, r, val);
	weed[v] = min(weed[v<<1], weed[v<<1^1]);
}

ll smoke(ll v, ll b, ll e){
	if (e - b == 1)
		return b;

	ll mid = b+e>>1;
	absorb(v);
	if (weed[v<<1] <= k)
		return smoke(v<<1, b, mid);
	return smoke(v<<1^1, mid, e);
}

int main(){
	scanf("%I64d %I64d %I64d", &n, &k, &d);
	for (ll i = 0; i < n; i++)	scanf("%I64d", &arr[i]), arr[i] += INF;

	if (!d){
		ll l = 0, r = 0;
		ll tl = 0, tr = 0;
		for (ll i = 0; i < n; i++){
			if (i && arr[i] ^ arr[i - 1])	tl = tr = i;

			tr++;
			if (r - l < tr - tl)
				l = tl, r = tr;
		}
		printf("%I64d %I64d\n", l + 1, r);
	}

	else{
		for (ll i = 0; i < n; i++){
			if (mp.count(arr[i]))
				prv[i] = mp[arr[i]] + 1;
			else
				prv[i] = 0;

			mp[arr[i]] = i;
		}
		mp.clear();

		ll l = 0, r = 0;
		ll tl = 0, hmin = 0, tmin = 0, hmax = 0, tmax = 0;
		plant(1, 0, n);
		for (ll i = 0; i < n; i++){
			if (tl < prv[i]){
				for (; tl < prv[i]; tl++)
					modify(1, 0, n, tl, INF);

				while (hmin < tmin && f[hmin].S <= tl)	hmin++;
				while (hmax < tmax && g[hmax].S <= tl)	hmax++;
			}

			if (i && arr[i - 1] % d ^ arr[i] % d){
				water(1, 0, n, tl, i, INF);
				tl = i, hmin = tmin, hmax = tmax;
			}

			//Next Chapter->
			ll v = arr[i]/d;
			while (hmin < tmin && f[tmin - 1].F > v)
				tmin--, water(1, 0, n, hmin==tmin?tl:f[tmin-1].S, f[tmin].S, f[tmin].F - v);
			while (hmax < tmax && g[tmax - 1].F < v)
				tmax--, water(1, 0, n, hmax==tmax?tl:g[tmax-1].S, g[tmax].S, v - g[tmax].F);

			f[tmin++] = {v, i + 1};
			g[tmax++] = {v, i + 1};

			modify(1, 0, n, i, 1);
			water(1, 0, n, tl, i + 1, -1);
			ll x = smoke(1, 0, n);
			if (i + 1 - x > r - l)
				l = x, r = i + 1;
		}
		printf("%I64d %I64d\n", l + 1, r);
	}
	return 0;
}


#include<cstdio>
#include<algorithm>
#include<map>
#include<utility>

using namespace std;

#define F first
#define S second

const int MAXN = 2e5 + 10;
const int INF = 1e8;

int n, k, d, arr[MAXN];
int prv[MAXN];
int weed[4 * MAXN], nut[4 * MAXN];
map<int, int>	mp;
pair<int, int>	f[MAXN], g[MAXN];

void plant(int v, int b, int e){
	weed[v] = INF;
	if (e - b == 1)	return;

	int mid = b+e>>1;
	plant(v<<1, b, mid);
	plant(v<<1^1, mid, e);
}

void absorb(int v){
	if (!nut[v])	return;
	nut[v<<1] += nut[v];
	nut[v<<1^1] += nut[v];
	weed[v<<1] += nut[v];
	weed[v<<1^1] += nut[v];
	nut[v] = 0;
}

void modify(int v, int b, int e, int pos, int val){
	if (e - b == 1){
		weed[v] = val;
		return;
	}

	int mid = b+e>>1;
	absorb(v);
	if (pos < mid)
		modify(v<<1, b, mid, pos, val);
	else
		modify(v<<1^1, mid, e, pos, val);
	weed[v] = min(weed[v<<1], weed[v<<1^1]);
}

void water(int v, int b, int e, int l, int r, int val){
	if (l <= b && e <= r){
		weed[v] += val;
		nut[v] += val;
		return;
	}
	if (r <= b || e <= l)	return;

	int mid = b+e>>1;
	absorb(v);
	water(v<<1, b, mid, l, r, val);
	water(v<<1^1, mid, e, l, r, val);
	weed[v] = min(weed[v<<1], weed[v<<1^1]);
}

int smoke(int v, int b, int e){
	if (e - b == 1)
		return b;

	int mid = b+e>>1;
	if (weed[v<<1] <= k)
		return smoke(v<<1, b, mid);
	return smoke(v<<1^1, mid, e);
}

int main(){
	scanf("%d %d %d", &n, &k, &d);
	for (int i = 0; i < n; i++)	scanf("%d", &arr[i]);

	if (!d){
		int l = 0, r = 0;
		int tl = 0, tr = 0;
		for (int i = 0; i < n; i++){
			if (i && arr[i] ^ arr[i - 1])	tl = tr = i;

			tr++;
			if (r - l < tr - tl)
				l = tl, r = tr;
		}
		printf("%d %d\n", l + 1, r);
	}

	else{
		for (int i = 0; i < n; i++){
			if (mp.count(arr[i]))
				prv[i] = mp[arr[i]] + 1;
			else
				prv[i] = 0;

			mp[arr[i]] = i;
		}
		mp.clear();

		int l = 0, r = 0;
		int tl = 0, hmin = 0, tmin = 0, hmax = 0, tmax = 0;
		plant(1, 0, n);
		for (int i = 0; i < n; i++){
			if (tl < prv[i]){
				for (; tl < prv[i]; tl++)
					modify(1, 0, n, tl, INF);

				while (hmin < tmin && f[hmin].S <= tl)	hmin++;
				while (hmax < tmax && g[hmax].S <= tl)	hmax++;
			}

			if (i && arr[i - 1] % d ^ arr[i] % d){
				water(1, 0, n, tl, i, INF);
				tl = i, hmin = tmin, hmax = tmax;
			}

			//Next Chapter->
			int v = arr[i]/d;
			while (hmin < tmin && f[tmin - 1].F > v)
				tmin--, water(1, 0, n, hmin==tmin?tl:f[tmin-1].S, f[tmin].S, f[tmin].F - v);
			while (hmax < tmax && g[tmax - 1].F < v)
				tmax--, water(1, 0, n, hmax==tmax?tl:g[tmax-1].S, g[tmax].S, v - g[tmax].F);

			f[tmin++] = {v, i + 1};
			g[tmax++] = {v, i + 1};

			modify(1, 0, n, i, 1);
			water(1, 0, n, tl, i + 1, -1);
			int x = smoke(1, 0, n);
			if (i + 1 - x > r - l)
				l = x, r = i + 1;
		}
		printf("%d %d\n", l + 1, r);
	}
	return 0;
}


// Version.20.39.55.05.26.20.
#include <bits/stdc++.h>
#define N 200200
#define ls (pos << 1)
#define rs (pos << 1 | 1)
using namespace std;
typedef long long ll;
const ll INF = 1e14;

int ansl = 1, ansr = 1;
ll mi[N << 2], tg[N << 2];

void build(int l, int r, int pos) {
    tg[pos] = 0;
    if (l == r) return mi[pos] = l, void();
    int mid = (l + r) >> 1;
    build(l, mid, ls), build(mid + 1, r, rs);
    mi[pos] = min(mi[ls], mi[rs]);
}

void add(int pos, int w) {
    mi[pos] += w, tg[pos] += w;
}

void pushdown(int pos) {
    if (tg[pos]) {
        add(ls, tg[pos]);
        add(rs, tg[pos]);
        tg[pos] = 0;
    }
}

void modify(int L, int R, ll w, int l, int r, int pos) {
    if (L <= l && r <= R) return add(pos, w);
    int mid = (l + r) >> 1;
    pushdown(pos);
    if (L <= mid) modify(L, R, w, l, mid, ls);
    if (mid < R) modify(L, R, w, mid + 1, r, rs);
    mi[pos] = min(mi[ls], mi[rs]);
}

int query(int w, int l, int r, int pos) {
    if (l == r) return mi[pos] <= w ? l : -1;
    pushdown(pos);
    int mid = (l + r) >> 1;
    return mi[ls] <= w
        ? query(w, l, mid, ls)
        : query(w, mid + 1, r, rs);
}

void chk(int l, int r) {
    if (r - l > ansr - ansl || (r - l == ansr - ansl && l < ansl))
        ansl = l, ansr = r;
}

ll qmin(int x, int l, int r, int pos) {
    if (l == r) return mi[pos];
    int mid = (l + r) >> 1;
    return x <= mid ? qmin(x, l, mid, ls) : qmin(x, mid + 1, r, rs);
}

int smi[N], tmi, smx[N], tmx;
map<int, int> las;

void work(int *a, int n, int m, int dlt) {
    build(1, n, 1);
    tmi = tmx = 0, las.clear();
    int lasi = 1;
    for (int i = 1; i <= n; ++i) {
        while (tmi && a[smi[tmi]] > a[i])
            modify(smi[tmi - 1] + 1, smi[tmi], a[smi[tmi]], 1, n, 1), tmi--;
        modify(smi[tmi] + 1, i, -a[i], 1, n, 1), smi[++tmi] = i;
        while (tmx && a[smx[tmx]] < a[i])
            modify(smx[tmx - 1] + 1, smx[tmx], -a[smx[tmx]], 1, n, 1), tmx--;
        modify(smx[tmx] + 1, i, a[i], 1, n, 1), smx[++tmx] = i;
        if (int tmp = las[a[i]])
            if (lasi <= tmp) modify(lasi, tmp, INF, 1, n, 1), lasi = tmp;
        las[a[i]] = i;
        int l = query(m + i, 1, n, 1);
        // cout << qmin(l, 1, n, 1) << endl;
        assert(l);
        if (l > 0 && l <= i) chk(l + dlt, i + dlt);
    }
}

int main() {
#ifdef isLOCAL
    freopen(".in", "r", stdin);
    freopen(".out", "w", stdout);
#endif

    static int n, m, d, a[N];
    cin >> n >> m >> d;
    for (int i = 1; i <= n; ++i)
        scanf("%d", a + i);

    if (!d) {
        for (int l = 1, r; l <= n; l = r + 1) {
            for (r = l; r < n && a[r + 1] == a[l]; ++r);
            chk(l, r);
        }
        cout << ansl << " " << ansr << endl;
        return 0;
    }

    for (int l = 1, r; l <= n; l = r + 1) {
        for (r = l; r < n && (a[r + 1] % d + d) % d == (a[l] % d + d) % d; ++r);
        for (int i = l; i <= r; ++i)
            a[i] = (a[i] + INF) / d;
        work(a + l - 1, r - l + 1, m, l - 1);
    }

    cout << ansl << ' ' << ansr << endl;

    return 0;
}


#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<string>
#include<iostream>
#include<queue>
#include<iomanip>
#include<algorithm>
#include<map>
using namespace std;
const int N=200010;
const long long INF=0x3F3F3F3F3F3F3F3Fll;

inline void read(int &x)
{
	x=0;
	int f=1;
	char ch=getchar();
	while((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
	if(ch=='-') f=-1,ch=getchar();
	while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
	x=x*f;
}

struct node
{
	long long mi,ma,tagmi,tagma,val;
};
map<int,int> mp;
int n,k,d,a[N],b[N],num,head,tail,top1,stk1[N],top2,stk2[N],ans,ansl,ansr;
struct segmenttree
{
	node tr[N<<2];
	void pushup(int x)
    {
		tr[x].mi=min(tr[x<<1].mi,tr[x<<1|1].mi);
		tr[x].ma=max(tr[x<<1].ma,tr[x<<1|1].ma);
		tr[x].val=min(tr[x<<1].val,tr[x<<1|1].val);
    }
	void pushdown(int x)
    {
        tr[x<<1].mi+=tr[x].tagmi;tr[x<<1].tagmi+=tr[x].tagmi;tr[x<<1].val-=tr[x].tagmi;
        tr[x<<1].ma+=tr[x].tagma;tr[x<<1].tagma+=tr[x].tagma;tr[x<<1].val+=tr[x].tagma;
        tr[x<<1|1].mi+=tr[x].tagmi;tr[x<<1|1].tagmi+=tr[x].tagmi;tr[x<<1|1].val-=tr[x].tagmi;
        tr[x<<1|1].ma+=tr[x].tagma;tr[x<<1|1].tagma+=tr[x].tagma;tr[x<<1|1].val+=tr[x].tagma;
        tr[x].tagmi=tr[x].tagma=0;
    }
	void build(int x=1,int l=1,int r=n)
	{
		if(l==r)
		{
			tr[x].mi=tr[x].ma=a[l];
			tr[x].val=l;
			return;
		}
		int mid=l+r>>1;
		build(x<<1,l,mid);build(x<<1|1,mid+1,r);
		pushup(x);
	}
	void delet(int p,int x=1,int l=1,int r=n)
	{
		if(l==r)
		{
			tr[x].val=INF;
			return;
		}
		pushdown(x);
		int mid=l+r>>1;
		if(p<=mid) delet(p,x<<1,l,mid);
		else delet(p,x<<1|1,mid+1,r);
		pushup(x);
	}
	void updatemin(int ll,int rr,int v,int x=1,int l=1,int r=n)
	{
		if(ll<=l&&r<=rr)
		{
			tr[x].mi+=v;tr[x].val-=v;tr[x].tagmi+=v;
			return;
		}
		pushdown(x);
		int mid=l+r>>1;
		if(ll<=mid) updatemin(ll,rr,v,x<<1,l,mid);
		if(rr>mid) updatemin(ll,rr,v,x<<1|1,mid+1,r);
		pushup(x);
	}
	void updatemax(int ll,int rr,int v,int x=1,int l=1,int r=n)
	{
		if(ll<=l&&r<=rr)
		{
			tr[x].ma+=v;tr[x].val+=v;tr[x].tagma+=v;
			return;
		}
		pushdown(x);
		int mid=l+r>>1;
		if(ll<=mid) updatemax(ll,rr,v,x<<1,l,mid);
		if(rr>mid) updatemax(ll,rr,v,x<<1|1,mid+1,r);
		pushup(x);
	}
	long long quer(int num,int x=1,int l=1,int r=n)
	{
		if(l==r) return l;
		pushdown(x);
		int mid=l+r>>1;
		if(tr[x<<1].val<=num) return quer(num,x<<1,l,mid);
		else return quer(num,x<<1|1,mid+1,r);
	}
}T;

int main()
{
	int i,j,op;
	read(n);read(k);read(d);
	op=-2147000000;
	for(i=1;i<=n;i++)
	{
		read(a[i]);
		op=min(op,a[i]);
	}
	for(i=1;i<=n;i++) a[i]-=op;
	if(d==0)
	{
		ans=0;
		i=1;
		while(i<=n)
		{
			j=i;
			while(j<n&&a[j+1]==a[i]) j++;
			if(j-i+1>ans)
			{
				ans=j-i+1;
				ansl=i;ansr=j;
			}
			i=j+1;
		}
		printf("%d %d\n",ansl,ansr);
		return 0;
	}
	i=1;
	while(i<=n)
	{
		j=i;b[i]=i;
		while(j<n&&a[j+1]%d==a[i]%d) j++,b[j]=i;
		i=j+1;
	}
	tail=1;T.build();top1=top2=0;
	for(head=1;head<=n;head++)
	{
		mp[a[head]]++;
		while(mp[a[head]]>1||b[tail]!=b[head])
		{
			T.delet(tail);
			mp[a[tail]]--;tail++;
		}
		while(top1>0&&a[head]<=a[stk1[top1]])
		{
			T.updatemin(stk1[top1-1]+1,stk1[top1],(a[head]-a[stk1[top1]])/d);
			top1--;
		}
		stk1[++top1]=head;
		while(top2>0&&a[head]>=a[stk2[top2]])
		{
			T.updatemax(stk2[top2-1]+1,stk2[top2],(a[head]-a[stk2[top2]])/d);
			top2--;
		}
		stk2[++top2]=head;
		long long l=T.quer(head+k);
        if(l>=tail&&head-l+1>ans)
		{
			ans=head-l+1;ansl=l;ansr=head;
		}
	}
	printf("%d %d\n",ansl,ansr);
	return 0;
}


#include<iostream>
#include<cstdio>
#include<cstring>
#include<map>
using namespace std;
int n,k,d;
int a[200010],pre[200010];//ÉÏÒ»¸öÏàµÈµÄÎ»ÖÃ
map<int,int>vis;
int stackmax[200010],stackmin[200010],topmax=0,topmin=0;
struct node{
	int l;
	int r;
	int minn;
	int add;
}tree[800010];
void build(int now,int l,int r){
	tree[now].l=l;
	tree[now].r=r;
	tree[now].minn=1e9;
	tree[now].add=0;
	if(l==r)return;
	int mid=(l+r)/2;
	build(now*2,l,mid);
	build(now*2+1,mid+1,r);
}
void add(int now,int x,int y,int ad){
	int l=tree[now].l;
	int r=tree[now].r;
	if(l==x&&r==y){
		tree[now].add+=ad;
		tree[now].minn+=ad;
		return;
	}
	int mid=(l+r)/2;
	if(tree[now].add){
		add(now*2,l,mid,tree[now].add);
		add(now*2+1,mid+1,r,tree[now].add);
		tree[now].add=0;
	}
	if(y<=mid){
		add(now*2,x,y,ad);
	}
	else if(x>mid){
		add(now*2+1,x,y,ad);
	}
	else{
		add(now*2,x,mid,ad);
		add(now*2+1,mid+1,y,ad);
	}
	tree[now].minn=min(tree[now*2].minn,tree[now*2+1].minn);
}
int check(int now,int x){
	int l=tree[now].l;
	int r=tree[now].r;
	if(l==r)return l;
	int lson=now*2;
	int rson=now*2+1;
	if(tree[lson].minn<=x)return check(lson,x);
	else return check(rson,x);
}
int main(){
	scanf("%d%d%d",&n,&k,&d);
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]);
	}
	if(d==0){
		cout<<n<<endl;
		int maxn=0,now=0,l=0,r=0;
		for(int i=1;i<=n;i++){
			if(a[i]!=a[i-1])now=i;
			if(i-now+1>maxn){
				maxn=i-now+1;
				l=now;
				r=i;
			}
		}
		printf("%d %d\n",l,r);
		return 0;
	}
	for(int i=1;i<=n;i++){
		pre[i]=vis[a[i]];
		vis[a[i]]=i;
	}
	int pr=1;
	int maxn=0,l=0,r=0;
	build(1,1,n);
	for(int i=1;i<=n;i++){
		while(pr<=pre[i]||a[pr]%d!=a[i]%d){
			add(1,pr,pr,1e9);
			vis[a[pr]]--;
			pr++;
		}
		add(1,i,i,-1e9+i);
		while(topmax>0&&a[stackmax[topmax]]<a[i]){
			add(1,stackmax[topmax-1]+1,stackmax[topmax],a[i]/d-a[stackmax[topmax]]/d);
			topmax--;
		}
		stackmax[++topmax]=i;
		while(topmin>0&&a[stackmin[topmin]]>a[i]){
			add(1,stackmin[topmin-1]+1,stackmin[topmin],a[stackmin[topmin]]/d-a[i]/d);
			topmin--;
		}
		stackmin[++topmin]=i;
		int nowl=check(1,i+k);
		if(i-nowl+1>maxn){
			maxn=i-nowl+1;
			l=nowl;
			r=i;
		}
	}
	printf("%d %d\n",l,r);
	return 0;
}


#include<bits/stdc++.h>
#define INF 0x7fffffff
#define inf 0x3f3f3f3f
#define love const
#define I inline
#define mid (l+r)/2
#define lc (now<<1)
#define rc (now<<1|1)
#define R register
#define lson lc,l,mid
#define int long long
#define rson rc,mid+1,r
#define rep(i,a,b)for(R int i=a;i<=b;i++)
#define per(i,a,b)for(R int i=a;i>=b;i--)
#define pii pair<int ,int >
#define re register
#define love const
#define debug cout<<"%"<<endl;
using namespace std;
namespace IO{
    const int IOsize=1<<21;
    I void read(){};I void Write(){};
    char buf[IOsize],*pa=buf,*pb=buf;
    char buffer[IOsize];int p1=-1;const int p2=(IOsize)-1;
    I char gc(){return pa==pb&&(pb=(pa=buf)+fread(buf,1,IOsize,stdin),pa==pb)?EOF:*pa++;}
    I void gchar(char s){s=gc();for(;!isalpha(s);s=gc());}
    template<typename T,typename... T2>I void read(T &x,T2 &... oth){
        x=0;R short y=0;R char ch=gc();
        for(;!isdigit(ch);ch=gc())y=ch=='-';
        for(;isdigit(ch);ch=gc())x=x*10+(ch^48);
        (y)&&(x=-x);read(oth...);return;}
    I void flush(){fwrite(buffer,1,p1+1,stdout);p1=-1;return;}
    I void pc(int ch){if(p1==p2)flush();buffer[++p1]=ch;return;}
    template<class T>I void write(T x){
        static char buf[20];static short len =-1;
        if(x>=0){do buf[++len]=(x%10)^48,x/=10;while(x);}
        else{pc     ('-');do buf[++len]=(-(x%10))^48,x/=10;while(x);}
        while(len>=0)pc(buf[len--]);return;}
    template<typename T,typename...T2>I void Write(T x,T2... oth){write(x),pc('\n'),Write(oth...);return;}
   }

using namespace IO;
love int N =5e5+50;
int n,m,ans,k,d,pos,vis[N],len1,len2,s[N],g[N],a[N],ans_l,ans_r,b[N];
map<int,int>cnt;
struct  Segment_Tree
{
    struct node{int v,tag;}tr[N<<1];
    I void pushup(int now){tr[now].v=min(tr[lc].v,tr[rc].v);}
  //  I void pushdown(int now, int l,int r);

    I void build(int now ,int l,int r){
        tr[now].v=0;tr[now].tag=0;
        if(l==r)return;
        build(lson);build(rson);
    }
    I void modify(int now ,int l,int r,int lx,int rx,int w){
        if(lx<=l && r<=rx){tr[now].v+=w;tr[now].tag+=w;return;}
        pushdown(now,l,r);
        if(lx<=mid)modify(lson,lx,rx,w);
        if(mid<rx)modify(rson,lx,rx,w);
        pushup(now);
    }
    I void pushdown(int now,int l,int r){
        if(!tr[now].tag)return;
        modify(lson,l,r,tr[now].tag);modify(rson,l,r,tr[now].tag);
        tr[now].tag=0;
    }
    I int find(int now ,int l,int r,int p){
        if(l==r){return tr[now].v<=k?l:-1;}
        pushdown(now,l,r);
        if(tr[lc].v<=k)return find(lson,p);
        if(mid<p)return find(rson,p);
        return -1;
    }
}seg;
I void solve(){
    int len = 1, now = -1, x = 0, pos = 0, L = 1, Ri = 1;
        for(int i = 1; i <= n; i++) {
             x=a[i];
            if(x != now) {
                if(len < i - pos)
                    len = i - pos, L = pos, Ri = i - 1;
                now = x, pos = i;
            }
        } if(len < n - pos + 1) L = pos, Ri = n;
        cout<<L<<" "<<Ri<<endl;
        return ;
}
I void work(int l,int r){
    seg.build(1,1,n);cnt.clear();m=0;len1=0;len2=0;int pos=0;
    rep(i,l,r)b[i-l+1]=a[i]/d;
    m=r-l+1;
    rep(i,1,m){
        int x=b[i];
        if(cnt.count(x)){
            seg.modify(1,1,n,pos+1,cnt[x],INF);
            pos=cnt[x];
        }
        seg.modify(1, 1, n, 1, n, -1);
        seg.modify(1, 1, n, i, i, i);
        cnt[x]=i;
        // s equal to max ,g equal to min
        while(len1>=1 && s[len1]<x){
            int pre = s[len1-1];
            seg.modify(1,1,n,pre+1,s[len1],-b[s[len1]]);
            len1--;
        }
        seg.modify(1,1,n,s[len1]+1,i,b[i]);
        s[++len1]=i;
        while(len2>=1 && g[len2]>x){
            int pre =g[len2-1];
            seg.modify(1,1,n,pre+1,g[len2],b[g[len2]]);
            len2--;
        }
        seg.modify(1,1,n,g[len2]+1,i,-b[i]);
        g[++len2]=i;int now =seg.find(1,1,n,i) ;
        if( now !=-1 &&  i-now+1>ans)ans=i-now+1,ans_l=now+l-1,ans_r=i+l-1;
    }
}
signed main(){
    read(n,k,d);int minn=INF;
    rep(i,1,n)read(a[i]),minn=min(minn,a[i]);
    if(!d){
        solve();
        return 0;
    }
    rep(i,1,n)a[i]-=minn-1;
    int now =a[1]%d;int pos=1;
    rep(i,2,n+1)
        if(now != a[i]%d || i==n+1)
            work(pos,i-1),pos=i,now=a[pos]%d;
    cout<<ans_l<<" "<<ans_r<<endl;
    return 0;
}


#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#define fi first
#define se second
#define rg register
#define fo(i,a,b) for(rg int i=a;i<=b;i++)
#define fd(i,a,b) for(rg int i=a;i>=b;i--)
using namespace std;
typedef pair<int,int> PP;
typedef long long ll;

struct tree
{
	int a,x,add,min;
	int c[2] , fa;
};
const int maxlong = int(1e9)+5;
const int N = int(2e5)+5;
int n , K , D;
ll KD;
int a[N] , dr[N] , tp[N] , r[N];
PP ma[N] , mi[N];
int t1 , t2 , root;
map<int,int> t;
tree tr[N];
inline void Init()
{
	scanf("%d%d%d",&n,&K,&D);
	KD = ll(K)*D;
	fo(i,2,n+1) scanf("%d",&a[i]);
}
inline void chan(int x,int v){tr[x].min += v;tr[x].a += v; tr[x].add += v;}
inline void up(int x)
{
	tr[x].x = x; tr[x].min = tr[x].a;
	int l = tr[x].c[0] , r = tr[x].c[1];
	if (l && tr[x].min > tr[l].min - ll(tr[l].x-tr[x].x)*D) tr[x].x = tr[l].x , tr[x].min = tr[l].min;
	if (r && tr[x].min > tr[r].min - ll(tr[r].x-tr[x].x)*D) tr[x].x = tr[r].x , tr[x].min = tr[r].min;
}
inline void down(int x)
{
	int l = tr[x].c[0] , r = tr[x].c[1];
	if (l) chan(l , tr[x].add);
	if (r) chan(r , tr[x].add);
	tr[x].add = 0;
}
inline void turn(int x,int t)
{
	int y = tr[x].c[t] , z = tr[y].c[!t] , fa = tr[x].fa;
	if (fa)
	if (tr[fa].c[0] == x) tr[fa].c[0]=y;else tr[fa].c[1]=y;
	tr[x].c[t] = z; tr[y].c[!t]=x;
	tr[x].fa = y; tr[y].fa = fa;
	if (z) tr[z].fa = x;
	up(x); up(y);
}

inline void uproot(int x,int mb)
{
	int y = x , cnt(0);
	while (y != mb) tp[++cnt]=y , y=tr[y].fa;
	fd(i,cnt,1) down(tp[i]);
	fo(i,2,cnt) dr[i] = (tr[tp[i]].c[1] == tp[i-1]);
	for(int i=2;i<=cnt;i+=2)
	if (i == cnt) turn(tp[i],dr[i]);else
	if (dr[i] == dr[i+1]) turn(tp[i+1],dr[i+1]) , turn(tp[i],dr[i]);else
	turn(tp[i],dr[i]) , turn(tp[i+1],dr[i+1]);
	if (!mb) root = x;
}
inline void change(int l,int r,int v)
{
	uproot(r+1 , 0);
	uproot(l-1 , root);
	chan(tr[tr[root].c[0]].c[1] , v);
	up(tr[root].c[0]); up(root);
}
inline int find(int l,int r)
{
	uproot(r+1 , 0);
	uproot(l-1 , root);
	int x = tr[tr[root].c[0]].c[1];
	while (1)
	{
		down(x);
		int lx = tr[tr[x].c[1]].x;
		if (tr[x].c[1] && tr[tr[x].c[1]].min - ll(lx-l)*D <= KD) x = tr[x].c[1];else
		if (tr[x].a - ll(x-l)*D <= KD) return x;else x = tr[x].c[0];
	}
	return x;
}
inline int make(int l,int r)
{
	if (l > r) return 0;
	if (l == r) return l;
	int mid = (l+r)>>1;
	tr[mid].c[0] = make(l,mid-1);
	if (tr[mid].c[0]) tr[tr[mid].c[0]].fa = mid;
	tr[mid].c[1] = make(mid+1,r);
	if (tr[mid].c[1]) tr[tr[mid].c[1]].fa = mid;
	return mid;
}
inline void Work()
{
	if (!D)
    {
        int ansl = n+2 , ansr = n+1;
        fo(i,1,n)
        {
            if (r[i-1] >= i) continue;
            r[i] = i;
            while (r[i] < n && a[i] == a[r[i]+1]) r[i]++;
            if (r[i] - i > ansr - ansl) ansl = i , ansr = r[i];
        }
        printf("%d %d\n",ansl-1,ansr-1);
        return;
    }
	fo(i,2,n+1)
    {
        if (r[i-1] < i) t[a[i]]++ , r[i] = i;else r[i] = r[i-1];
        while (r[i] < n+1 && (a[r[i]+1]%D+D)%D == (a[i]%D+D)%D && t[a[r[i]+1]] == 0)
        r[i]++ , t[a[r[i]]]++;
        t[a[i]]--;
    }

	root = make(1,n+2);
	fo(i,1,n+2) tr[i].a = tr[i].min = maxlong;
	ma[0] = PP(n+2 , maxlong); mi[0] = PP(n+2 , -maxlong);
	t1 = t2 = 0;
	int last , ansr = n+2 , ansl = n+2 , nr;
	fd(i,n+1,2)
	{
		tr[i].a = tr[i].min = 0;
		tr[i].x = i;
		last = i+1;
		while (a[i] > ma[t1].se && t1)
		change(last,ma[t1-1].fi-1,a[i]-ma[t1].se) , t1-- , last = ma[t1].fi;
		ma[++t1] = PP(i , a[i]);
		last = i+1;
		while (a[i] < mi[t2].se && t2)
		change(last,mi[t2-1].fi-1,mi[t2].se-a[i]) , t2-- , last = mi[t2].fi;
		mi[++t2] = PP(i , a[i]);
		nr = find(i , r[i]);
		if (nr - i >= ansr - ansl) ansl = i , ansr = nr;
	}
	printf("%d %d\n",ansl-1,ansr-1);
}

int main()
{
	Init();
	Work();
	return 0;
}


#include<bits/stdc++.h>
#define INF 0x7fffffff
#define inf 0x3f3f3f3f
#define love const
#define I inline
#define mid (l+r)/2
#define lc (now<<1)
#define rc (now<<1|1)
#define R register
#define lson lc,l,mid
#define int long long
#define rson rc,mid+1,r
#define rep(i,a,b)for(R int i=a;i<=b;i++)
#define per(i,a,b)for(R int i=a;i>=b;i--)
#define pii pair<int ,int >
#define re register
#define love const
#define debug cout<<"%"<<endl;
using namespace std;
namespace IO{
    const int IOsize=1<<21;
    I void read(){};I void Write(){};
    char buf[IOsize],*pa=buf,*pb=buf;
    char buffer[IOsize];int p1=-1;const int p2=(IOsize)-1;
    I char gc(){return pa==pb&&(pb=(pa=buf)+fread(buf,1,IOsize,stdin),pa==pb)?EOF:*pa++;}
    I void gchar(char s){s=gc();for(;!isalpha(s);s=gc());}
    template<typename T,typename... T2>I void read(T &x,T2 &... oth){
        x=0;R short y=0;R char ch=gc();
        for(;!isdigit(ch);ch=gc())y=ch=='-';
        for(;isdigit(ch);ch=gc())x=x*10+(ch^48);
        (y)&&(x=-x);read(oth...);return;}
    I void flush(){fwrite(buffer,1,p1+1,stdout);p1=-1;return;}
    I void pc(int ch){if(p1==p2)flush();buffer[++p1]=ch;return;}
    template<class T>I void write(T x){
        static char buf[20];static short len =-1;
        if(x>=0){do buf[++len]=(x%10)^48,x/=10;while(x);}
        else{pc     ('-');do buf[++len]=(-(x%10))^48,x/=10;while(x);}
        while(len>=0)pc(buf[len--]);return;}
    template<typename T,typename...T2>I void Write(T x,T2... oth){write(x),pc('\n'),Write(oth...);return;}
   }

using namespace IO;
love int N =5e5+50;
int n,m,ans,k,d,pos,vis[N],len1,len2,s[N],g[N],a[N],ans_l,ans_r,b[N];
map<int,int>cnt;
struct  Segment_Tree
{
    struct node{int v,tag;}tr[N<<1];
    I void pushup(int now){tr[now].v=min(tr[lc].v,tr[rc].v);}
  //  I void pushdown(int now, int l,int r);

    I void build(int now ,int l,int r){
        tr[now].v=0;tr[now].tag=0;
        if(l==r)return;
        build(lson);build(rson);
    }
    I void modify(int now ,int l,int r,int lx,int rx,int w){
        if(lx<=l && r<=rx){tr[now].v+=w;tr[now].tag+=w;return;}
        pushdown(now,l,r);
        if(lx<=mid)modify(lson,lx,rx,w);
        if(mid<rx)modify(rson,lx,rx,w);
        pushup(now);
    }
    I void pushdown(int now,int l,int r){
        if(!tr[now].tag)return;
        modify(lson,l,r,tr[now].tag);modify(rson,l,r,tr[now].tag);
        tr[now].tag=0;
    }
    I int find(int now ,int l,int r,int p){
        if(l==r){return tr[now].v<=k?l:-1;}
        pushdown(now,l,r);
        if(tr[lc].v<=k)return find(lson,p);
        if(mid<p)return find(rson,p);
        return -1;
    }
}seg;
I void solve(){
    int len = 1, now = -1, x = 0, pos = 0, L = 1, Ri = 1;
        for(int i = 1; i <= n; i++) {
             x=a[i];
            if(x != now) {
                if(len < i - pos)
                    len = i - pos, L = pos, Ri = i - 1;
                now = x, pos = i;
            }
        } if(len < n - pos + 1) L = pos, Ri = n;
        cout<<L<<" "<<Ri<<endl;
        return ;
}
I void work(int l,int r){
    seg.build(1,1,n);cnt.clear();m=0;len1=0;len2=0;int pos=0;
    rep(i,l,r)b[i-l+1]=a[i]/d;
    m=r-l+1;
    rep(i,1,m){
        int x=b[i];
        if(cnt.count(x)){
            seg.modify(1,1,n,pos+1,cnt[x],1000000000);
            pos=cnt[x];
        }
        seg.modify(1, 1, n, 1, n, -1);
        seg.modify(1, 1, n, i, i, i);
        cnt[x]=i;
        // s equal to max ,g equal to min
        while(len1>=2 && s[len1]<x){
            int pre = s[len1-1];
            seg.modify(1,1,n,pre+1,s[len1],-b[s[len1]]);
            len1--;
        }
        seg.modify(1,1,n,s[len1]+1,i,b[i]);
        s[++len1]=i;
        while(len2>=2 && g[len2]>x){
            int pre =g[len2-1];
            seg.modify(1,1,n,pre+1,g[len2],b[g[len2]]);
            len2--;
        }
        seg.modify(1,1,n,g[len2]+1,i,-b[i]);
        g[++len2]=i;int now =seg.find(1,1,n,i) ;
        if( (~now) &&  i-now+1>ans)ans=i-now+1,ans_l=now+l-1,ans_r=i+l-1;
    }
}
signed main(){
    read(n,k,d);int minn=2147483647;
    rep(i,1,n)read(a[i]),minn=min(minn,a[i]);
    if(!d){
        solve();
        return 0;
    }
    rep(i,1,n)a[i]-=minn-1  ;
    int now =a[1]%d;int pos=1;
    rep(i,2,n+1)
        if(now != a[i]%d || i==n+1)
            work(pos,i-1),pos=i,now=a[pos]%d;
    cout<<ans_l<<" "<<ans_r<<endl;
    return 0;
}


// Version.20.39.55.05.26.20.
#include <bits/stdc++.h>
#define N 200200
#define ls (pos << 1)
#define rs (pos << 1 | 1)
using namespace std;
typedef long long ll;
const int INF = 1e9;

int ansl = 1, ansr = 1;
ll mi[N], tg[N];

void build(int l, int r, int pos) {
    tg[pos] = 0;
    if (l == r) return mi[pos] = l, void();
    int mid = (l + r) >> 1;
    build(l, mid, ls), build(mid + 1, r, rs);
    mi[pos] = min(mi[ls], mi[rs]);
}

void add(int pos, int w) {
    mi[pos] += w, tg[pos] += w;
}

void pushdown(int pos) {
    if (tg[pos]) {
        add(ls, tg[pos]);
        add(rs, tg[pos]);
        tg[pos] = 0;
    }
}

void modify(int L, int R, int w, int l, int r, int pos) {
    if (L <= l && r <= R) return add(pos, w);
    int mid = (l + r) >> 1;
    pushdown(pos);
    if (L <= mid) modify(L, R, w, l, mid, ls);
    if (mid < R) modify(L, R, w, mid + 1, r, rs);
    mi[pos] = min(mi[ls], mi[rs]);
}

int query(int w, int l, int r, int pos) {
    if (l == r) return l;
    pushdown(pos);
    int mid = (l + r) >> 1;
    return mi[ls] <= w
        ? query(w, l, mid, ls)
        : query(w, mid + 1, r, rs);
}

void chk(int l, int r) {
    if (r - l > ansr - ansl || (r - l == ansr - ansl && l < ansl))
        ansl = l, ansr = r;
}

int smi[N], tmi, smx[N], tmx;
map<int, int> las;

void work(int *a, int n, int m, int dlt) {
    build(1, n, 1);
    tmi = tmx = 0, las.clear();
    for (int i = 1; i <= n; ++i) {
        while (tmi && a[smi[tmi]] >= a[i])
            modify(smi[tmi - 1] + 1, smi[tmi], a[smi[tmi]], 1, n, 1), tmi--;
        modify(smi[tmi] + 1, i, -a[i], 1, n, 1), smi[++tmi] = i;
        while (tmx && a[smx[tmx]] <= a[i])
            modify(smx[tmx - 1] + 1, smx[tmx], -a[smx[tmx]], 1, n, 1), tmx--;
        modify(smx[tmx] + 1, i, a[i], 1, n, 1), smx[++tmx] = i;
        if (int tmp = las[a[i]])
            modify(1, tmp, INF, 1, n, 1);
        las[a[i]] = i;
        int l = query(m + i, 1, n, 1);
        assert(l);
        chk(l + dlt, i + dlt);
    }
}

int main() {
#ifdef isLOCAL
    freopen(".in", "r", stdin);
    freopen(".out", "w", stdout);
#endif

    static int n, m, d, a[N];
    cin >> n >> m >> d;
    for (int i = 1; i <= n; ++i)
        scanf("%d", a + i);

    if (!d) {
        for (int l = 1, r; l <= n; l = r + 1) {
            for (r = l; r < n && a[r + 1] == a[l]; ++r);
            chk(l, r);
        }
        cout << ansl << " " << ansr << endl;
        return 0;
    }
    // XXX d = 0's condition

    for (int l = 1, r; l <= n; l = r + 1) {
        for (r = l; r < n && (a[r + 1] % d + d) % d == (a[l] % d + d) % d; ++r);
        for (int i = l; i <= r; ++i)
            a[i] = (a[i] + INF) / d;
        work(a + l - 1, r - l + 1, m, l - 1);
    }

    cout << ansl << ' ' << ansr << endl;

    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define next Next
#define int long long
#define mid (l+r)/2
const int N=1e6+5;
int n,m,k,d,ans,l,r,top1,top2,ansL,ansR,a[N],zuo[N],zhan1[N],zhan2[N];
int mi[N*4],ma[N*4],tree[N*4],tag1[N*4],tag2[N*4];
map<int,int>gs;
/*char buf[1<<21],*p1=buf,*p2=buf;
inline int gc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}*/
#define gc getchar
inline int read()
{
	int ret=0,f=0;char c=gc();
	while(!isdigit(c)){if(c=='-')f=1;c=gc();}
	while(isdigit(c)){ret=ret*10+c-48;c=gc();}
	if(f)return -ret;return ret;
}
void pushup(int nod)
{
	mi[nod]=min(mi[nod*2],mi[nod*2+1]);
	ma[nod]=max(ma[nod*2],ma[nod*2+1]);
	tree[nod]=min(tree[nod*2],tree[nod*2+1]);
}
void pushdown(int nod)
{
	mi[nod*2]+=tag1[nod];tag1[nod*2]+=tag1[nod];
	mi[nod*2+1]+=tag1[nod];tag1[nod*2+1]+=tag1[nod];
	tag1[nod]=0;tree[nod*2]-=tag1[nod];tree[nod*2+1]-=tag1[nod];
	ma[nod*2]+=tag2[nod];tag2[nod*2]+=tag2[nod];
	ma[nod*2+1]+=tag2[nod];tag2[nod*2+1]+=tag2[nod];
	tag2[nod]=0;tree[nod*2]+=tag2[nod];tree[nod*2+1]+=tag2[nod];
}
void build(int nod,int l,int r)
{
	if(l==r)
	{
		tree[nod]=l;
		mi[nod]=ma[nod]=a[l];
		return;
	}
	build(nod*2,l,mid);
	build(nod*2+1,mid+1,r);
	pushup(nod);
}
int find(int nod,int l,int r,int x)
{
	if(l==r)return l;
	pushdown(nod);
	if(tree[nod*2]<=x)return find(nod*2,l,mid,x);
	else return find(nod*2+1,mid+1,r,x);
}
void del(int nod,int l,int r,int x)
{
	if(l==r){tree[nod]=1e15;return;}
	pushdown(nod);
	if(x<=mid)del(nod*2,l,mid,x);
	else del(nod*2+1,mid+1,r,x);
	pushup(nod);
}
void change1(int nod,int l,int r,int L,int R,int val)
{
	if(L<=l&&r<=R)
	{
		mi[nod]+=val;
		tag1[nod]+=val;
		tree[nod]-=val;
		return;
	}
	pushdown(nod);
	if(R<=mid)change1(nod*2,l,mid,L,R,val);
	else if(L>mid)change1(nod*2+1,mid+1,r,L,R,val);
	else{
		change1(nod*2,l,mid,L,mid,val);
		change1(nod*2+1,mid+1,r,mid+1,R,val);
	}
	pushup(nod);
}
void change2(int nod,int l,int r,int L,int R,int val)
{
	if(L<=l&&r<=R)
	{
		ma[nod]+=val;
		tag2[nod]+=val;
		tree[nod]+=val;
		return;
	}
	pushdown(nod);
	if(R<=mid)change2(nod*2,l,mid,L,R,val);
	else if(L>mid)change2(nod*2+1,mid+1,r,L,R,val);
	else{
		change2(nod*2,l,mid,L,mid,val);
		change2(nod*2+1,mid+1,r,mid+1,R,val);
	}
	pushup(nod);
}
signed main()
{
	n=read();k=read();d=read();
	for(int i=1;i<=n;i++)a[i]=read()+1e9;
	if(!d)
    {
        for(int i=1,j;i<=n;)
        {
            j=i;
            while(j<n&&a[j+1]==a[i])j++;
            if(j-i+1>ans){ans=j-i+1;ansL=i;ansR=j;}
            i=j+1;
        }
        printf("%lld %lld\n",ansL,ansR);
        return 0;
    }
	for(int i=1;i<=n;)
    {
        int j=i;
		zuo[i]=i;
        while(j<n&&a[j+1]%d==a[i]%d){j++;zuo[j]=i;}
        i=j+1;
    }
    r=1;
    build(1,1,n);
    while(l<n)
    {
        l++;gs[a[l]]++;
        while(gs[a[l]]>1||zuo[l]!=zuo[r])
		{
			del(1,1,n,r);
			gs[a[r]]--;
			r++;
		}
        while(top1>0&&a[l]<=a[zhan1[top1]])
        {
            change1(1,1,n,zhan1[top1-1]+1,zhan1[top1],a[l]/d-a[zhan1[top1]]/d);
            top1--;
        }
        zhan1[++top1]=l;
        while(top2>0&&a[l]>=a[zhan2[top2]])
        {
            change2(1,1,n,zhan2[top2-1]+1,zhan2[top2],a[l]/d-a[zhan2[top2]]/d);
            top2--;
        }
        zhan2[++top2]=l;
        int L=find(1,1,n,l+k);
        if(L>=r&&l-L+1>ans)
		{
			ans=l-L+1;
			ansL=L;ansR=l;
		}
    }
    printf("%lld %lld\n",ansL,ansR);
    return 0;
}
/*
*/


#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#define fi first
#define se second
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
typedef pair<int,int> PP;
typedef long long ll;

struct tree
{
	int a,x,add,min;
	int c[2] , fa;
};
const int maxlong = int(1e9)+5;
const int N = int(2e5)+5;
int n , K , D;
ll KD;
int a[N] , dr[N] , tp[N] , r[N];
PP ma[N] , mi[N];
int t1 , t2 , root;
map<int,int> t;
tree tr[N];
inline void Init()
{
	scanf("%d%d%d",&n,&K,&D);
	KD = ll(K)*D;
	fo(i,2,n+1) scanf("%d",&a[i]);
}
inline boid chan(int x,int v){tr[x].min += v;tr[x].a += v; tr[x].add += v;}
inline void up(int x)
{
	tr[x].x = x; tr[x].min = tr[x].a;
	int l = tr[x].c[0] , r = tr[x].c[1];
	if (l && tr[x].min > tr[l].min - ll(tr[l].x-tr[x].x)*D) tr[x].x = tr[l].x , tr[x].min = tr[l].min;
	if (r && tr[x].min > tr[r].min - ll(tr[r].x-tr[x].x)*D) tr[x].x = tr[r].x , tr[x].min = tr[r].min;
}
inline void down(int x)
{
	int l = tr[x].c[0] , r = tr[x].c[1];
	if (l) chan(l , tr[x].add);
	if (r) chan(r , tr[x].add);
	tr[x].add = 0;
}
inline void turn(int x,int t)
{
	int y = tr[x].c[t] , z = tr[y].c[!t] , fa = tr[x].fa;
	if (fa)
	if (tr[fa].c[0] == x) tr[fa].c[0]=y;else tr[fa].c[1]=y;
	tr[x].c[t] = z; tr[y].c[!t]=x;
	tr[x].fa = y; tr[y].fa = fa;
	if (z) tr[z].fa = x;
	up(x); up(y);
}

inline void uproot(int x,int mb)
{
	int y = x , cnt(0);
	while (y != mb) tp[++cnt]=y , y=tr[y].fa;
	fd(i,cnt,1) down(tp[i]);
	fo(i,2,cnt) dr[i] = (tr[tp[i]].c[1] == tp[i-1]);
	for(int i=2;i<=cnt;i+=2)
	if (i == cnt) turn(tp[i],dr[i]);else
	if (dr[i] == dr[i+1]) turn(tp[i+1],dr[i+1]) , turn(tp[i],dr[i]);else
	turn(tp[i],dr[i]) , turn(tp[i+1],dr[i+1]);
	if (!mb) root = x;
}
inline void change(int l,int r,int v)
{
	uproot(r+1 , 0);
	uproot(l-1 , root);
	chan(tr[tr[root].c[0]].c[1] , v);
	up(tr[root].c[0]); up(root);
}
inline int find(int l,int r)
{
	uproot(r+1 , 0);
	uproot(l-1 , root);
	int x = tr[tr[root].c[0]].c[1];
	while (1)
	{
		down(x);
		int lx = tr[tr[x].c[1]].x;
		if (tr[x].c[1] && tr[tr[x].c[1]].min - ll(lx-l)*D <= KD) x = tr[x].c[1];else
		if (tr[x].a - ll(x-l)*D <= KD) return x;else x = tr[x].c[0];
	}
	return x;
}
inline int make(int l,int r)
{
	if (l > r) return 0;
	if (l == r) return l;
	int mid = (l+r)>>1;
	tr[mid].c[0] = make(l,mid-1);
	if (tr[mid].c[0]) tr[tr[mid].c[0]].fa = mid;
	tr[mid].c[1] = make(mid+1,r);
	if (tr[mid].c[1]) tr[tr[mid].c[1]].fa = mid;
	return mid;
}
inline void Work()
{
	if (!D)
    {
        int ansl = n+2 , ansr = n+1;
        fo(i,1,n)
        {
            if (r[i-1] >= i) continue;
            r[i] = i;
            while (r[i] < n && a[i] == a[r[i]+1]) r[i]++;
            if (r[i] - i > ansr - ansl) ansl = i , ansr = r[i];
        }
        printf("%d %d\n",ansl-1,ansr-1);
        return;
    }
	fo(i,2,n+1)
    {
        if (r[i-1] < i) t[a[i]]++ , r[i] = i;else r[i] = r[i-1];
        while (r[i] < n+1 && (a[r[i]+1]%D+D)%D == (a[i]%D+D)%D && t[a[r[i]+1]] == 0)
        r[i]++ , t[a[r[i]]]++;
        t[a[i]]--;
    }

	root = make(1,n+2);
	fo(i,1,n+2) tr[i].a = tr[i].min = maxlong;
	ma[0] = PP(n+2 , maxlong); mi[0] = PP(n+2 , -maxlong);
	t1 = t2 = 0;
	int last , ansr = n+2 , ansl = n+2 , nr;
	fd(i,n+1,2)
	{
		tr[i].a = tr[i].min = 0;
		tr[i].x = i;
		last = i+1;
		while (a[i] > ma[t1].se && t1)
		change(last,ma[t1-1].fi-1,a[i]-ma[t1].se) , t1-- , last = ma[t1].fi;
		ma[++t1] = PP(i , a[i]);
		last = i+1;
		while (a[i] < mi[t2].se && t2)
		change(last,mi[t2-1].fi-1,mi[t2].se-a[i]) , t2-- , last = mi[t2].fi;
		mi[++t2] = PP(i , a[i]);
		nr = find(i , r[i]);
		if (nr - i >= ansr - ansl) ansl = i , ansr = nr;
	}
	printf("%d %d\n",ansl-1,ansr-1);
}

int main()
{
	Init();
	Work();
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define next Next
#define int long long
#define mid (l+r)/2
const int N=1e6+5;
int n,m,k,d,ans,l,r,top1,top2,ansL,ansR,a[N],zuo[N],gs[N],zhan1[N],zhan2[N];
int mi[N*4],ma[N*4],tree[N*4],tag1[N*4],tag2[N*4];
/*char buf[1<<21],*p1=buf,*p2=buf;
inline int gc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}*/
#define gc getchar
inline int read()
{
	int ret=0,f=0;char c=gc();
	while(!isdigit(c)){if(c=='-')f=1;c=gc();}
	while(isdigit(c)){ret=ret*10+c-48;c=gc();}
	if(f)return -ret;return ret;
}
void pushup(int nod)
{
	mi[nod]=min(mi[nod*2],mi[nod*2+1]);
	ma[nod]=max(ma[nod*2],ma[nod*2+1]);
	tree[nod]=min(tree[nod*2],tree[nod*2+1]);
}
void pushdown(int nod)
{
	mi[nod*2]+=tag1[nod];tag1[nod*2]+=tag1[nod];
	mi[nod*2+1]+=tag1[nod];tag1[nod*2+1]+=tag1[nod];
	tag1[nod]=0;
	ma[nod*2]+=tag2[nod];tag2[nod*2]+=tag2[nod];
	ma[nod*2+1]+=tag2[nod];tag2[nod*2+1]+=tag2[nod];
	tag2[nod]=0;
}
void build(int nod,int l,int r)
{
	if(l==r)
	{
		tree[nod]=l;
		mi[nod]=ma[nod]=a[l];
		return;
	}
	build(nod*2,l,mid);
	build(nod*2+1,mid+1,r);
	pushup(nod);
}
int find(int nod,int l,int r,int x)
{
	if(l==r)return l;
	pushdown(nod);
	if(tree[nod*2]<=x)return find(nod*2,l,mid,x);
	else return find(nod*2+1,mid+1,r,x);
}
void del(int nod,int l,int r,int x)
{
	if(l==r){tree[nod]=1e15;return;}
	if(x<=mid)del(nod*2,l,mid,x);
	else del(nod*2+1,mid+1,r,x);
	pushup(nod);
}
void change1(int nod,int l,int r,int L,int R,int val)
{
	if(l==L&&r==R)
	{
		mi[nod]+=val;
		tag1[nod]+=val;
		tree[nod]-=val;
		return;
	}
	pushdown(nod);
	if(R<=mid)change1(nod*2,l,mid,L,R,val);
	else if(L>mid)change1(nod*2+1,mid+1,r,L,R,val);
	else{
		change1(nod*2,l,mid,L,mid,val);
		change1(nod*2+1,mid+1,r,mid+1,R,val);
	}
	pushup(nod);
}
void change2(int nod,int l,int r,int L,int R,int val)
{
	if(l==L&&r==R)
	{
		ma[nod]+=val;
		tag2[nod]+=val;
		tree[nod]+=val;
		return;
	}
	pushdown(nod);
	if(R<=mid)change2(nod*2,l,mid,L,R,val);
	else if(L>mid)change2(nod*2+1,mid+1,r,L,R,val);
	else{
		change2(nod*2,l,mid,L,mid,val);
		change2(nod*2+1,mid+1,r,mid+1,R,val);
	}
	pushup(nod);
}
signed main()
{
	n=read();k=read();d=read();
	for(int i=1;i<=n;i++)a[i]=read()+1000000000;
	if(!d)
    {
        for(int i=1,j;i<=n;)
        {
            j=i;
            while(j<n&&a[j+1]==a[i])j++;
            if(j-i+1>ans){ans=j-i+1;ansL=i;ansR=j;}
            i=j+1;
        }
        printf("%lld %lld\n",ansL,ansR);
        return 0;
    }
	for(int i=1;i<=n;)
    {
        int j=i;
		zuo[i]=i;
        while(j<n&&a[j+1]%d==a[i]%d){j++;zuo[j]=i;}
        i=j+1;
    }
    build(1,1,n);
    while(l<n)
    {
        l++;gs[a[l]]++;
        while(gs[a[l]]>1||zuo[l]!=zuo[r])
		{
			del(1,1,n,r);
			gs[a[r]]--;
			r++;
		}
        while(top1>0&&a[l]<=a[zhan1[top1]])
        {
            change1(1,1,n,zhan1[top1-1]+1,zhan1[top1],a[l]/d-a[zhan1[top1]]/d);
            top1--;
        }
        zhan1[++top1]=l;
        while(top2>0&&a[l]>=a[zhan2[top2]])
        {
            change2(1,1,n,zhan2[top2-1]+1,zhan2[top2],a[l]/d-a[zhan2[top2]]/d);
            top2--;
        }
        zhan2[++top2]=l;
        int L=find(1,1,n,l+k);
        if(L>=r&&l-L+1>ans)
		{
			ans=l-L+1;
			ansL=L;ansR=l;
		}
    }
    printf("%lld %lld\n",ansL,ansR);
    return 0;
}
/*
*/