#pragma GCC optimize("Ofast")
#include <cassert>
#include <cstdio>
#include <cstdlib>
#include <string>
#include <algorithm>
#include <iostream>
#include <queue>
#include <vector>
#include <bitset>
#include <cmath>
#include <limits>
#include <iostream>
#include <map>
#include <set>
#include <stack>
#include <tuple>
#include <iomanip>
#include <functional>
#include <complex>

using namespace std;

using ll=long long int;
using pii=pair<int,int>;
using pil=pair<int,ll>;
using pli=pair<ll,int>;
using pll=pair<ll,ll>;
using psi=pair<string,int>;
using pis=pair<int,string>;
using psl=pair<string,ll>;
using pls=pair<ll,string>;
using pss=pair<string,string>;



template<typename T> using vc=vector<T>;
template<typename T> using vvc=vector<vector<T>>;
template<typename T> using vvvc=vector<vector<vector<T>>>;
template<typename T> using vvvvc=vector<vvvc<T>>;
template<typename T> using vvvvvc=vector<vvvvc<T>>;

template<class T,class U>inline constexpr bool chmin(T&a,const U b){if(a<=b)return false;a=b;return true;}
template<class T,class U>inline constexpr bool chmax(T&a,const U b){if(a>=b)return false;a=b;return true;}
#define bit(n,k) ( (n>>k)&1 )

inline void bin101(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr); 
    cout<<fixed<<setprecision(20);
}

template<typename T>
inline void Yes(T flag){
    if(flag) cout<<"Yes"<<endl;
    else cout<<"No"<<endl;
}

template<typename T>
inline void YES(T flag){
    if(flag) cout<<"YES"<<endl;
    else cout<<"NO"<<endl;
}

//1-indexed vector cin
template<typename T>
inline void vin1(vector<T> &v){
    for(int i=1;i<v.size();i++) cin>>v[i];
}

//0-indexed vector cin
template<typename T>
inline void vin0(vector<T> &v){
    for(int i=0;i<v.size();i++) cin>>v[i];
}

//1-indexed vector<vector> cin
template<typename T>
inline void vin1(vector<vector<T>> &v){
    for(int i=1;i<v.size();i++){
        for(int j=1;j<v[i].size();j++) cin>>v[i][j];
    }
}

//0-indexed vector<vector> cin
template<typename T>
inline void vin0(vector<vector<T>> &v){
    for(int i=0;i<v.size();i++){
        for(int j=0;j<v[i].size();j++) cin>>v[i][j];
    }
}



//デバッグ
template<typename T>
inline void vout(const vector<T> &v){
    cout<<"\nstart\n";
    const int sz=v.size();
    for(int i=0;i<sz;i++){
        cout<<i<<" "<<v[i]<<'\n';
    }
    cout<<"end\n"<<endl;
}
//デバッグ
template<typename T>
inline void vout(const vvc<T> &v){
    cout<<"\nstart\n";
    const int sz=v.size();
    for(int i=0;i<sz;i++){
        int ssz=v[i].size();
        for(int j=0;j<ssz;j++){
            cout<<i<<" "<<j<<" "<<v[i][j]<<'\n';
        }
    }
    cout<<"\nend\n"<<endl;
}

//デバッグ(グリッド)
template<typename T>
inline void gvout(const vector<T> &v){
    cout<<"\nstart\n";
    const int sz=v.size();
    for(int i=0;i<sz;i++){
        if(i) cout<<" ";
		cout<<v[i];
    }
    cout<<"\nend\n"<<endl;
}
//デバッグ(グリッド)
template<typename T>
inline void gvout(const vvc<T> &v){
    cout<<"\nstart\n";
    const int sz=v.size();
    for(int i=0;i<sz;i++){
        int ssz=v[i].size();
        for(int j=0;j<ssz;j++){
			if(j) cout<<" ";
            cout<<v[i][j];
        }
		cout<<endl;
    }
    cout<<"end\n"<<endl;
}


//デバッグ
template<typename T>
inline void vout(const vvvc<T> &v){
    cout<<"\nstart\n";
    const int sz=v.size();
    for(int i=0;i<sz;i++){
        int ssz=v[i].size();
        for(int j=0;j<ssz;j++){
            int sssz=v[i][j].size();
            for(int k=0;k<sssz;k++){
                cout<<i<<" "<<j<<" "<<k<<" "<<v[i][j][k]<<'\n';
            }
        }
    }
    cout<<"end\n"<<endl;
}


//pair cout
template<typename T, typename U>
inline ostream &operator<<(ostream &os,const pair<T,U> &p) {
  os<<p.first<<" "<<p.second;
  return os;
}

