package main
import (
"bufio"
"fmt"
"os"
"strings"
)
type Node struct {
leaf bool
name string
op byte
l int
r int
}
type OpKey struct {
op byte
l int
r int
}
func main() {
in := bufio.NewReader(os.Stdin)
out := bufio.NewWriter(os.Stdout)
defer out.Flush()
var n int
fmt.Fscan(in, &n)
nodes := make([]Node, 0, 2*n+10)
leafID := make(map[string]int)
opID := make(map[OpKey]int)
var getLeaf func(string) int
getLeaf = func(name string) int {
if id, ok := leafID[name]; ok {
return id
}
id := len(nodes)
nodes = append(nodes, Node{leaf: true, name: name})
leafID[name] = id
return id
}
getOp := func(op byte, l, r int) int {
key := OpKey{op: op, l: l, r: r}
if id, ok := opID[key]; ok {
return id
}
id := len(nodes)
nodes = append(nodes, Node{op: op, l: l, r: r})
opID[key] = id
return id
}
curTerm := make(map[string]int)
var cur func(string) int
cur = func(name string) int {
if id, ok := curTerm[name]; ok {
return id
}
id := getLeaf(name)
curTerm[name] = id
return id
}
used := make(map[string]bool)
used["res"] = true
for i := 0; i < n; i++ {
var line string
fmt.Fscan(in, &line)
eq := strings.IndexByte(line, '=')
lhs := line[:eq]
rhs := line[eq+1:]
used[lhs] = true
pos := strings.IndexAny(rhs, "$^#&")
if pos == -1 {
used[rhs] = true
curTerm[lhs] = cur(rhs)
} else {
a := rhs[:pos]
op := rhs[pos]
b := rhs[pos+1:]
used[a] = true
used[b] = true
curTerm[lhs] = getOp(op, cur(a), cur(b))
}
}
root := cur("res")
if nodes[root].leaf {
if nodes[root].name == "res" {
fmt.Fprintln(out, 0)
} else {
fmt.Fprintln(out, 1)
fmt.Fprintf(out, "res=%s\n", nodes[root].name)
}
return
}
chars := []byte("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
tempCount := 0
nextTemp := func() string {
for {
x := tempCount
tempCount++
a := chars[(x/(62*62))%62]
b := chars[(x/62)%62]
c := chars[x%62]
name := string([]byte{'Z', a, b, c})
if !used[name] {
used[name] = true
return name
}
}
}
dest := make([]string, len(nodes))
visited := make([]bool, len(nodes))
lines := make([]string, 0, len(nodes))
dest[root] = "res"
var nameOf func(int) string
nameOf = func(id int) string {
if nodes[id].leaf {
return nodes[id].name
}
return dest[id]
}
var dfs func(int)
dfs = func(id int) {
if nodes[id].leaf || visited[id] {
return
}
dfs(nodes[id].l)
dfs(nodes[id].r)
if dest[id] == "" {
dest[id] = nextTemp()
}
lines = append(lines, fmt.Sprintf("%s=%s%c%s", dest[id], nameOf(nodes[id].l), nodes[id].op, nameOf(nodes[id].r)))
visited[id] = true
}
dfs(root)
fmt.Fprintln(out, len(lines))
for _, line := range lines {
fmt.Fprintln(out, line)
}
}