#!/usr/bin/env python3

import sys, re

regs=[("initial_r%d" % i) for i in range(32)]
regs[0]="0" # r0 always has zero, as in MIPS

def dump_regs():
    global regs
    for reg in range(1, 32):
        if regs[reg] != f"initial_r{reg}":
            print (f"r{reg}", "=", rewrite(regs[reg]))

def regname_to_regno(reg):
    return int(reg.removeprefix("r").removesuffix(","))

def parse_addk(l):
    global regs
    tmp=l.split(" ")
    assert tmp[0]=="addk"
    dst=regname_to_regno(tmp[1])
    src1=regname_to_regno(tmp[2])
    src2=regname_to_regno(tmp[3])
    #print (dst, src1, src2)
    if src1==src2:
        regs[dst]=f"({regs[src1]}*2)"
    else:
        regs[dst]=f"({regs[src1]}+{regs[src2]})"

def parse_rsubk(l):
    global regs
    tmp=l.split(" ")
    assert tmp[0]=="rsubk"
    dst=regname_to_regno(tmp[1])
    src1=regname_to_regno(tmp[2])
    src2=regname_to_regno(tmp[3])
    #print (dst, src1, src2)
    regs[dst]=f"({regs[src2]}-{regs[src1]})"

# these regexp subexpressions are unusual a bit
# ?P<name> means that subexpression will have a name:
# https://docs.python.org/3/howto/regex.html#non-capturing-and-named-groups
# ? at the end means non-greedy regexp:
# https://docs.python.org/3/howto/regex.html#greedy-versus-non-greedy
# non-greedy regexps are used here because we want to find smallest possible subexpression
# default is greedy -- largest possible subexpression is to be found, but we don't want this
re_X= "(?P<X>[a-z0-9_]+?)"
re_X1="(?P<X1>[a-z0-9_]+?)"
re_X2="(?P<X2>[a-z0-9_]+?)"
re_N= "(?P<N>[0-9]+?)"
re_N1="(?P<N1>[0-9]+?)"
re_N2="(?P<N2>[0-9]+?)"

# ((X*N1)*N2) -> X*(N1+N2)
def rewrite_two_mul(s):
    x=re.compile("\\(\\("+re_X+"\\*"+re_N1+"\\)\\*"+re_N2+"\\)")
    m=x.search(s)
    if m==None:
        return s
    m_start, m_end = m.start(0), m.end(0)
    X=m.group("X")
    N1=int(m.group("N1"))
    N2=int(m.group("N2"))
    new_expr=f"({X}*{N1*N2})"
    rt=s[0:m_start]+new_expr+s[m_end:] # replace substring
    return rt

# test
assert rewrite_two_mul("((x*2)*2)")=="(x*4)"
assert rewrite_two_mul("y+((x*2)*2)+z")=="y+(x*4)+z"

# ((X*N)+X) -> X*(N+1)
def rewrite_1(s):
    x=re.compile("\\(\\("+re_X1+"\\*"+re_N+"\\)\\+"+re_X2+"\\)")
    m=x.search(s)
    if m==None:
        return s
    m_start, m_end = m.start(0), m.end(0)
    X1=m.group("X1")
    N=int(m.group("N"))
    X2=m.group("X2")
    if X1!=X2:
        return s # leave unchanged
    new_expr=f"({X1}*{N+1})"
    rt=s[0:m_start]+new_expr+s[m_end:] # replace substring
    return rt

assert rewrite_1("((x*2)+x)")=="(x*3)"

# (X+(X*N)) -> X*(N+1)
def rewrite_1_rvr(s):
    x=re.compile("\\("+re_X1+"\\+\\("+re_X2+"\\*"+re_N+"\\)\\)")
    m=x.search(s)
    if m==None:
        return s
    m_start, m_end = m.start(0), m.end(0)
    X1=m.group("X1")
    N=int(m.group("N"))
    X2=m.group("X2")
    if X1!=X2:
        return s # leave unchanged
    new_expr=f"({X1}*{N+1})"
    rt=s[0:m_start]+new_expr+s[m_end:] # replace substring
    return rt

assert rewrite_1_rvr("(x+(x*2))")=="(x*3)"

# ((X*N)-X) -> X*(N-1)
def rewrite_2(s):
    x=re.compile("\\(\\("+re_X1+"\\*"+re_N+"\\)\\-"+re_X2+"\\)")
    m=x.search(s)
    if m==None:
        return s
    m_start, m_end = m.start(0), m.end(0)
    X1=m.group("X1")
    N=int(m.group("N"))
    X2=m.group("X2")
    if X1!=X2:
        return s # leave unchanged
    new_expr=f"({X1}*{N-1})"
    rt=s[0:m_start]+new_expr+s[m_end:] # replace substring
    return rt

assert rewrite_2("((x*10)-x)")=="(x*9)"

# ((X*N1)+(X*N2)) -> X*(N1+N2)
def rewrite_3(s):
    x=re.compile("\\(\\("+re_X1+"\\*"+re_N1+"\\)\\+\\("+re_X2+"\\*"+re_N2+"\\)\\)")
    m=x.search(s)
    if m==None:
        return s
    m_start, m_end = m.start(0), m.end(0)
    X1=m.group("X1")
    N1=int(m.group("N1"))
    X2=m.group("X2")
    N2=int(m.group("N2"))
    if X1!=X2:
        return s # leave unchanged
    new_expr=f"({X1}*{N1+N2})"
    rt=s[0:m_start]+new_expr+s[m_end:] # replace substring
    return rt

assert rewrite_3("((x*10)+(x*15))")=="(x*25)"

# ((X*N1)-(X*N2)) -> X*(N1-N2)
def rewrite_4(s):
    x=re.compile("\\(\\("+re_X1+"\\*"+re_N1+"\\)\\-\\("+re_X2+"\\*"+re_N2+"\\)\\)")
    m=x.search(s)
    if m==None:
        return s
    m_start, m_end = m.start(0), m.end(0)
    X1=m.group("X1")
    N1=int(m.group("N1"))
    X2=m.group("X2")
    N2=int(m.group("N2"))
    if X1!=X2:
        return s # leave unchanged
    new_expr=f"({X1}*{N1-N2})"
    rt=s[0:m_start]+new_expr+s[m_end:] # replace substring
    return rt

assert rewrite_4("((x*16)-(x*10))")=="(x*6)"

def rewrite_one_step(s):
    s=rewrite_two_mul(s)
    s=rewrite_1(s)
    s=rewrite_1_rvr(s)
    s=rewrite_2(s)
    s=rewrite_3(s)
    s=rewrite_4(s)
    return s

def rewrite(s):
    #print (f"Before rewrite: {s}")
    while True:
        new_s=rewrite_one_step(s)
        if new_s==s:
            #print (f"After rewrite: {new_s}")
            return new_s
        s=new_s

for l in sys.stdin:
    l=l.rstrip()
    if l.startswith ("addk"):
        parse_addk(l)
    elif l.startswith ("rsubk"):
        parse_rsubk(l)
    else:
        print ("panic, can't parse: ", l)
        exit(0)
    print (f"state of registers after {l}:")
    dump_regs()

print ("final state of registers:")
dump_regs()

