#!/usr/bin/python2.6

from types import *

verbose = False

duel = True

class LtgException(Exception):
    def __init__(self,value):
        self.value = value

    def __str__(self):
        return "LTG exception: %s" % self.value

def check_integer(i):
    if type(i) != IntType:
        raise LtgException('integer expected')

def check_slot(i):
    check_integer(i)
    if i<0 or i>255:
        raise LtgException('slot number expected')

def check_string(s):
    if type(s) != StringType:
        raise LtgException('card function expected')

def check_function(f):
    if type(f) == IntType:
        raise LtgException('function expected %s found' % (f,))

def apply(f,x):
    if type(f) == StringType:
        return (f,x)
    if type(f) == TupleType:
        return f + (x,)
    raise LtgException('apply: not a function')

class Context:
    def __init__(self,game):
        self.proponent = game.player[game.turn].slot
        self.opponent = game.player[1-game.turn].slot
        self.count = 0
        self.zombie = False

    def increment(self):
        self.count += 1
        if self.count > 1000:
            raise LtgException('too many function applications')

    def eval_base(self,expr):
        if type(expr) == TupleType:
            if len(expr) == 1:
                if expr[0] == 'zero': return 0

            elif len(expr) == 2:
                
                if expr[0] == 'I':
                    self.increment()
                    return expr[1]

                if expr[0] == 'succ':
                    self.increment()
                    n = expr[1]
                    check_integer(n)
                    n += 1
                    if n > 65535:
                        n = 65535
                    return n

                if expr[0] == 'dbl':
                    self.increment()
                    n = expr[1]
                    check_integer(n)
                    n *= 2
                    if n > 65535: 
                        n = 65535
                    return n

                if expr[0] == 'get':
                    self.increment()
                    i = expr[1]
                    check_slot(i)
                    if self.proponent[i].vitality < 0:
                        raise LtgException('dead slot')
                    return self.proponent[i].field
                if expr[0] == 'put':
                    self.increment()
                    return 'I'

                if expr[0] == 'inc':
                    self.increment()
                    i = expr[1]
                    check_slot(i)
                    v=self.proponent[i].vitality
                    if v>0 and v<65535:
                        if self.zombie:
                            v = v - 1
                        else:
                            v = v + 1
                        self.proponent[i].vitality = v
                    return 'I'
                
                if expr[0] == 'dec':
                    self.increment()
                    i = expr[1]
                    check_slot(i)
                    v=self.opponent[255-i].vitality
                    if v>0:
                        if self.zombie:
                            if v < 65535:
                                v = v + 1 
                        else:
                            v = v - 1
                        self.opponent[255-i].vitality = v
                    return 'I'
                    
                if expr[0] == 'copy':
                    self.increment()
                    i = expr[1]
                    check_slot(i)
                    return self.opponent[i].field

                if expr[0] == 'revive':
                    self.increment()
                    i = expr[1]
                    check_slot(i)
                    v = self.proponent[i].vitality
                    if v <= 0:
                        self.proponent[i].vitality = 1
                    return 'I'

            elif len(expr) == 3:

                if expr[0] == 'K':
                    self.increment()
                    x = expr[1]
                    return x

                if expr[0] == 'zombie':
                    self.increment()
                    i = expr[1]
                    x = expr[2]
                    check_slot(i)
                    if self.opponent[255-i].vitality > 0:
                        raise LtgException('slot alive')
                    self.opponent[255-i].field = x
                    self.opponent[255-i].vitality = -1
                    return 'I'

            elif len(expr) == 4:

                if expr[0] == 'attack':
                    self.increment()
                    i = expr[1]
                    j = expr[2]
                    n = expr[3]
                    check_slot(i)
                    check_integer(n)
                    v = self.proponent[i].vitality
                    if n>v:
                        raise LtgException('n>v')
                    self.proponent[i].vitality = v - n
                    w = self.opponent[255-j].vitality
                    if w>0:
                        if self.zombie:
                            w = w + n*9/10
                            if w>65535:
                                w = 65535
                        else:
                            w = w - n*9/10
                            if w<0: w=0
                        self.opponent[255-j].vitality = w
                    return 'I'

                if expr[0] == 'help':
                    self.increment()
                    i = expr[1]
                    j = expr[2]
                    n = expr[3]
                    check_slot(i)
                    check_slot(j)
                    v = self.proponent[i].vitality
                    if n > v:
                        raise LtgException('n>v')
                    self.proponent[i].vitality = v - n
                    w = self.proponent[j].vitality
                    if w > 0:
                        if self.zombie:
                            w = w - n*11/10
                            if w < 0: 
                                w = 0
                        else:
                            w = w + n*11/10
                            if w>65535:
                                w=65535
                        self.proponent[j].vitality = w
                    return 'I'

                if expr[0] == 'S':
                    self.increment()
                    f = expr[1]
                    g = expr[2]
                    x = expr[3]
                    h = self.eval(apply(f,x))
                    y = self.eval(apply(g,x))
                    z = self.eval(apply(h,y))
                    return z
        return expr

    def eval(self,expr):
        if verbose:
            print "evaluating expr %s" % (expr,)
        try:
            r = self.eval_base(expr)
            if r == 'zero':
                r = 0
            if verbose:
                print "result: %s" % (r,)
            return r
        except LtgException as e:
            raise LtgException(e.value+(' in expr %s' % (expr,)))

    def zombie(self):
        self.zombie = True
        for i in range(256):
            if proponent[i].vitality == -1:
                pass
        self.zombie = False

class Slot:
    def __init__(self):
        self.field = 'I'
        self.vitality = 10000

    def __str__(self):
        return "{%d,%s}" % (self.vitality, self.field)

