#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <cmath>
#include <queue>
#include <map>
#include <unordered_map>
#include <set>
#include <functional>
#include <bitset>
#include <numeric>
#include <complex>
#include <cassert>
#include <random>
using namespace std;
using ll = long long;

class SegmentTree {
private:
	using Monoid = int;
	const Monoid INI = 0;
	Monoid op(Monoid a, Monoid b) {
		return max(a, b);
	}

	int num;
	vector<Monoid> dat;

public:
	SegmentTree(int n_) {
		num = 1;
		while (num < n_) num *= 2;
		dat = vector<Monoid>(2 * num, INI);
	}

	SegmentTree(const vector<Monoid> &m) : SegmentTree(m.size()) {
		int n = m.size();
		for (int i = 0; i < n; i++) {
			dat[num - 1 + i] = m[i];
		}
		for (int i = num - 2; i >= 0; i--) {
			dat[i] = op(dat[2 * i + 1], dat[2 * i + 2]);
		}
	}

	// Update the k-th value (0-indexed) to a.
	void update(int k, Monoid a) {
		k += num - 1;
		dat[k] = a;
		while (k > 0) {
			k = (k - 1) / 2;
			dat[k] = op(dat[2 * k + 1], dat[2 * k + 2]);
		}
	}

	// Get the value of the range [a, b).
	// k: The index of the node.
	// [left, right): The range corresponds to the k-th node.
	// Call like getval(a, b).
	Monoid getval(int a, int b, int k = 0, int left = 0, int right = -1) {
		if (right < 0) right = num;
		if (right <= a || b <= left) return INI;
		if (a <= left && right <= b) return dat[k];
		Monoid vleft = getval(a, b, 2 * k + 1, left, left + (right - left) / 2);
		Monoid vright = getval(a, b, 2 * k + 2, left + (right - left) / 2, right);
		return op(vleft, vright);
	}
};

class SegmentTree2 {
private:
	using Monoid = int;
	const Monoid INI = 0;
	Monoid op(Monoid a, Monoid b) {
		return a + b;
	}

	int num;
	vector<Monoid> dat;

public:
	SegmentTree2(int n_) {
		num = 1;
		while (num < n_) num *= 2;
		dat = vector<Monoid>(2 * num, INI);
	}

	SegmentTree2(const vector<Monoid> &m) : SegmentTree2(m.size()) {
		int n = m.size();
		for (int i = 0; i < n; i++) {
			dat[num - 1 + i] = m[i];
		}
		for (int i = num - 2; i >= 0; i--) {
			dat[i] = op(dat[2 * i + 1], dat[2 * i + 2]);
		}
	}

	// Update the k-th value (0-indexed) to a.
	void update(int k, Monoid a) {
		k += num - 1;
		dat[k] = a;
		while (k > 0) {
			k = (k - 1) / 2;
			dat[k] = op(dat[2 * k + 1], dat[2 * k + 2]);
		}
	}

	// Get the value of the range [a, b).
	// k: The index of the node.
	// [left, right): The range corresponds to the k-th node.
	// Call like getval(a, b).
	Monoid getval(int a, int b, int k = 0, int left = 0, int right = -1) {
		if (right < 0) right = num;
		if (right <= a || b <= left) return INI;
		if (a <= left && right <= b) return dat[k];
		Monoid vleft = getval(a, b, 2 * k + 1, left, left + (right - left) / 2);
		Monoid vright = getval(a, b, 2 * k + 2, left + (right - left) / 2, right);
		return op(vleft, vright);
	}
};



int main() {
	int n, k, c; cin >> n >> k >> c;
	string s; cin >> s;
	if (c == 0) {
		int cnt = 0;
		for (int i = 0; i < n; i++) cnt += s[i] == 'o';
		if (cnt == k) {
			for (int i = 0; i < n; i++) {
				if (s[i] == 'o') cout << i + 1 << endl;
			}
		}
		return 0;
	}
	SegmentTree segl(n), segr(n);
	for (int i = 0; i < n; i++) {
		if (s[i] == 'x') continue;
		int v = segl.getval(0, i - c);
		segl.update(i, v + 1);
	}
	for (int i = n - 1; i >= 0; i--) {
		if (s[i] == 'x') continue;
		int v = segr.getval(i + c + 1, n);
		segr.update(i, v + 1);
	}

	SegmentTree2 seg(n);
	for (int i = 0; i < n; i++) {
		if (s[i] == 'x') continue;
		int vl = segl.getval(0, i - c);
		int vr = segr.getval(i + c + 1, n);
		seg.update(i, vl + vr + 1 >= k);
	}

	vector<int> ans;
	for (int i = 0; i < n; i++) {
		int vm = seg.getval(i, i + 1);
		if (vm == 0) continue;
		int l = i - c;
		int r = i + c + 1;
		int v = seg.getval(l, r);
		if (v > 1) continue;
		ans.push_back(i + 1);
	}
	for (int i = 0; i < (int)ans.size(); i++) {
		cout << ans[i] << "\n";
	}
	return 0;
}

Measured memory_bytes: 6788