from itertools import *

def wsieve():       # wheel-sieve, by Will Ness.   ideone.com/trR9OI
    yield 11        # cf. ideone.com/WFv4f
    mults = {}      #     codereview.stackexchange.com/q/92365/9064
    ps = wsieve()   
    p = next(ps)       # 11
    psq = p*p          # 121
    D = dict( zip( accumulate( [0,       # where to start
                 2,4,2,4,6,2,6,4,2,4,6,6, 2,6,4,2,6,4,6,8,4,2,4,2,
                 4,8,6,4,6,2,4,6,2,6,6,4, 2,4,6,2,6,4,2,4,2,10,2,10] ),
                   count(0)))
    for c in accumulate( chain( [13], cycle( 
                [  4,2,4,6,2,6,4,2,4,6,6, 2,6,4,2,6,4,6,8,4,2,4,2,
                 4,8,6,4,6,2,4,6,2,6,6,4, 2,4,6,2,6,4,2,4,2,10,2,10,2] ))):
        if c in mults:
            wheel = mults.pop(c)  
        elif c < psq:              
            yield c ; continue   
        else:          # (c==psq)   
            p2=p*2   ;   p6=p*6   ;  p10=p*10 # map (p*) (roll wh from p) =
            p4=p*4   ;   p8=p*8               #  = roll (wh*p) from p*p
            wheel = accumulate( chain( [p*p], islice( cycle( 
                          [p2,p4,p2,p4,p6,p2,p6,p4,p2,p4,p6,p6,
                           p2,p6,p4,p2,p6,p4,p6,p8,p4,p2,p4,p2,
                           p4,p8,p6,p4,p6,p2,p4,p6,p2,p6,p6,p4,
                           p2,p4,p6,p2,p6,p4,p2,p4,p2,p10,p2,p10] ),
                          D[ (p-11) % 210 ], None )))
            p = next(ps) ; psq = p*p ; next(wheel)   # p*p
        for m in wheel: 
            if not m in mults: 
                break
        mults[m] = wheel
        
def primes(): 
	yield from (2, 3, 5, 7)
	yield from wsieve()  
                          
if True:                   
    n = 1000000  # ! 1.5x speedup vs nw1BQn: 1M 5.1/3.4  2M 10.88/7.2
    print(n) 
    print( list( islice( (p for p in primes() ), n-1, n+1)))   