Problem:
Score : 600 points

Problem Statement

Takahashi is playing a board game called Sugoroku.

On the board, there are N + 1 squares numbered 0 to N. Takahashi starts at Square 0, and he has to stop exactly at Square N to win the game.

The game uses a roulette with the M numbers from 1 to M. In each turn, Takahashi spins the roulette. If the number x comes up when he is at Square s, he moves to Square s+x. If this makes him go beyond Square N, he loses the game.

Additionally, some of the squares are Game Over Squares. He also loses the game if he stops at one of those squares. You are given a string S of length N + 1, representing which squares are Game Over Squares. For each i (0 \leq i \leq N), Square i is a Game Over Square if S[i] = 1 and not if S[i] = 0.

Find the sequence of numbers coming up in the roulette in which Takahashi can win the game in the fewest number of turns possible. If there are multiple such sequences, find the lexicographically smallest such sequence. If Takahashi cannot win the game, print -1.

Constraints

1 \leq N \leq 10^5

1 \leq M \leq 10^5

|S| = N + 1

S consists of 0 and 1.

S[0] = 0

S[N] = 0

Input

Input is given from Standard Input in the following format:

N M
S

Output

If Takahashi can win the game, print the lexicographically smallest sequence among the shortest sequences of numbers coming up in the roulette in which Takahashi can win the game, with spaces in between.

If Takahashi cannot win the game, print -1.

Sample Input 1

9 3
0001000100

Sample Output 1

1 3 2 3

If the numbers 1, 3, 2, 3 come up in this order, Takahashi can reach Square 9 via Square 1, 4, and 6. He cannot reach Square 9 in three or fewer turns, and this is the lexicographically smallest sequence in which he reaches Square 9 in four turns.

Sample Input 2

5 4
011110

Sample Output 2

-1

Takahashi cannot reach Square 5.

Sample Input 3

6 6
0101010

Sample Output 3

6

Solution in C++14 (GCC 5.4.1) (judge verdict: Accepted)

#include <iostream>
#include <algorithm>
#include <array>
#include <cstring>
#include <list>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <vector>
#include <map>
#include <chrono>
#include <random>
#include <math.h>
#include <bitset>
using namespace std;

using lli = long long int;
using Vint = std::vector<int>;
using Vlli = std::vector<lli>;
using Wint = std::vector<Vint>;
using Wlli = std::vector<Vlli>;
using Vbool = std::vector<bool>;
using Wbool = std::vector<Vbool>;
using pii = std::pair<int, int>;
using pll = std::pair<lli, lli>;
template <class T>
using Vec = std::vector<T>;
template <class T>
using Wec = Vec<Vec<T>>;

constexpr int MOD = 1e9 + 7;
constexpr int INFi = 2e9 + 1;
constexpr lli INFl = (lli)(9e18) + 1;
constexpr std::array<std::pair<int, int>, 4> dxdy = 
            {std::pair<int, int>(1, 0), std::pair<int, int>(-1, 0), 
             std::pair<int, int>(0, 1), std::pair<int, int>(0, -1)};
constexpr char BR = '\n';

#define DEBUG(x) std::cerr << #x << " = " << x << '\n';
#define FOR(i, a, b) for(int (i) = (a); (i) < (b); ++(i))
#define FOReq(i, a, b) for(int (i) = (a); (i) <= (b); ++(i))
#define rFOR(i, a, b) for(int (i) = (b); (i) >= (a); --(i))
#define FORstep(i, a, b, step) for(int (i) = (a); i < (b); i += (step))
#define REP(i, n) FOR(i, 0, n)
#define rREP(i, n) rFOR(i, 0, (n-1))
#define vREP(ele, vec) for(auto &(ele) : (vec))
#define vREPcopy(ele, vec) for(auto (ele) : (vec))
#define SORT(A) std::sort((A).begin(), (A).end())
#define RSORT(A) std::sort((A).rbegin(), (A).rend())
#define ALL(A) (A).begin(), (A).end()
// 座標圧縮 (for vector) : ソートしてから使うのが一般的 ; SORT(A) => COORDINATE_COMPRESSION(A)
#define COORDINATE_COMPRESSION(A) (A).erase(unique((A).begin(),(A).end()),(A).end())


