#!/usr/bin/env python3
import math
import random
import sys

'''
This generator picks a specific value of k, and then generates A in such a way that k falls 
just around the threshold where it's possible to do it: we will either have enough large 
chunks of toppings for k cakes or just for k-1. This should guarantee at least one 
transition from YES to NO.

And it seems that it generally produces multiple, because e.g. around k' = threshold_k/2
we are using chunks of ingredients that are roughly twice as big => there number of chunks
is roughly halved => it's again somewhere around k'.
'''

def logrand(lo, hi):
    while True:
        b = random.randint(1, 31)
        x = random.randint(2**(b-1), (2**b)-1)
        if lo <= x <= hi: return x

def attempt(N, Q, maxA, maxK, tmt=None, threshold_ok=None,min_v=None):
    
    As = [ random.randint( max(1,int(0.97*maxA)), maxA )  ]

    if tmt is not None:
        threshold_min_tastiness = tmt
    elif random.randint(0,1):
        threshold_min_tastiness = logrand( 2, int(math.sqrt(As[0]))-1 )
    else:
        threshold_min_tastiness = random.randint( 2, int(math.sqrt(As[0]))-1 )

    if threshold_ok is None:
        threshold_ok = random.randint(0, 1)
    
    if min_v is None:
        min_v = 1

    candidate_ks = [ k for k in range(1, As[0]//min_v) if (As[0] + k - 1) // k == threshold_min_tastiness ]
    if not candidate_ks: return None  # retry: chosen threshold_min_tastiness is too small for given min_v
    threshold_k = random.choice(candidate_ks)
    min_tastiness = threshold_min_tastiness
    print(f'chosen A0 = {As[0]}, threshold_k = {threshold_k}, min_tastiness = {min_tastiness}', file=sys.stderr)
    
    Ks = set([threshold_k-1, threshold_k, threshold_k+1])
    if Q < 3: Ks = set([threshold_k])
    while len(Ks) < Q: Ks.add( logrand(1, maxK) )
    Ks = list(sorted(Ks))

    possible_pieces = As[0] // min_tastiness
    while len(As) < N and possible_pieces < threshold_k:
        As.append( random.randint(threshold_k, As[0]-1) )
        possible_pieces += As[-1] // min_tastiness
    print(f'end of phase1: len(A) = {len(As)}, possible_pieces = {possible_pieces}', file=sys.stderr)

    if len(As) == N and possible_pieces < threshold_k: return None # retry :P
    possible_pieces -= As[-1] // min_tastiness
    As.pop()
    remains = threshold_k - possible_pieces - (1-threshold_ok)
    As.append( random.randint(remains*min_tastiness, remains*min_tastiness+min_tastiness-1) )
    possible_pieces += As[-1] // min_tastiness
    print(f'end of phase1: len(A) = {len(As)}, possible_pieces = {possible_pieces}', file=sys.stderr)

    while len(As) < N: As.append( random.randint(1, min_tastiness-1) )
    return (As, Ks)

if __name__ == '__main__':
    N = int(sys.argv[1])
    Q = int(sys.argv[2])
    maxA = int(sys.argv[3])
    maxK = int(sys.argv[4])
    seed = int(sys.argv[5])
    
    try:
        tmt = int(sys.argv[6])
    except:
        tmt = None
    
    try:
        threshold_ok = int(sys.argv[7])
    except:
        threshold_ok = None

    try:
        min_v = int(sys.argv[8])
    except:
        min_v = None

    assert maxK >= maxA >= 1000

    random.seed(seed)
    while True:
        testcase = attempt(N, Q, maxA, maxK, tmt, threshold_ok,min_v)
        if testcase: break

    A, K = testcase
    random.shuffle(A)
    random.shuffle(K)
    print(N, Q)
    print(*A)
    for k in K: print(k)

