#!/usr/bin/env python3
import sys, random, time
N=int(sys.argv[1]); seed=int(sys.argv[2]) if len(sys.argv)>2 else 1
random.seed(seed)
spf=[0]*(N+1); primes=[]
for i in range(2,N+1):
    if spf[i]==0: spf[i]=i; primes.append(i)
    for p in primes:
        if p*i>N or p>spf[i]: break
        spf[p*i]=p
sign=[0]*(N+1); f=[0]*(N+1); pref=[0]*(N+1); tried=[0]*(N+1); fixed=[False]*(N+1)
sign[1]=1; f[1]=1; pref[1]=1
# optional walters first W
W=int(sys.argv[3]) if len(sys.argv)>3 else 0
for p in primes:
    if p<=W:
        fixed[p]=True
        sign[p]= 1 if p%3==1 else -1
n=2; steps=0; start=time.time(); back=0
while n<=N:
    steps+=1
    if spf[n]==n:
        if fixed[n]:
            choices=[sign[n]]
        else:
            S=pref[n-1]
            if S>=3: choices=[-1]
            elif S<=-3: choices=[1]
            elif S>0: choices=[-1,1]
            elif S<0: choices=[1,-1]
            else: choices=[1,-1] if random.getrandbits(1) else [-1,1]
        # select next not tried bit
        val=None
        for c in choices:
            bit=1 if c==1 else 2
            if not (tried[n]&bit): val=c; tried[n]|=bit; break
        if val is None:
            # reset and backtrack
            tried[n]=0; sign[n]=0; n-=1
            while n>=2 and (spf[n]!=n or fixed[n]):
                if spf[n]==n: tried[n]=0; sign[n]=0
                n-=1
            if n<2: print('unsat search'); sys.exit(1)
            back+=1
            continue
        sign[n]=val; f[n]=val
    else:
        p=spf[n]; f[n]=sign[p]*f[n//p]
    pref[n]=pref[n-1]+f[n]
    if abs(pref[n])>3:
        if spf[n]==n and not fixed[n]:
            # try other branch at same prime
            continue
        # backtrack to latest nonfixed prime
        n-=1
        while n>=2 and (spf[n]!=n or fixed[n]):
            if spf[n]==n: tried[n]=0; sign[n]=0
            n-=1
        if n<2: print('unsat search at viol'); sys.exit(1)
        back+=1
        continue
    n+=1
    if n%10000==0: print('n',n,'back',back,'steps',steps,'time',time.time()-start, flush=True)
print('ok',N,'back',back,'steps',steps,'time',time.time()-start)
open('/workspace/cms_bits.txt','w').write(''.join('1' if f[i]>0 else '0' for i in range(1,N+1)))
