← Home
package main

import (
	"fmt"
	"io"
	"os"
)

const (
	nodeNum = iota
	nodeVar
	nodeCall
	nodeAdd
	nodeSub
	nodeMul
	nodeDiv
)

const (
	cmpLt = iota
	cmpGt
	cmpEq
)

type Expr struct {
	kind       int
	val        int
	left, right *Expr
}

type Cond struct {
	op         int
	left, right *Expr
}

type Stmt struct {
	hasCond bool
	cond    *Cond
	expr    *Expr
}

type Parser struct {
	s   string
	pos int
}

func isSpace(c byte) bool {
	return c == ' ' || c == '\n' || c == '\r' || c == '\t'
}

func isDigit(c byte) bool {
	return c >= '0' && c <= '9'
}

func (p *Parser) skip() {
	for p.pos < len(p.s) && isSpace(p.s[p.pos]) {
		p.pos++
	}
}

func (p *Parser) peek() byte {
	p.skip()
	if p.pos >= len(p.s) {
		return 0
	}
	return p.s[p.pos]
}

func (p *Parser) accept(t string) bool {
	p.skip()
	if p.pos+len(t) > len(p.s) {
		return false
	}
	if p.s[p.pos:p.pos+len(t)] == t {
		p.pos += len(t)
		return true
	}
	return false
}

func (p *Parser) expect(t string) {
	if !p.accept(t) {
		panic("parse error")
	}
}

func (p *Parser) parseNumber() *Expr {
	p.skip()
	val := 0
	for p.pos < len(p.s) && isDigit(p.s[p.pos]) {
		val = val*10 + int(p.s[p.pos]-'0')
		p.pos++
	}
	return &Expr{kind: nodeNum, val: val}
}

func (p *Parser) parseMultiplier() *Expr {
	p.skip()
	c := p.peek()
	if isDigit(c) {
		return p.parseNumber()
	}
	if c == 'n' {
		p.pos++
		return &Expr{kind: nodeVar}
	}
	if c == 'f' {
		p.pos++
		p.expect("(")
		arg := p.parseExpr()
		p.expect(")")
		return &Expr{kind: nodeCall, left: arg}
	}
	panic("parse error")
}

func (p *Parser) parseProduct() *Expr {
	node := p.parseMultiplier()
	for {
		p.skip()
		if p.accept("*") {
			right := p.parseMultiplier()
			node = &Expr{kind: nodeMul, left: node, right: right}
		} else if p.accept("/") {
			right := p.parseMultiplier()
			node = &Expr{kind: nodeDiv, left: node, right: right}
		} else {
			break
		}
	}
	return node
}

func (p *Parser) parseExpr() *Expr {
	node := p.parseProduct()
	for {
		p.skip()
		if p.accept("+") {
			right := p.parseProduct()
			node = &Expr{kind: nodeAdd, left: node, right: right}
		} else if p.accept("-") {
			right := p.parseProduct()
			node = &Expr{kind: nodeSub, left: node, right: right}
		} else {
			break
		}
	}
	return node
}

func (p *Parser) parseCond() *Cond {
	left := p.parseExpr()
	var op int
	if p.accept("==") {
		op = cmpEq
	} else if p.accept(">") {
		op = cmpGt
	} else if p.accept("<") {
		op = cmpLt
	} else {
		panic("parse error")
	}
	right := p.parseExpr()
	return &Cond{op: op, left: left, right: right}
}

func (p *Parser) parseStmt() Stmt {
	if p.accept("if") {
		p.expect("(")
		cond := p.parseCond()
		p.expect(")")
		p.expect("return")
		expr := p.parseExpr()
		p.expect(";")
		return Stmt{hasCond: true, cond: cond, expr: expr}
	}
	p.expect("return")
	expr := p.parseExpr()
	p.expect(";")
	return Stmt{expr: expr}
}

func (p *Parser) parseFunction() []Stmt {
	p.expect("int")
	p.expect("f")
	p.expect("(")
	p.expect("int")
	p.expect("n")
	p.expect(")")
	p.expect("{")
	var stmts []Stmt
	for {
		p.skip()
		if p.peek() == '}' {
			break
		}
		stmts = append(stmts, p.parseStmt())
	}
	p.expect("}")
	return stmts
}

func evalExpr(e *Expr, n int, fvals []int) int {
	switch e.kind {
	case nodeNum:
		return e.val
	case nodeVar:
		return n
	case nodeCall:
		arg := evalExpr(e.left, n, fvals)
		return fvals[arg]
	case nodeAdd:
		return (evalExpr(e.left, n, fvals) + evalExpr(e.right, n, fvals)) & 32767
	case nodeSub:
		return (evalExpr(e.left, n, fvals) - evalExpr(e.right, n, fvals)) & 32767
	case nodeMul:
		return (evalExpr(e.left, n, fvals) * evalExpr(e.right, n, fvals)) & 32767
	case nodeDiv:
		return evalExpr(e.left, n, fvals) / evalExpr(e.right, n, fvals)
	}
	return 0
}

func evalCond(c *Cond, n int, fvals []int) bool {
	a := evalExpr(c.left, n, fvals)
	b := evalExpr(c.right, n, fvals)
	switch c.op {
	case cmpLt:
		return a < b
	case cmpGt:
		return a > b
	case cmpEq:
		return a == b
	}
	return false
}

func evalFunction(stmts []Stmt, n int, fvals []int) int {
	for _, st := range stmts {
		if !st.hasCond || evalCond(st.cond, n, fvals) {
			return evalExpr(st.expr, n, fvals)
		}
	}
	return 0
}

func main() {
	data, _ := io.ReadAll(os.Stdin)
	s := string(data)
	i := 0
	for i < len(s) && isSpace(s[i]) {
		i++
	}
	target := 0
	for i < len(s) && isDigit(s[i]) {
		target = target*10 + int(s[i]-'0')
		i++
	}
	p := Parser{s: s[i:]}
	stmts := p.parseFunction()

	fvals := make([]int, 32768)
	for n := 0; n < 32768; n++ {
		fvals[n] = evalFunction(stmts, n, fvals)
	}

	ans := -1
	for n := 32767; n >= 0; n-- {
		if fvals[n] == target {
			ans = n
			break
		}
	}
	fmt.Print(ans)
}