//pair cin
template<typename T, typename U>
inline istream &operator>>(istream &is,pair<T,U> &p) {
  is>>p.first>>p.second;
  return is;
}

//ソート
template<typename T>
inline void vsort(vector<T> &v){
    sort(v.begin(),v.end());
}

//逆順ソート
template<typename T>
inline void rvsort(vector<T> &v){
  sort(v.rbegin(),v.rend());
}

//要素数a 初期値x
template<typename T>
inline vector<T> vmake(int a,T x){
  return vector<T>(a,x);
}

//data[a][b] 初期値x
template<typename T>
inline vector<vector<T>> vmake(int a,int b,T x){
  return vector<vector<T>>(a, vector<T>(b,x));
}

//data[a][b][c] 初期値x
template<typename T>
inline vector<vector<vector<T>>> vmake(int a,int b,int c,T x){
  return vector<vector<vector<T>>> (a, vector<vector<T>>(b, vector<T>(c, x)));
}

//data[a][b][c][d]　初期値x
template<typename T>
inline vector<vector<vector<vector<T>>>> vmake(int a,int b,int c,int d,T x){
  return vector<vector<vector<vector<T>>>> (a,vvvc<T>(b,vvc<T>(c,vc<T>(d,x))));
}

//data[a][b][c][d][e] 初期値x
template<typename T>
inline vvvvvc<T> vmake(int a,int b,int c,int d,int e,T x){
  return vvvvvc<T> (a,vvvvc<T>(b,vvvc<T>(c,vvc<T>(d,vc<T>(e,x)))));
}

//1ビットの数を返す
inline int popcount(int x){
  return __builtin_popcount(x);
}
//1ビットの数を返す
inline int popcount(ll x){
  return __builtin_popcountll(x);
}

//queのfront() pop()
template<typename T>
inline T pop(queue<T> &que){
    T x=que.front();
    que.pop();
    return x;
}

//priority_que top() pop()
template<typename T>
inline T pop(priority_queue<T> &que){
  T x=que.top();
  que.pop();
  return x;
}

//stack top() pop()
template<typename T>
inline T pop(stack<T> &st){
  T x=st.top();
  st.pop();
  return x;
}

#define SZ(x) ( (int)x.size()  )
#define pb push_back

/*
満たすものの個数を返す
mode:0 x未満
mode:1 x以下の数
mode:2 x以上の数
mode:3 x超
mode:4 x
*/
template<typename T>
inline int count_bound(vector<T> &v,T x,int mode){
    switch(mode){
        case 0:
            return lower_bound(v.begin(),v.end(),x)-v.begin();
        case 1:
            return upper_bound(v.begin(),v.end(),x)-v.begin();
        case 2:
            return v.end()-lower_bound(v.begin(),v.end(),x);
        case 3:
            return v.end()-upper_bound(v.begin(),v.end(),x);
        case 4:
            return upper_bound(v.begin(),v.end(),x)-lower_bound(v.begin(),v.end(),x);
    }
}

/*
mode:0 xより小さい数で最大の数
mode:1 x以下の数で最大の数
mode:2 x以上の数で最小の数
mode:3 xより大きい数で最小の数
*/
template<typename T>
inline T value_bound(vector<T> &v,T x,int mode){
    switch(mode){
        case 0:
            return *(--lower_bound(v.begin(),v.end(),x));
        case 1:
            return *(--upper_bound(v.begin(),v.end(),x));
        case 2:
            return *lower_bound(v.begin(),v.end(),x);
        case 3:
            return *upper_bound(v.begin(),v.end(),x);
    }
}



constexpr int MAX=1<<30;
constexpr ll INF=1LL<<62;
constexpr ll MOD=1e9+7;
int dx[]={1,-1,0,0},dy[]={0,0,-1,1};

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

template<typename T,typename L>
struct LazySegmentTree{
    //using
    using F=function<T(T,T)>;
    using G=function<T(T,L)>;
    using H=function<L(L,L)>; //二番目が後に追加されたもの

    //データ
    int sz;
    int height;
    vector<T> seg;
    vector<L> lazy;
    const T sut;
    const L lut;
    const F f;
    const G g;
    const H h;

    LazySegmentTree(int n,const T sut,const L lut,const F &f,const G &g,const H &h):sut(sut),lut(lut),f(f),g(g),h(h){
        sz=1;
        height=0;
        while(sz<n) sz<<=1,height++;
        seg.assign((sz<<1),sut);
        lazy.assign((sz<<1),lut);        
    }