class Player:
    def __init__(self):
        self.slot=[ Slot() for x in range(256)]
        
    def __str__(self):
        s=[]
        for n in range(256):
            if self.slot[n].vitality != 10000 or self.slot[n].field != 'I':
                s.append("%d=%s" % (n,self.slot[n]))
        return ", ".join(s)

class Move:
    def __init__(self, mode, card, slot_no):
        self.mode = mode
        self.card = card
        self.slot_no = slot_no

    def __str__(self):
        return "[%d,%s,%d]\n" % (self.mode, self.card, self.slot_no)

    def output(self):
        from sys import stdout
        if self.mode == 1:
            print "1\n%s\n%d" % (self.card, self.slot_no)
        else:
            print "2\n%d\n%s" % (self.slot_no, self.card)
        stdout.flush()
            

def convert(expr):
    if type(expr)==IntType:
        if expr == 0:
            return 'zero'
        elif expr % 2 == 1:
            return ('succ', convert(expr-1))
        else:
            return ('dbl', convert(expr/2))
    if type(expr)==StringType:
        return expr
    if type(expr)!=TupleType:
        raise Exception('tuple expected in compose')
    if type(expr[-1]) == IntType:
        expr = expr[:-1] + ((convert(expr[-1])),)
    if type(expr[-1]) == TupleType:
        f = expr[:-1]
        g = expr[-1][:-1]
        if len(g)==1:
            g=g[0]
        x = expr[-1][-1]
        expr = ('S', ('K',)+f, g, x)
        return convert(expr)
    return expr

def compose(expr):
    if expr == 0:
        expr = 'zero'
        
    if type(expr) == StringType:
        return [
            ('I', (2,expr)),
            (None, (1,'put')), 
            ]
 
    if type(expr) == TupleType:
        if type(expr[-1]) == StringType:
            x= expr[:-1]
            if len(x) == 1:
                x = x[0]
            f=x
            if f == 'zero':
                f = 0
            l = [ (f, (2, expr[-1])) ]
            l += compose(x)
            return l
        if type(expr[0]) == StringType and len(expr)==2:
            x = expr[1:]
            if len(x) == 1:
                x = x[0]
            f=x
            if f == 'zero': 
                f = 0
            l = [ (f, (1,expr[0])) ]
            l += compose(x)
            return l
        
    raise Exception('cannot compose expr: %s' % (expr,))

class Game:
    def __init__(self):
        self.player = [Player(), Player()]
        self.turn = 0
        self.count = 0
        
    def play_move(self, move):
        context = Context(self)
        check_slot(move.slot_no)
        try:
            if context.proponent[move.slot_no].vitality <= 0:
                raise LtgException('dead slot')
            field = context.proponent[move.slot_no].field
            try:
                card = move.card
                if card == 'zero':
                    card = 0
                if move.mode == 1:
                    check_string(move.card)
                    expr = (card, field)
                    expr = context.eval(expr)
                elif move.mode == 2:
                    check_function(field)
                    if type(field) == StringType:
                        expr = (field, card)
                    else:
                        expr = field + (card,)
                    expr = context.eval(expr)
                else:
                    raise Exception('invalid move.mode=%d' % move.mode)
            except LtgException as e:
                if verbose:
                    print "ltgexception: %s in move %s" % (e,move)
                expr = 'I'
            context.proponent[move.slot_no].field = expr
        except LtgException as e:
            if verbose:
                print "ltgexception: %s in move %s" % (e,move)

        self.turn = 1 - self.turn
        self.count += 1
        if verbose:
            print "move: %d %s %d" % (move.mode, move.card, move.slot_no)
            print "Turn #%d/%d" % (self.count/2,self.turn)
            print "player[0]: %s" % self.player[0]
            print "player[1]: %s" % self.player[1]

    def input_move(self):
        while True:
            if verbose:
                print "write command"
            try:
                mode = int(raw_input())
                if mode == 1:
                    card = raw_input()
                    slot_no = int(raw_input())
                elif mode == 2:
                    slot_no = int(raw_input())
                    card = raw_input()
                else:
                    raise Exception('invalid move mode %s' % mode)
                return Move(mode,card,slot_no)
            except Exception:
                pass

    def play(self):
        if self.turn == 0:
            # my turn
            move = self.think_move()
            if duel:
                move.output();
        else:
            move = self.input_move()
        self.play_move(move)
        if self.count >= 2000000: return False
        return True
        
    def think_move(self):
        proponent = self.player[self.turn].slot
        opponent = self.player[1-self.turn].slot
        slot_no = 0
        l = [ None , (1, 'put')]
        if proponent[255-0].vitality>0:   
            l = compose(convert(('dec', 0)))
        elif proponent[255-1].vitality>0:
            l = compose(convert(('dec', 1)))
        field = proponent[slot_no].field
        for (f,m) in l:
            if field == f or f==None:
                if verbose:
                    print "found %s apply %d %s" % (f,m[0],m[1])
                return Move(m[0],m[1],slot_no)            
        return Move(1,'I',0)

def main():
    from sys import argv
    game = Game()
    for arg in argv[1:]:
       if arg == '0':
           game.turn = 0
       elif arg == '1':
           game.turn = 1
       elif arg == 'v':
           global verbose
           verbose=True
       else:
           raise Exception('invalid arg %s' % arg)
    while game.play():
        pass

if False:
    expr = ('dec', 2)
    converted = convert(expr)
    print "convert %s -> %s" % (expr,converted)
    print "compose %s : %s" % (converted,compose(converted))

if __name__ == "__main__":
    main()
