#include using namespace std; long long total_len(long long n) { long long res = 0; for (long long len = 1, l = 1; l <= n; len++) { long long r = min(n, l * 2 - 1); res += len * (r - l + 1); if (l > n / 2) break; l <<= 1; } return res; } int bit_length(int x) { return 32 - __builtin_clz((unsigned)x); } struct DLX { int nCol; vector L, R, U, D; vector col, row, sz; vector answer; DLX(int nCol, long long reserveNodes = 0) : nCol(nCol) { int base = nCol + 1; int cap = base + (int)min(reserveNodes, INT_MAX - base - 1); L.reserve(cap); R.reserve(cap); U.reserve(cap); D.reserve(cap); col.reserve(cap); row.reserve(cap); L.resize(nCol + 1); R.resize(nCol + 1); U.resize(nCol + 1); D.resize(nCol + 1); col.resize(nCol + 1); row.resize(nCol + 1, -1); sz.assign(nCol + 1, 0); for (int i = 0; i <= nCol; i++) { L[i] = i - 1; R[i] = i + 1; U[i] = D[i] = i; col[i] = i; } L[0] = nCol; R[nCol] = 0; } void add_node(int r, int c, int& first) { int id = (int)col.size(); L.push_back(id); R.push_back(id); U.push_back(0); D.push_back(0); col.push_back(c); row.push_back(r); U[id] = U[c]; D[id] = c; D[U[c]] = id; U[c] = id; sz[c]++; if (first == -1) { first = id; L[id] = R[id] = id; } else { R[id] = first; L[id] = L[first]; R[L[first]] = id; L[first] = id; } } void add_row(int r, const vector& cols) { int first = -1; for (int c : cols) { add_node(r, c, first); } } void cover(int c) { R[L[c]] = R[c]; L[R[c]] = L[c]; for (int i = D[c]; i != c; i = D[i]) { for (int j = R[i]; j != i; j = R[j]) { D[U[j]] = D[j]; U[D[j]] = U[j]; sz[col[j]]--; } } } void uncover(int c) { for (int i = U[c]; i != c; i = U[i]) { for (int j = L[i]; j != i; j = L[j]) { sz[col[j]]++; D[U[j]] = j; U[D[j]] = j; } } R[L[c]] = c; L[R[c]] = c; } bool solve() { if (R[0] == 0) return true; int c = R[0]; for (int j = R[c]; j != 0; j = R[j]) { if (sz[j] < sz[c]) { c = j; } } if (sz[c] == 0) return false; cover(c); for (int i = D[c]; i != c; i = D[i]) { answer.push_back(row[i]); for (int j = R[i]; j != i; j = R[j]) { cover(col[j]); } if (solve()) return true; for (int j = L[i]; j != i; j = L[j]) { uncover(col[j]); } answer.pop_back(); } uncover(c); return false; } }; struct RowInfo { int start; int len; int value; }; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); string C; cin >> C; int S = (int)C.size(); long long lo = 1, hi = 1; while (total_len(hi) < S) { hi <<= 1; } while (lo < hi) { long long mid = (lo + hi) / 2; if (total_len(mid) >= S) hi = mid; else lo = mid + 1; } if (total_len(lo) != S) { return 0; } int N = (int)lo; int M = bit_length(N); long long nodeCount = 0; for (int s = 0; s < S; s++) { if (C[s] != '1') continue; int v = 0; for (int len = 1; len <= M && s + len <= S; len++) { v = (v << 1) + (C[s + len - 1] - '0'); if (v > N) break; nodeCount += len + 1; } } // 列: // 1..N : 数字 // N+1..N+S : 文字位置 DLX dlx(N + S, nodeCount); vector rows; for (int s = 0; s < S; s++) { if (C[s] != '1') continue; int v = 0; vector cols; cols.reserve(M + 1); for (int len = 1; len <= M && s + len <= S; len++) { v = (v << 1) + (C[s + len - 1] - '0'); if (v > N) break; cols.clear(); // 数字 v を使う cols.push_back(v); // 文字位置 s..s+len-1 を覆う for (int p = s; p < s + len; p++) { cols.push_back(N + p + 1); } int id = (int)rows.size(); rows.push_back({s, len, v}); dlx.add_row(id, cols); } } if (!dlx.solve()) { return 0; } vector chosen; for (int id : dlx.answer) { chosen.push_back(rows[id]); } sort(chosen.begin(), chosen.end(), [](const RowInfo& a, const RowInfo& b) { return a.start < b.start; }); for (int i = 0; i < (int)chosen.size(); i++) { if (i) cout << ' '; cout << chosen[i].value; } cout << '\n'; return 0; }