    inline void set(int k,const T &x){
        seg[k+sz]=x;
    }
    inline void build(){
        for(int k=sz-1;k>0;k--){
            seg[k]=f(seg[(k<<1)],seg[(k<<1)+1]);
        }
    }
    inline T reflect(int k){
        return (lazy[k]==lut) ? seg[k]:g(seg[k],lazy[k]);
    }
    //子にlazyを伝える(updateで丸々収まる所を更新した尻ぬぐい)
    //lazy[k]とlazy[2*k]が違った場合,lazy[k]の方が後に更新されたもの
    inline void propagate(int k){
        if(lazy[k]!=lut){
            lazy[(k<<1)]=h(lazy[(k<<1)],lazy[k]);
            lazy[(k<<1)+1]=h(lazy[(k<<1)+1],lazy[k]);
            seg[k]=reflect(k);
            lazy[k]=lut;
        }
    }
    //ボトムアップで更新していく
    inline void recalc(int k){
        while(k>>=1) seg[k]=f(reflect((k<<1)),reflect((k<<1)+1));
    }
    //トップダウンで更新していく(これでseg[k]が正しい値になる)
    inline void thrust(int k){
        for(int i=height;i>0;i--) propagate(k>>i);
    }
    //[a:b)
    void update(int a,int b,const L &x){
        //トップダウンでlazy[i]!=lutのものを更新
        thrust(a+=sz);
        thrust(b+=sz-1);
        //丸々収まるところを更新
        for(int l=a,r=b+1;l<r;l>>=1,r>>=1){
            if(l&1) lazy[l]=h(lazy[l],x),l++;
            if(r&1) --r,lazy[r]=h(lazy[r],x);
        }
        //ボトムアップで新しく更新
        recalc(a);
        recalc(b);
    }

    //[a:b)
    T query(int a,int b){
        //トップダウンで関係あってlazy[i]!=lutのものを更新
        thrust(a+=sz);
        thrust(b+=sz-1);
        //更新した後は普通のセグ木と同じ
        T l=sut,r=sut;
        for(a,b+=1;a<b;a>>=1,b>>=1){
            if(a&1) l=f(l,reflect(a++));
            if(b&1) r=f(reflect(--b),r);
        }
        return f(l,r);
    }
    //セグ木と違い、log(n)かかる
    T operator[](const int k){
        return query(k,k+1);
    }

};


signed main(){
	bin101();

    int N,K,C;
    cin>>N>>K>>C;
    string S;
    cin>>S;

    vector<int> pre(N,K+1);
    vector<int> status(N,K);
    int now=K;
    for(int i=N-1;i>=0;i--){
        chmin(now,status[i]);
        if(S[i]=='x') continue;
        pre[i]=now;
        if(i-1-C>=0) chmin(status[i-1-C],now-1);
    }
    vector<int> post(N,-1);
    status.assign(N,-1);
    now=1;
    for(int i=0;i<N;i++){
        chmax(now,status[i]);
        if(S[i]=='x') continue;
        post[i]=now;
        if(i+1+C<N) chmax(status[i+1+C],now+1);
    }
    auto f1=[](pii a,pii b){
        pii x;
        x.second=-1;
        chmax(b.second,a.second);
        chmax(x.second,b.second);
        x.first=a.first+b.first;
        return x;
    };
    auto f2=[](pii a,pii b){
        pii x;
        x.second=-1;
        chmax(b.second,a.second);
        chmax(x.second,b.second);
        x.first=a.first+b.first;
        return x;
    };
    auto f3=[](pii a,pii b){
        pii x;
        x.second=-1;
        chmax(b.second,a.second);
        chmax(x.second,b.second);
        x.first=a.first+b.first;
        return x;
    };
    LazySegmentTree<pii,pii> seg(N,{0,0},{0,0},f1,f2,f3);
    seg.build();
    for(int i=0;i<N;i++){
        //cout<<pre[i]<<" "<<post[i]<<endl;
        if(pre[i]<=post[i]){
            seg.update(pre[i],post[i]+1,pii(1,i+1));
        }
    }
    vector<int> ret;
    seg.build();
    for(int i=1;i<=K;i++){
        pii x=seg[i];
        //cout<<seg[i].first<<" "<<seg[i].second<<endl;
        if(x.first==1){
            ret.push_back(x.second);
        }
    }
    //return 0;
    //cout<<ret.size()<<endl;
    vsort(ret);
    for(int i=0;i<ret.size();i++) cout<<ret[i]<<endl;
}


Measured memory_bytes: 13196