package main

import (
	"bufio"
	"fmt"
	"os"
	"strings"
)

const (
	MaxInt = int(^uint(0) >> 1)
	MinInt = -MaxInt - 1
)

var lastState string
var garden *Garden

func main() {
	inp := StdinToStringSlice()
	garden = NewGarden(strings.Trim(inp[0], "intalsae: "), 0)
	for _, v := range inp[2:] {
		garden.transitions = append(garden.transitions, NewTransition(v))
	}
	generations := 50000000000
	var i int
	for i = 0; i < generations; i++ {
		lastState = garden.string()
		garden = garden.tick()
		if garden.string() == lastState {
			i++
			break
		}
	}
	garden.shiftPots(generations - i)
	fmt.Println(garden.sum())
}

/**
 * A Garden
 */
type Garden struct {
	pots        []*Pot
	transitions []*Transition
}

func NewGarden(inp string, start int) *Garden {
	g := &Garden{}
	for k, v := range inp {
		p := &Pot{
			id:    k + start,
			value: rb(v),
		}
		g.pots = append(g.pots, p)
	}
	return g
}

func (g *Garden) shiftPots(val int) {
	for i := range g.pots {
		g.pots[i].id = g.pots[i].id + val
	}
}

func (g *Garden) sum() int64 {
	var ret int64
	st, ed := g.getStartIndex(), g.getEndIndex()
	for i := st; i <= ed; i++ {
		if g.getPot(i).value {
			ret += int64(i)
		}
	}
	return ret
}

func (g *Garden) tick() *Garden {
	earliest, latest := g.getStartIndex(), g.getEndIndex()
	st := earliest - 2
	ed := latest + 2
	ret := &Garden{
		transitions: g.transitions,
	}
	for i := st; i <= ed; i++ {
		next := g.getNextStateForPot(i)
		if next {
			ret.pots = append(ret.pots, &Pot{
				id:    i,
				value: next,
			})
		}
	}
	return ret
}

func (g *Garden) getNextStateForPot(id int) bool {
	var ret byte
	for i := id - 2; i <= id+2; i++ {
		ret = ret << 1
		if g.getPot(i).value {
			ret = ret | 1
		}
	}
	for _, v := range g.transitions {
		if v.GetValue() == ret {
			return v.next
		}
	}
	return false //g.getPot(id).value
}

func (g *Garden) substring(st, ed int) string {
	var ret string
	for i := st; i <= ed; i++ {
		ret += g.getPot(i).string()
	}
	return ret
}

func (g *Garden) string() string {
	var ret string
	for i := g.getStartIndex(); i <= g.getEndIndex(); i++ {
		ret += g.getPot(i).string()
	}
	return ret
}

func (g *Garden) transitionStrings() string {
	var ret string
	for _, v := range g.transitions {
		ret = ret + v.string() + "\n"
	}
	return ret
}

func (g *Garden) getStartIndex() int {
	min := MaxInt
	for _, v := range g.pots {
		if v.id < min {
			min = v.id
		}
	}
	return min
}

func (g *Garden) getEndIndex() int {
	max := MinInt
	for _, v := range g.pots {
		if v.id > max {
			max = v.id
		}
	}
	return max
}

func (g *Garden) getPot(idx int) *Pot {
	for _, v := range g.pots {
		if v.id == idx {
			return v
		}
	}
	return &Pot{
		id:    idx,
		value: false,
	}
}

/**
 * A Pot
 */
type Pot struct {
	id    int
	value bool
}

func (p *Pot) string() string {
	return bs(p.value)
}

/**
 * Transitions
 */
type Transition struct {
	state []bool
	next  bool
}

func NewTransition(inp string) *Transition {
	var state []bool
	var next bool
	pts := strings.Split(inp, " => ")
	for i := range pts[0] {
		state = append(state, bb(pts[0][i]))
	}
	//for i := len(pts[0]) - 1; i >= 0; i-- {
	//	state = append(state, bb(pts[0][i]))
	//}
	next = bb(pts[1][0])
	t := &Transition{
		state: state,
		next:  next,
	}
	return t
}

func (t *Transition) string() string {
	var ret string
	for _, v := range t.state {
		ret += bs(v)
	}
	return ret + " => " + bs(t.next)
}

func (t *Transition) GetValue() byte {
	var ret byte
	for _, v := range t.state {
		ret = ret << 1
		if v {
			ret = ret | 1
		}
	}
	return ret
}

/**
 * Helper Functions
 */

// Take a byte and return a string representation of the bits
func byteToString(b byte) string {
	var ret string
	for i := 0; i < 8; i++ {
		if b&1 == 1 {
			ret += "#"
		} else {
			ret += "."
		}
		b = b >> 1
	}
	return ret
}

// Take a string representation of a bits and return the byte
func stringToByte(n string) byte {
	var b byte
	for i := range n {
		if n[i] == '#' {
			b = b | 1
		}
		b = b << 1
	}
	return b
}

func bs(b bool) string {
	if b {
		return "#"
	}
	return "."
}

func rb(r rune) bool {
	return bb(byte(r))
}
func bb(b byte) bool {
	return b == '#'
}

func StdinToStringSlice() []string {
	var input []string
	scanner := bufio.NewScanner(os.Stdin)
	for scanner.Scan() {
		input = append(input, scanner.Text())
	}
	return input
}
