use std::io::stdin;
use std::str::FromStr;

fn main(){
    let (n, m): (usize, usize) = get_pair();
    let s = get_chars();
    let ans = solve(n, m, &s);
    if let Some(v) = ans {
        print!("{}", v[0]);
        for i in 1..v.len() {
            print!(" {}", v[i]);
        }
        println!("");
    } else {
        println!("-1");
    }
}

fn solve(n: usize, m: usize, s: &Vec<char>) -> Option<Vec<usize>> {
    let mut v = vec![Z(None); n];
    v.push(Z(Some(Elem{
        cost: 0,
        current: n,
        after: 0,
    })));
    let mut st = SegmentTree::new(&mut v);
    for i in (0..n).rev() {
        if s[i] == '1'{ continue; }

        if let Z(Some(elem)) = st.mconcat(i+1, i+m+1).clone() {
            st.update(i, Z(Some(Elem{
                cost: elem.cost + 1,
                current: i,
                after: elem.current,
            })));
        }
    }
    if let Z(Some(elem)) = st.mconcat(0, 1).clone() {
        let mut ans = Vec::new();
        let mut c = elem;
        while c.current < n {
            ans.push(c.after - c.current);
            c = st.mconcat(c.after, c.after+1).clone().0.unwrap();
        }
        Some(ans)
    } else {
        None
    }
}


trait Monoid {
    fn mappend(&self, b: &Self) -> Self;
    fn mempty() -> Self;
}

struct Elem {
    cost: usize,
    current: usize,
    after: usize,
}

struct Z(Option<Elem>);

impl Monoid for Z {
    fn mappend(&self, b: &Self) -> Self {
        match &self.0 {
            None => b.clone(),
            Some(elem_a) => match &b.0 {
                None => self.clone(),
                Some(elem_b) => {
                    if elem_a.cost < elem_b.cost {
                        self.clone()
                    } else if elem_a.cost > elem_b.cost {
                        b.clone()
                    } else {
                        if elem_a.current < elem_b.current {
                            self.clone()
                        } else {
                            b.clone()
                        }
                    }
                },
            }
        }
    }
    fn mempty() -> Self {
        Z(None)
    }
}

impl Clone for Z {
    fn clone(&self) -> Self {
        match self.0 {
            None => Z(None),
            Some(Elem{cost, current, after}) => Z(Some(Elem{cost, current, after})),
        }
    }
}

struct SegmentTree<M: Monoid + Clone> {
    value: M,
    start: usize,
    end: usize,
    children: Option<Box<SegmentTreeChildren<M>>>
}

struct SegmentTreeChildren<M: Monoid + Clone> {
    head: SegmentTree<M>,
    tail: SegmentTree<M>
}

impl<M> SegmentTree<M> where M: Monoid + Clone {
    fn new(vec: &Vec<M>) -> SegmentTree<M> {
        SegmentTree::_build(vec, 0, vec.len())
    }

    fn mconcat(&self, i: usize, j: usize) -> M {
        if j <= self.start || self.end <=i {
            M::mempty()
        } else if i <= self.start && self.end <= j {
            self.value.clone()
        } else {
            match &self.children {
                &Some(ref children) => children.head.mconcat(i, j).mappend(&children.tail.mconcat(i, j)),
                &None => M::mempty()
            }
        }
    }

    fn update(&mut self, i: usize, m: M) {
        if let &mut Some(ref mut children) = &mut self.children {
            if i < children.head.end {
                children.head.update(i, m);
            } else {
                children.tail.update(i, m);
            }
            self.value = children.head.value.mappend(&children.tail.value);
        } else {
            self.value = m;
        }
    }

    fn _build(vec: &Vec<M>, start: usize, end: usize) -> SegmentTree<M> {
        if end <= start {
            SegmentTree{
                value: M::mempty(),
                start: start,
                end: end,
                children: None
            }
        } else if start+1 == end {
            SegmentTree {
                value: vec[start].clone(),
                start: start,
                end: end,
                children: None
            }
        } else {
            let mid = (start + end) / 2;
            let head = SegmentTree::_build(vec, start, mid);
            let tail = SegmentTree::_build(vec, mid, end);
            SegmentTree {
                value: head.value.mappend(&tail.value),
                start: start,
                end: end,
                children: Some(Box::new(
                    SegmentTreeChildren{
                        head: head,
                        tail: tail
                    }
                ))
            }
        }
    }
}

#[allow(dead_code)]
fn get_line() -> String {
    let mut s = String::new();
    match stdin().read_line(&mut s){
        Ok(_) => {s.trim().to_string()}
        Err(_) => String::new()
    }
}

#[allow(dead_code)]
fn get_vec<T: std::str::FromStr>() -> Vec<T> {
    let line = get_line();
    line.split_whitespace().filter_map(|x| x.parse().ok()).collect()
}

#[allow(dead_code)]
fn get_one<T: FromStr + Copy>() -> T {
    let v = get_vec();
    v[0]
}

#[allow(dead_code)]
fn get_pair<T: FromStr + Copy>() -> (T, T) {
    let v = get_vec();
    (v[0], v[1])
}

#[allow(dead_code)]
fn get_triple<T: FromStr + Copy>() -> (T, T, T) {
    let v = get_vec();
    (v[0], v[1], v[2])
}

#[allow(dead_code)]
fn get_chars() -> Vec<char> {
    get_line().chars().collect()
}

#[allow(dead_code)]
fn vec_min(xs: &Vec<i64>) -> i64 {
    xs.iter().map(|&x|x).fold(std::i64::MAX, std::cmp::min)
}

#[allow(dead_code)]
fn vec_max(xs: &Vec<i64>) -> i64 {
    xs.iter().map(|&x|x).fold(std::i64::MIN, std::cmp::max)
}

#[allow(dead_code)]
fn vec_sum(xs: &Vec<i64>) -> i64 {
    xs.iter().fold(0, |acc, &x| acc+x)
}


Measured memory_bytes: 18828