Problem p02739 (python)

Fixed submission:
import sys
from heapq import *

def first_1(x):
  if x:
    i = 0
    while x & 1 == 0:
      x >>= 1
      i += 1
    return i

def sep_single(s):
  if s:
    r = 1 << (s.bit_length()-1)
    i = s.bit_length()-1
    while s:
      if r & s:
        yield -i, r
        s ^= r
      r >>= 1
      i -= 1

def prepare_to_right(g, x):
  x0, y0 = g[-1]
  if x0 < x and y0:
    y0 = 0
    g.append((x0, 0))
  while x0 < x:
    x0 += 1
    g.append((x0, 0))

def prepare_to_left(g, x):
  x0, y0 = g[-1]
  if x+1 < x0 and y0:
    y0 = 0
    g.append((x0, 0))
  while x+1 < x0:
    x0 -= 1
    g.append((x0, 0))

def append_to_right(g, x, y):
  prepare_to_right(g, x)
  x0, y0 = g[-1]
  if y != y0:
    g.append((x, y))
  g.append((x+1, y))

def subloop_tp_group(g):
  x = 0
  while g&1 == 0:
    g >>= 1
    x += 1
  loop = [(x+1, 0)]
  tail = [(x, 0), (x, 1), (x+1, 1)]
  g >>= 1
  x += 1
  while g:
    while g&1==0:
      g >>= 1
      x += 1
    prepare_to_right(loop, x)
    prepare_to_right(tail, x)
    rev = reversed(loop)
    append_to_right(loop, x, 1)
    loop.append((x+1, 0))
    loop.extend(rev)
    loop.extend(tail)
    append_to_right(loop, x, 0)
    append_to_right(tail, x, 1)
    g >>= 1
    x += 1
  loop.extend(reversed(tail))
  return loop

N = int(input())

single = 0
tpg = []
for i in range(1<<N):
  a = int(sys.stdin.read(1))
  if bin(i).count("1") == 1:
    if a == 0:
      single |= i
  else:
    b = i & single
    if i and b | a == 0 and all(p & i != p for n, p in tpg):
      heappush(tpg, (-first_1(i), i))
    elif i | a == 0 or a and (b or any(p & i == p for n, p in tpg)):
      print("Impossible")
      break
else:
  print("Possible")
  loop = []
  for n, g in merge(sep_single(single), nsmallest(len(tpg),tpg)):
    subloop = subloop_tp_group(g)
    if loop:
      prepare_to_left(loop, subloop[0][0])
      if loop[-1] == subloop[0]:
        loop.pop()
    loop.extend(subloop)
  
  if not loop:
    loop.append((0, 0))
  prepare_to_right(loop, loop[0][0])
  
  print(len(loop)-1)
  for p in loop:
    print(*p)

Buggy submission (verdict: Runtime Error):
import sys
from heapq import *

def first_1(x):
  if x:
    i = 0
    while x & 1 == 0:
      x >>= 1
      i += 1
    return i

def sep_single(s):
  if s:
    r = 1 << (s.bit_length()-1)
    i = s.bit_length()-1
    while s:
      if r & s:
        yield -i, r
        s ^= r
      r >>= 1
      i -= 1

def prepare_to_right(g, x):
  x0, y0 = g[-1]
  if x0 < x and y0:
    y0 = 0
    g.append((x0, 0))
  while x0 < x:
    x0 += 1
    g.append((x0, 0))

def prepare_to_left(g, x):
  x0, y0 = g[-1]
  if x+1 < x0 and y0:
    y0 = 0
    g.append((x0, 0))
  while x+1 < x0:
    x0 -= 1
    g.append((x0, 0))

def append_to_right(g, x, y):
  prepare_to_right(g, x)
  x0, y0 = g[-1]
  if y != y0:
    g.append((x, y))
  g.append((x+1, y))

def subloop_tp_group(g):
  x = 0
  while g&1 == 0:
   g >>= 1
   x += 1
  loop = [(x+1, 0)]
  tail = [(x, 0), (x, 1), (x+1, 1)]
  g >>= 1
  x += 1
  while g:
    while g&1==0:
      g >>= 1
      x += 1
    prepare_to_right(loop, x)
    prepare_to_right(tail, x)
    rev = reversed(loop)
    append_to_right(loop, x, 1)
    loop.append((x+1, 0))
    loop.extend(rev)
    loop.extend(tail)
    append_to_right(loop, x, 0)
    append_to_right(tail, x, 1)
    g >>= 1
    x += 1
  loop.extend(reversed(tail))
  return loop

N = int(input())

single = 0
tpg = []
for i in range(1<<N):
  a = int(sys.stdin.read(1))
  if bin(i).count("1") == 1:
    if a == 0:
      single |= i
  else:
    b = i & single
    if i and b | a == 0 and all(p & i != p for n, p in tpg):
      heappush(tpg, (-first_1(i), i))
    elif i | a == 0 or a and (b or any(p & i == p for n, p in tpg)):
      print("Impossible")
      break
else:
  raise
  print("Possible")
  loop = []
  for n, g in merge(sep_single(single), tpg):
    subloop = subloop_tp_group(g)
    if loop:
      prepare_to_left(loop, subloop[0][0])
      if loop[-1] == subloop[0]:
        loop.pop()
    loop.extend(subloop)
  
  if not loop:
    loop.append((0, 0))
  prepare_to_right(loop, loop[0][0])
  
  print(len(loop)-1)
  for p in loop:
    print(*p)

Buggy submission (verdict: Runtime Error):
import sys
N = int(input())

on = 0
for i in range(1<<N):
  a = int(sys.stdin.read(1))
  if bin(i).count("1") == 1 and not a:
    on |= i
  if not a ^ bool(i & on):
    print("Impossible")
    break
else:
  raise ValueError