← Home
package main

import (
	"bufio"
	"fmt"
	"math"
	"math/rand"
	"os"
	"sort"
)

func main() {
	reader := bufio.NewReader(os.Stdin)
	n := 5000

	ans := make([]int, n)
	for i := 0; i < n; i++ {
		ans[i] = rand.Intn(2)
	}

	S := query(ans, reader)
	if S == n+1 {
		return
	}

	p := make([]float64, n)
	for i := 0; i < n; i++ {
		p[i] = 0.5
	}

	K := 45

	type Item struct {
		idx  int
		diff float64
	}

	for step := 1; step <= 98; step++ {
		if S == n+1 {
			return
		}

		items := make([]Item, 0, S-1)
		for i := 0; i < S-1; i++ {
			items = append(items, Item{i, math.Abs(p[i] - 0.5)})
		}
		sort.Slice(items, func(i, j int) bool {
			return items[i].diff < items[j].diff
		})

		A := make([]int, 0, K)
		for i := 0; i < K && i < len(items); i++ {
			A = append(A, items[i].idx)
		}

		new_ans := make([]int, n)
		copy(new_ans, ans)
		for _, idx := range A {
			new_ans[idx] = 1 - new_ans[idx]
		}
		new_ans[S-1] = 1 - new_ans[S-1]

		S_new := query(new_ans, reader)
		if S_new == n+1 {
			return
		}

		D_raw := S_new - S

		var A_eff []int
		var W_obs float64
		var noise_V float64

		if D_raw > 0 {
			A_eff = A
			W_obs = float64(len(A))/2.0 + float64(D_raw-1)/4.0
			noise_V = float64(D_raw-1) / 16.0
		} else {
			for _, idx := range A {
				if idx < S_new {
					A_eff = append(A_eff, idx)
				}
			}
			D_abs := -D_raw
			W_obs = float64(len(A_eff)-1)/2.0 - float64(D_abs-1)/4.0
			noise_V = float64(D_abs-1) / 16.0
		}

		if noise_V < 1e-6 {
			noise_V = 1e-6
		}

		mu := 0.0
		v := 0.0
		for _, idx := range A_eff {
			mu += p[idx]
			v += p[idx] * (1.0 - p[idx])
		}

		new_p := make(map[int]float64)
		for _, idx := range A_eff {
			mu_minus := mu - p[idx]
			v_minus := v - p[idx]*(1.0-p[idx])

			V := v_minus + noise_V + 1e-6

			diff1 := W_obs - 1.0 - mu_minus
			diff0 := W_obs - 0.0 - mu_minus

			L1 := math.Exp(-(diff1 * diff1) / (2.0 * V))
			L0 := math.Exp(-(diff0 * diff0) / (2.0 * V))

			p1 := p[idx] * L1
			p0 := (1.0 - p[idx]) * L0

			var p_up float64
			if p1+p0 == 0 {
				p_up = p[idx]
			} else {
				p_up = p1 / (p1 + p0)
			}

			if p_up < 0.001 {
				p_up = 0.001
			}
			if p_up > 0.999 {
				p_up = 0.999
			}

			new_p[idx] = p_up
		}

		if S_new > S {
			ans = new_ans
			S_old := S
			S = S_new
			for _, idx := range A_eff {
				p[idx] = 1.0 - new_p[idx]
			}
			p[S_old-1] = 0.0
		} else {
			for _, idx := range A_eff {
				p[idx] = new_p[idx]
			}
			p[S-1] = 1.0
		}
	}

	final_ans := make([]int, n)
	copy(final_ans, ans)
	for i := 0; i < S-1; i++ {
		if p[i] > 0.5 {
			final_ans[i] = 1 - final_ans[i]
		}
	}
	final_ans[S-1] = 1 - final_ans[S-1]
	query(final_ans, reader)
}

func query(ans []int, reader *bufio.Reader) int {
	out := make([]byte, len(ans)+1)
	for i, v := range ans {
		if v == 1 {
			out[i] = '1'
		} else {
			out[i] = '0'
		}
	}
	out[len(ans)] = '\n'
	os.Stdout.Write(out)
	os.Stdout.Sync()

	var res int
	fmt.Fscan(reader, &res)
	return res
}