from __future__ import print_function
import sys, struct, shlex, operator

nd_Ident, nd_String, nd_Integer, nd_Sequence, nd_If, nd_Prtc, nd_Prts, nd_Prti, nd_While, \
nd_Assign, nd_Negate, nd_Not, nd_Mul, nd_Div, nd_Mod, nd_Add, nd_Sub, nd_Lss, nd_Leq,     \
nd_Gtr, nd_Geq, nd_Eql, nd_Neq, nd_And, nd_Or = range(25)

all_syms = {
     : nd_Ident,         : nd_String,
        : nd_Integer,     : nd_Sequence,
             : nd_If,              : nd_Prtc,
           : nd_Prts,            : nd_Prti,
          : nd_While,         : nd_Assign,
         : nd_Negate,           : nd_Not,
       : nd_Mul,           : nd_Div,
            : nd_Mod,              : nd_Add,
       : nd_Sub,             : nd_Lss,
      : nd_Leq,          : nd_Gtr,
    : nd_Geq,            : nd_Eql,
       : nd_Neq,              : nd_And,
             : nd_Or}

FETCH, STORE, PUSH, ADD, SUB, MUL, DIV, MOD, LT, GT, LE, GE, EQ, NE, AND, OR, NEG, NOT, \
JMP, JZ, PRTC, PRTS, PRTI, HALT = range(24)

operators = {nd_Lss: LT, nd_Gtr: GT, nd_Leq: LE, nd_Geq: GE, nd_Eql: EQ, nd_Neq: NE,
    nd_And: AND, nd_Or: OR, nd_Sub: SUB, nd_Add: ADD, nd_Div: DIV, nd_Mul: MUL, nd_Mod: MOD}

unary_operators = {nd_Negate: NEG, nd_Not: NOT}

input_file  = None
code        = bytearray()
string_pool = {}
globals     = {}
string_n    = 0
globals_n   = 0
word_size   = 4


def error(msg):
    print(% (msg))
    exit(1)

def int_to_bytes(val):
    return struct.pack(, val)

def bytes_to_int(bstr):
    return struct.unpack(, bstr)

class Node:
    def __init__(self, node_type, left = None, right = None, value = None):
        self.node_type  = node_type
        self.left  = left
        self.right = right
        self.value = value


def make_node(oper, left, right = None):
    return Node(oper, left, right)


def make_leaf(oper, n):
    return Node(oper, value = n)


def emit_byte(x):
    code.append(x)


def emit_word(x):
    s = int_to_bytes(x)
    for x in s:
        code.append(x)

def emit_word_at(at, n):
    code[at:at+word_size] = int_to_bytes(n)

def hole():
    t = len(code)
    emit_word(0)
    return t


def fetch_var_offset(name):
    global globals_n

    n = globals.get(name, None)
    if n == None:
        globals[name] = globals_n
        n = globals_n
        globals_n += 1
    return n


def fetch_string_offset(the_string):
    global string_n

    n = string_pool.get(the_string, None)
    if n == None:
        string_pool[the_string] = string_n
        n = string_n
        string_n += 1
    return n


def code_gen(x):
    if x == None: return
    elif x.node_type == nd_Ident:
        emit_byte(FETCH)
        n = fetch_var_offset(x.value)
        emit_word(n)
    elif x.node_type == nd_Integer:
        emit_byte(PUSH)
        emit_word(x.value)
    elif x.node_type == nd_String:
        emit_byte(PUSH)
        n = fetch_string_offset(x.value)
        emit_word(n)
    elif x.node_type == nd_Assign:
        n = fetch_var_offset(x.left.value)
        code_gen(x.right)
        emit_byte(STORE)
        emit_word(n)
    elif x.node_type == nd_If:
        code_gen(x.left)              
        emit_byte(JZ)                 
        p1 = hole()                   
        code_gen(x.right.left)        
        if (x.right.right != None):
            emit_byte(JMP)            
            p2 = hole()
        emit_word_at(p1, len(code) - p1)
        if (x.right.right != None):
            code_gen(x.right.right)   
            emit_word_at(p2, len(code) - p2)
    elif x.node_type == nd_While:
        p1 = len(code)
        code_gen(x.left)
        emit_byte(JZ)
        p2 = hole()
        code_gen(x.right)
        emit_byte(JMP)                       
        emit_word(p1 - len(code))
        emit_word_at(p2, len(code) - p2)
    elif x.node_type == nd_Sequence:
        code_gen(x.left)
        code_gen(x.right)
    elif x.node_type == nd_Prtc:
        code_gen(x.left)
        emit_byte(PRTC)
    elif x.node_type == nd_Prti:
        code_gen(x.left)
        emit_byte(PRTI)
    elif x.node_type == nd_Prts:
        code_gen(x.left)
        emit_byte(PRTS)
    elif x.node_type in operators:
        code_gen(x.left)
        code_gen(x.right)
        emit_byte(operators[x.node_type])
    elif x.node_type in unary_operators:
        code_gen(x.left)
        emit_byte(unary_operators[x.node_type])
    else:
        error(% (x.node_type))


def code_finish():
    emit_byte(HALT)


def list_code():
    print(% (len(globals), len(string_pool)))

    for k in sorted(string_pool, key=string_pool.get):
        print(k)

    pc = 0
    while pc < len(code):
        print(% (pc), end='')
        op = code[pc]
        pc += 1
        if op == FETCH:
            x = bytes_to_int(code[pc:pc+word_size])[0]
            print(% (x));
            pc += word_size
        elif op == STORE:
            x = bytes_to_int(code[pc:pc+word_size])[0]
            print(% (x));
            pc += word_size
        elif op == PUSH:
            x = bytes_to_int(code[pc:pc+word_size])[0]
            print(% (x));
            pc += word_size
        elif op == ADD:   print()
        elif op == SUB:   print()
        elif op == MUL:   print()
        elif op == DIV:   print()
        elif op == MOD:   print()
        elif op == LT:    print()
        elif op == GT:    print()
        elif op == LE:    print()
        elif op == GE:    print()
        elif op == EQ:    print()
        elif op == NE:    print()
        elif op == AND:   print()
        elif op == OR:    print()
        elif op == NEG:   print()
        elif op == NOT:   print()
        elif op == JMP:
            x = bytes_to_int(code[pc:pc+word_size])[0]
            print(% (x, pc + x));
            pc += word_size
        elif op == JZ:
            x = bytes_to_int(code[pc:pc+word_size])[0]
            print(% (x, pc + x));
            pc += word_size
        elif op == PRTC:  print()
        elif op == PRTI:  print()
        elif op == PRTS:  print()
        elif op == HALT:  print()
        else: error(, (op));

def load_ast():
    line = input_file.readline()
    line_list = shlex.split(line, False, False)

    text = line_list[0]
    if text == :
        return None
    node_type = all_syms[text]

    if len(line_list) > 1:
        value = line_list[1]
        if value.isdigit():
            value = int(value)
        return make_leaf(node_type, value)

    left = load_ast()
    right = load_ast()
    return make_node(node_type, left, right)


input_file = sys.stdin
if len(sys.argv) > 1:
    try:
        input_file = open(sys.argv[1], , 4096)
    except IOError as e:
        error(% sys.argv[1])

n = load_ast()
code_gen(n)
code_finish()
list_code()