package main

import (
	"fmt"
	"io"
	"log"
	"strconv"
	"strings"
)

var wires map[string]uint16

func main() {
	var input []string
	var bldInput string
	var readInp string
	for {
		_, err := fmt.Scan(&readInp)
		if err != nil {
			if err != io.EOF {
				log.Fatal(err)
			}
			break
		}
		if strings.HasSuffix(bldInput, "->") {
			bldInput = bldInput + " " + readInp
			input = append(input, bldInput)
			bldInput = ""
			continue
		}
		if len(bldInput) > 0 {
			bldInput += " "
		}
		bldInput = bldInput + readInp
	}

	wires = make(map[string]uint16)
	var done bool
	for !done {
		for i := range input {
			parsePts := strings.Split(input[i], " -> ")
			inputs := parsePts[0]
			output := parsePts[1]
			if _, ok := getValue(output); ok {
				// We've already done this one
				continue
			}
			// What's up with these inputs?
			inpParts := strings.Split(inputs, " ")
			if len(inpParts) == 1 {
				if val, ok := getValue(inpParts[0]); ok {
					setValue(output, val)
				} else {
					continue
				}
			} else if len(inpParts) == 2 {
				if val, ok := getValue(inpParts[1]); ok {
					setValue(output, ^val)
				} else {
					continue
				}
			} else {
				// All other gates
				var inp1, inp2 uint16
				if val, ok := getValue(inpParts[0]); ok {
					inp1 = val
				} else {
					continue
				}
				if val, ok := getValue(inpParts[2]); ok {
					inp2 = val
				} else {
					continue
				}

				if inpParts[1] == "RSHIFT" {
					setValue(output, (inp1 >> inp2))
				} else if inpParts[1] == "LSHIFT" {
					setValue(output, (inp1 << inp2))
				} else if inpParts[1] == "OR" {
					setValue(output, (inp1 | inp2))
				} else if inpParts[1] == "AND" {
					setValue(output, (inp1 & inp2))
				}
			}
			if len(wires) == len(input) {
				done = true
			}
		}

		if aWire, ok := wires["a"]; ok {
			fmt.Printf("\"a\" value: %d\n", aWire)
			done = true
		}
	}
}

func setValue(key string, val uint16) {
	wires[key] = val
}

func getValue(input string) (uint16, bool) {
	var ret uint16
	var i int
	var err error
	if i, err = strconv.Atoi(input); err != nil {
		if w, ok := wires[input]; ok {
			return w, true
		}
		return wires[input], false
	}
	ret = uint16(i)
	return ret, true
}