template <class T> inline int argmin(std::vector<T> &vec){return min_element(vec.begin(), vec.end()) - vec.begin();}
template <class T> inline int argmax(std::vector<T> &vec){return max_element(vec.begin(), vec.end()) - vec.begin();}
template <class T> inline T& chmin(T& a, T b){return (a > b) ? a = b : a;}
template <class T> inline T& chmax(T& a, T b){return (a < b) ? a = b : a;}
template <class T> inline void reverseSORT(Vec<T> &Array){
  std::sort(Array.begin(), Array.end(), std::greater<T>());
}
inline int BitI(int k){return 1 << k;}
inline lli BitL(int k){return 1LL << k;}
inline void putsDouble(double d){printf("%.16lf\n", d);}
template <class T> inline std::string toString(T n){
  if(n == 0) return "0";
  std::string res;
  if(n < 0){n = -n;while(n != 0){res += (char)(n % 10 + '0'); n /= 10;}
  std::reverse(res.begin(), res.end()); return '-' + res;}
  while(n != 0){res += (char)(n % 10 + '0'); n /= 10;} std::reverse(res.begin(), res.end()); return res;
}

namespace MyFunc{
    using LLi = long long int;
    using ULLi = unsigned long long int;
    // GCD(a, b) ; a, bの最大公約数を求める関数
    inline LLi gcd(LLi a, LLi b){ while(b != 0){ a %= b; std::swap(a, b);} return a; }
    // LCM(a, b) ; a, bの最小公倍数を求める関数
    inline LLi lcm(LLi a, LLi b){ return (a * b) / MyFunc::gcd(a, b);}
    // 累乗を求める関数
    inline LLi power(LLi a, LLi n){
        LLi res = 1LL, waiting = a;
        while(n != 0LL){ if((n & 1LL) != 0LL) res *= waiting; waiting *= waiting; n >>= 1;}
        return res;
    }
    // 累乗の余りを求める関数
    inline LLi power_mod(LLi a, LLi n, LLi mod_number___ = 1e9 + 7){
        LLi res = 1LL, waiting = a;
        while(n != 0LL){ if((n & 1LL) != 0LL){ res *= waiting; res %= mod_number___;}
            waiting *= waiting; waiting %= mod_number___; n >>= 1; }
        return res;
    }
    // Z/pZ上の逆元を求める関数 (フェルマーの小定理)
    inline LLi inverse_mod(LLi a, LLi mod_number___ = 1e9 + 7){
        return MyFunc::power_mod(a, mod_number___-2);
    }
    inline LLi inverse_mod_euclid(LLi a, LLi mod_number___ = 1e9+7){
        LLi b = mod_number___, u = 1, v = 0;
        while (b != 0) { LLi t = a / b; a -= t * b; std::swap(a, b);
            u -= t * v; std::swap(u, v);}
        u %= mod_number___; if (u < 0) u += mod_number___;
        return u;
    }
    // 素数であるかを判定する関数
    template <typename Integer_type>
    inline bool isPrime(Integer_type n){
        if(n < 2) return false; if(n == 2) return true; if(n % 2 == 0) return false;
        for(Integer_type x = 3; x * x <= n; ++++x) if(n % x == 0) return false;
        return true;
    }
    // 素数であるかの真偽表を返す　: n ≥ 1
    inline std::vector<bool> primeTable(int n){
        std::vector<bool> res(n+1, true); res[0] = false; res[1] = false;
        for(int x = 2; x * x <= n; ++x) if(res[x]){
            for(int i = 2 * x; i <= n; i += x){ res[i] = false; } }
        return std::move(res);
    }
    // 素因数分解したベクトルを返す　; {素因数, 指数}
    template <typename Integer_type>
    inline std::vector<std::pair<Integer_type, int>> prime_factorization(Integer_type n){
        std::vector<std::pair<Integer_type, int>> res(0);
        if(n <= 0) return std::move(res); // 例外処理　: nが 0 以下
        if(n % 2 == 0){
            n /= 2; int cnt = 1; while(n % 2 == 0){ n /= 2; cnt++;}
            res.emplace_back(make_pair(2, cnt));
        }
        Integer_type x = 3;
        while(x * x <= n){
            if(n % x == 0){
                n /= x; int cnt = 1; while(n % x == 0){ n /= x; cnt++; }
                res.emplace_back(make_pair(x, cnt));
            } ++++x;
        } if(n > 1) res.emplace_back(make_pair(n, 1));
        return std::move(res);
    }
    // unsigned long 符号なし64bit整数で平方数かを判定する関数 O(log(N))
    inline bool is_square_unsigned(ULLi n){
        // 0 は 平方数
        if(n == 0) return true;
        // 平方数の可能性としては 2^32 - 1 が最大 : (2^32)^2 - 1
        static ULLi MAX_LONG_SQRT__ = (1UL << 32) - 1;
        if(MAX_LONG_SQRT__ * MAX_LONG_SQRT__ < n) return false;
        if(MAX_LONG_SQRT__ * MAX_LONG_SQRT__ == n) return true;
        // 二分探索
        ULLi smaller = 0, bigger = MAX_LONG_SQRT__;
        while(bigger - smaller > 1){
            ULLi m = (smaller + bigger) >> 1;
            if(m * m == n) return true;
            if(m * m < n) smaller = m;
            else bigger = m;
        }
        return false;
    }
    // 符号付き64bit整数で平方数か判定する関数
    inline bool is_square(LLi n){
        if(n < 0) return false;
        // 平方数を4で割った余りは 0 か 1 に限る
        if((n & 0b11) > 0b01) return false;
        return is_square_unsigned(n);
    }
}


// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


constexpr long long int inf = 9e18 + 1;


// Dijkstra 法 を行うクラス : updated : doubleも可能
template <class DistanceType = int, class AnsType = long long int>
class Dijkstra{
private:
    // 無限大 の距離
    const long long int infinity_cost = 9e18 + 1;
    const int V; // 枝の数, 頂点数
    // (指し示す頂点, コスト)
    using edge = std::pair<int, DistanceType>;
    using edgeSet = std::vector<edge>; // 1つの頂点からでる枝の集合
    std::vector<edgeSet> Edges; // 枝全体
    std::vector<AnsType> Distances; // 距離を表す
    std::vector<bool> hasVisited;
public:
    // コンストラクタ
    Dijkstra(int edgeSize): V(edgeSize){
        Edges.resize(edgeSize, edgeSet(0)); hasVisited.resize(edgeSize);
        Distances.resize(edgeSize, infinity_cost);
    }
    Dijkstra(int edgeSize, std::vector<edgeSet> &A): V(edgeSize){
        Edges = A; hasVisited.resize(edgeSize);
        Distances.resize(edgeSize, infinity_cost);
    }
    // デコンストラクタ
    ~Dijkstra(void){}
    // 頂点 u -> v へ 重み cost を追加
    void add(int u, int v, DistanceType cost){
        Edges[u].emplace_back(std::pair<int, DistanceType>(v, cost));
    }
    // 頂点 vertex 中心の計算を行う
    using Info__Type_ = std::pair<AnsType, int>;
    void computeAround(int vertex){
        std::fill(Distances.begin(), Distances.end(), infinity_cost);
        std::fill(hasVisited.begin(), hasVisited.end(), false);
        std::priority_queue<Info__Type_, std::vector<Info__Type_>,
            std::greater<Info__Type_>> undoneEdge;
        undoneEdge.push(edge(0, vertex));
        int vtx; AnsType dist;
        while(not undoneEdge.empty()){
            std::tie(dist, vtx) = undoneEdge.top(); undoneEdge.pop();
            
            if(hasVisited[vtx]) continue;
            hasVisited[vtx] = true; Distances[vtx] = dist;
            for(edge element : Edges[vtx]){
                AnsType nextDistance = dist + element.second;
                if(nextDistance < Distances[element.first])
                        undoneEdge.push(Info__Type_(nextDistance, element.first));
            }
        }
    }
    AnsType distance(int vertex){
        return Distances.at(vertex);
    }
    void debugShow(void){
        for(int i = 0; i < V; ++i){
            printf("距離[%d] : ", i);
            if(Distances[i] == infinity_cost) std::cout << "INF" << '\n';
            else std::cout << Distances[i] << '\n';
        }
    }
};



constexpr int MAX_N = 1e5 + 10;
char str[MAX_N + 10];
std::vector<int> pO;
std::vector<int> A;


int main(void){
    int n, m; scanf("%d%d%s", &n, &m, str);
    pO.resize(n+1, -1);
    REP(i, n+1) if(str[i] == '0') pO[i] = i;
    REP(i, n+1) if(str[i] == '1') pO[i] = pO[i-1];
    Dijkstra<int, long long int> D(n+1);
    REP(i, n) if(str[i] == '0'){
        int e = i + m; if(e > n) e = n;
        int v = pO[e];
        if(i == v){ puts("-1");return 0; }
        D.add(i, v, 1);
    }
    int idx = 0;
    while(idx < n){
        if(str[idx] == '1'){idx++; continue;}
        int cnt = 1;
        while(idx + cnt <= n and str[idx+cnt] == '1') cnt++;
        D.add(idx+cnt, idx, 0);
        //printf("%d -> %d\n", idx+cnt, idx);
        idx += cnt;
    }

    D.computeAround(0);
    if(D.distance(n) == inf){ puts("-1"); return 0;}
    int d = D.distance(n), v = n;
    std::stack<int> P;
    while(d > 0){
        int u = v - m; if(u < 0) u = 0;
        while(D.distance(u) != d - 1) u++;
        P.push(v - u); v = u; d--;
    }
    while(not P.empty()){
        printf("%d\n", P.top()); P.pop();
    }









    

    return 0;
}