package main

import (
	"bufio"
	"os"
	"strconv"
	"fmt"
)

type node struct {
	children  [] int
	queryType int
	r         int
	c         int
	k         int
	i         int
	ans       int
}

var library [][]bool
var graph []*node
var n, m, q int

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	scanner.Split(bufio.ScanWords)
	n, m, q = readInt(scanner), readInt(scanner), readInt(scanner)

	library = make([][]bool, n)
	for i, _ := range library {
		library[i] = make([]bool, m)
	}

	graph = make([]*node, q+1)
	temp := node{}
	graph[0] = &temp

	for i := 1; i <= q; i++ {
		queryType := readInt(scanner)
		if queryType == 1 || queryType == 2 {
			r, c := readInt(scanner)-1, readInt(scanner)-1
			newNode := node{queryType: queryType, r: r, c: c}
			graph[i] = &newNode
			graph[i-1].children = append(graph[i-1].children, i)
		} else if queryType == 3 {
			k := readInt(scanner) - 1
			newNode := node{queryType: queryType, k: k}
			graph[i] = &newNode
			graph[i-1].children = append(graph[i-1].children, i)
		} else if queryType == 4 {
			to := readInt(scanner)
			graph[i] = graph[to]
		}
	}

	dfs(graph[0], 0)

	for i := 1; i <= q; i++ {
		fmt.Println(graph[i].ans)
	}
}

func readInt(scanner *bufio.Scanner) int {
	scanner.Scan()
	ret, _ := strconv.Atoi(scanner.Text())
	return ret
}

func dfs(current *node, count int) {
	changed := false

	if current.queryType == 1 && !library[current.r][current.c] {
		library[current.r][current.c] = true
		count++
		changed = true
	} else if current.queryType == 2 && library[current.r][current.c] {
		library[current.r][current.c] = false
		count--
		changed = true
	} else if current.queryType == 3 {
		changed = true
		for i := 0; i < m; i++ {
			library[current.k][i] = !library[current.k][i]
			if library[current.k][i] {
				count++
			} else {
				count--
			}
		}
	}

	current.ans = count
	for _, v := range current.children {
		dfs(graph[v], count)
	}

	if !changed {
		return
	}

	if current.queryType == 1 {
		library[current.r][current.c] = false
	} else if current.queryType == 2 {
		library[current.r][current.c] = true
	} else if current.queryType == 3 {
		for i := 0; i < m; i++ {
			library[current.k][i] = !library[current.k][i]
		}
	}
}

package main

import (
	"bufio"
	"strconv"
	"os"
	//"fmt"
)

var scanner *bufio.Scanner
var writer *bufio.Writer

func getI64() int64 {
  scanner.Scan()
  x, _ := strconv.ParseInt(scanner.Text(), 10, 64)
  return x
}

func getI() int {
  return int(getI64())
}

func getS() string {
  scanner.Scan()
  return scanner.Text()
}

type State struct {
	bookCount int
	shelfIdxs []int
}

type Command struct {
	command int

}

type Node struct {
	opNo     int
	children []*Node
}

func (node *Node) visit () {
	//fmt.Println("HELLO", node.opNo, node.children)
	for _, child := range node.children {
		command := commands[child.opNo - 1]

		if command[0] == 1 {
			i, j := command[1], command[2]
			if !shelves[i][j] {
				bookCount[child.opNo] = bookCount[child.opNo - 1] + 1
				shelves[i][j] = true
				child.visit()
				shelves[i][j]= false
			} else {
				bookCount[child.opNo] = bookCount[child.opNo - 1]
				child.visit()
			}
		} else if command[0] == 2 {
			i, j := command[1], command[2]
			if shelves[i][j] {
				bookCount[child.opNo] = bookCount[child.opNo - 1] - 1
				shelves[i][j] = false
				child.visit()
				shelves[i][j] = true
			} else {
				bookCount[child.opNo] = bookCount[child.opNo - 1]
				child.visit()
			}
		} else if command[0] == 3 {
			i := command[1]
			newBookCount := 0
			for idx:=0; idx < m; idx++ {
				if shelves[i][idx] { shelves[i][idx] = false } else {
					shelves[i][idx] = true
					newBookCount += 1
				}
			}

			bookCount[child.opNo] = bookCount[child.opNo - 1] - (m - newBookCount) + newBookCount
			child.visit()

			for idx:=0; idx < m; idx++ {
				shelves[i][idx] = !shelves[i][idx]
			}

		} else if command[0] == 4 {
			stateNo := command[1]
			bookCount[child.opNo] = bookCount[stateNo]
			child.visit()
		}
	}
}

var (
	m, n, q int
	commands [100001][]int
	bookCount [100001]int
	shelves [1000][1000]bool
	nodes [100001]*Node
)

func main()  {

	scanner = bufio.NewScanner(os.Stdin)
	scanner.Split(bufio.ScanWords)

	writer = bufio.NewWriter(os.Stdout)
	defer writer.Flush()

	n = getI()
	m = getI()
	q = getI()

	bookCount[0] = 0
	nodes[0] = &Node{opNo: 0, children:make([]*Node, 0)}

	for opNo := 0; opNo < q; opNo++ {
		command := getI()
		if command == 1 {
			commands[opNo] = []int{command, getI() - 1, getI() - 1}
			node := &Node{opNo: opNo+1, children:make([]*Node, 0)}
			nodes[opNo + 1] = node
			nodes[opNo].children = append(nodes[opNo].children, node)
		} else if command == 2 {
			commands[opNo] = []int{command, getI() - 1, getI() - 1}
			node := &Node{opNo: opNo+1, children:make([]*Node, 0)}
			nodes[opNo + 1] = node
			nodes[opNo].children = append(nodes[opNo].children, node)
		} else if command == 3 {
			commands[opNo] = []int{command, getI() - 1}
			node := &Node{opNo: opNo+1, children:make([]*Node, 0)}
			nodes[opNo + 1] = node
			nodes[opNo].children = append(nodes[opNo].children, node)
		} else {
			stateNo := getI()
			commands[opNo] = []int{command, stateNo}
			node := &Node{opNo: opNo+1, children:make([]*Node, 0)}
			nodes[opNo + 1] = node
			nodes[stateNo].children = append(nodes[stateNo].children, node)
		}
	}

	nodes[0].visit()

	for i:=1; i<=q; i++{
		writer.WriteString(strconv.Itoa(bookCount[i]))
		writer.WriteByte('\n')
	}
}

package main

import (
	"bufio"
	"os"
	"strconv"
)

type node struct {
	children  [] int
	queryType int
	r         int
	c         int
	k         int
	i         int
	ans       int
}

var library [][]bool
var graph []*node
var n, m, q int

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	writer := bufio.NewWriter(os.Stdout)

	defer writer.Flush()

	scanner.Split(bufio.ScanWords)
	n, m, q = readInt(scanner), readInt(scanner), readInt(scanner)

	library = make([][]bool, n)
	for i, _ := range library {
		library[i] = make([]bool, m)
	}

	graph = make([]*node, q+1)
	temp := node{}
	graph[0] = &temp

	for i := 1; i <= q; i++ {
		queryType := readInt(scanner)
		if queryType == 1 || queryType == 2 {
			r, c := readInt(scanner)-1, readInt(scanner)-1
			newNode := node{queryType: queryType, r: r, c: c}
			graph[i] = &newNode
			graph[i-1].children = append(graph[i-1].children, i)
		} else if queryType == 3 {
			k := readInt(scanner) - 1
			newNode := node{queryType: queryType, k: k}
			graph[i] = &newNode
			graph[i-1].children = append(graph[i-1].children, i)
		} else if queryType == 4 {
			to := readInt(scanner)
			graph[i] = graph[to]
		}
	}

	dfs(graph[0], 0)

	for i := 1; i <= q; i++ {
		writer.WriteString(strconv.Itoa(graph[i].ans))
		writer.WriteByte('\n')
	}

}

func readInt(scanner *bufio.Scanner) int {
	scanner.Scan()
	ret, _ := strconv.Atoi(scanner.Text())
	return ret
}

func dfs(current *node, count int) {
	changed := false

	if current.queryType == 1 && !library[current.r][current.c] {
		library[current.r][current.c] = true
		count++
		changed = true
	} else if current.queryType == 2 && library[current.r][current.c] {
		library[current.r][current.c] = false
		count--
		changed = true
	} else if current.queryType == 3 {
		changed = true
		for i := 0; i < m; i++ {
			library[current.k][i] = !library[current.k][i]
			if library[current.k][i] {
				count++
			} else {
				count--
			}
		}
	}

	current.ans = count
	for _, v := range current.children {
		dfs(graph[v], count)
	}

	if !changed {
		return
	}

	if current.queryType == 1 {
		library[current.r][current.c] = false
	} else if current.queryType == 2 {
		library[current.r][current.c] = true
	} else if current.queryType == 3 {
		for i := 0; i < m; i++ {
			library[current.k][i] = !library[current.k][i]
		}
	}
}

package main

import "bufio"
import "strconv"
import "os"

type Query struct {
	cat int
	row int
	col int
}

var n, m, q, total int
var queries []Query
var adj, next, last, sum, inv, res, cur []int
var book [][]int

func add(u int, v int) {
	adj = append(adj, v)
	next = append(next, last[u])
	last[u] = len(next) - 1
}

func has(row int, col int) bool {
	return (book[row][col] ^ inv[row]) == 1
}

func toggle(row int, col int) {
	old := book[row][col]
	new := old ^ 1
	book[row][col] = new
	delta := (new ^ inv[row]) - (old ^ inv[row])
	sum[row] += delta
	total += delta
}

func invert(row int) {
	old := sum[row]
	new := m - sum[row]
	sum[row] = new
	inv[row] ^= 1
	total += new - old
}

func dfs(u int) {
	cat := queries[u].cat
	row := queries[u].row
	col := queries[u].col

	hasbook := has(row, col)
	good := ((cat == 1) && !hasbook) || ((cat == 2) && hasbook)

	switch queries[u].cat {
	case 1, 2:
		if good {
			toggle(row, col)
		}
	case 3:
		invert(row)
	}

	res[u] = total
	for e := last[u]; e != -1; e = next[e] {
		v := adj[e]
		dfs(v)
	}

	switch queries[u].cat {
	case 1, 2:
		if good {
			toggle(row, col)
		}
	case 3:
		invert(row)
	}
}

func main() {
	in := bufio.NewScanner(os.Stdin)
	out := bufio.NewWriter(os.Stdout)

	in.Split(bufio.ScanWords)
	defer out.Flush()

	in.Scan()
	n, _ = strconv.Atoi(in.Text())

	in.Scan()
	m, _ = strconv.Atoi(in.Text())

	in.Scan()
	q, _ = strconv.Atoi(in.Text())

	sum = make([]int, n+1)
	inv = make([]int, n+1)
	book = make([][]int, n+1)
	for i := 0; i <= n; i++ {
		sum[i] = 0
		inv[i] = 0
		book[i] = make([]int, m+1)
		for j := 0; j <= m; j++ {
			book[i][j] = 0
		}
	}

	queries = append(queries, Query{
		cat: 0,
		row: 0,
		col: 0,
	})

	for i := 0; i <= q; i++ {
		last = append(last, -1)
		res = append(res, -2)
		cur = append(cur, -1)
	}

	res[0] = 0
	cur[0] = 0

	for i := 1; i <= q; i++ {
		in.Scan()
		cat, _ := strconv.Atoi(in.Text())

		in.Scan()
		row, _ := strconv.Atoi(in.Text())

		col := 0
		if cat <= 2 {
			in.Scan()
			col, _ = strconv.Atoi(in.Text())
		}

		queries = append(queries, Query{
			cat: cat,
			row: row,
			col: col,
		})

		if cat <= 3 {
			add(cur[i-1], i)
			cur[i] = i
		} else {
			cur[i] = cur[row]
		}
	}

	total = 0
	dfs(0)

	for i := 1; i <= q; i++ {
		if queries[i].cat == 4 {
			res[i] = res[queries[i].row]
		}
		out.WriteString(strconv.Itoa(res[i]))
		out.WriteByte('\n')
	}
}

package main

import (
	"bufio"
	"os"
	"strconv"
)

type node struct {
	children  [] int
	queryType int
	r         int
	c         int
	k         int
	ans       int
}

var library [][]bool
var graph []*node
var n, m, q int

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	writer := bufio.NewWriter(os.Stdout)

	defer writer.Flush()

	scanner.Split(bufio.ScanWords)
	n, m, q = readInt(scanner), readInt(scanner), readInt(scanner)

	library = make([][]bool, n)
	for i, _ := range library {
		library[i] = make([]bool, m)
	}

	graph = make([]*node, q+1)
	temp := node{}
	graph[0] = &temp

	for i := 1; i <= q; i++ {
		queryType := readInt(scanner)
		if queryType == 1 || queryType == 2 {
			r, c := readInt(scanner)-1, readInt(scanner)-1
			newNode := node{queryType: queryType, r: r, c: c}
			graph[i] = &newNode
			graph[i-1].children = append(graph[i-1].children, i)
		} else if queryType == 3 {
			k := readInt(scanner) - 1
			newNode := node{queryType: queryType, k: k}
			graph[i] = &newNode
			graph[i-1].children = append(graph[i-1].children, i)
		} else if queryType == 4 {
			to := readInt(scanner)
			graph[i] = graph[to]
		}
	}

	dfs(graph[0], 0)

	for i := 1; i <= q; i++ {
		writer.WriteString(strconv.Itoa(graph[i].ans))
		writer.WriteByte('\n')
	}

}

func readInt(scanner *bufio.Scanner) int {
	scanner.Scan()
	ret, _ := strconv.Atoi(scanner.Text())
	return ret
}

func dfs(current *node, count int) {
	changed := false

	if current.queryType == 1 && !library[current.r][current.c] {
		library[current.r][current.c] = true
		count++
		changed = true
	} else if current.queryType == 2 && library[current.r][current.c] {
		library[current.r][current.c] = false
		count--
		changed = true
	} else if current.queryType == 3 {
		changed = true
		for i := 0; i < m; i++ {
			library[current.k][i] = !library[current.k][i]
			if library[current.k][i] {
				count++
			} else {
				count--
			}
		}
	}

	current.ans = count
	for _, v := range current.children {
		dfs(graph[v], count)
	}

	if !changed {
		return
	}

	if current.queryType == 1 {
		library[current.r][current.c] = false
	} else if current.queryType == 2 {
		library[current.r][current.c] = true
	} else if current.queryType == 3 {
		for i := 0; i < m; i++ {
			library[current.k][i] = !library[current.k][i]
		}
	}
}

package main

import (
	"bufio"
	"strconv"
	"os"
	//"fmt"
)

var scanner *bufio.Scanner
var writer *bufio.Writer

func getI64() int64 {
  scanner.Scan()
  x, _ := strconv.ParseInt(scanner.Text(), 10, 64)
  return x
}

func getI() int {
  return int(getI64())
}

func getS() string {
  scanner.Scan()
  return scanner.Text()
}

type State struct {
	bookCount int
	shelfIdxs []int
}

type Command struct {
	command int

}

func main()  {
	var (
		m, n, q int
		newShelf []byte
		newState State
		shelves [][]byte
		commands [][]int
	)

	scanner = bufio.NewScanner(os.Stdin)
	scanner.Split(bufio.ScanWords)

	writer = bufio.NewWriter(os.Stdout)
	defer writer.Flush()

	n = getI()
	m = getI()
	q = getI()

	for opNo := 0; opNo < q; opNo++ {
		command := getI()
		if command == 1 {
			commands = append(commands, []int{command, getI() - 1, getI() - 1})
		} else if command == 2 {
			commands = append(commands, []int{command, getI() - 1, getI() - 1})
		} else if command == 3 {
			commands = append(commands, []int{command, getI() - 1})
		} else {
			commands = append(commands, []int{command, getI()})
		}
	}

	statesToStore := make(map[int]bool)
	for _, commandSlice := range commands {
		if commandSlice[0] == 4 {
			statesToStore[commandSlice[1]] = true
		}
	}

	shelves = make([][]byte, 1, 1)
	shelves[0] = make([]byte, m, m)

	states := make(map[int]State)
	states[0] = State{bookCount: 0, shelfIdxs: make([]int, n, n)}
	currentState := State{bookCount: 0, shelfIdxs: make([]int, n, n)}

	for opNo, commandSlice := range commands {
		command := commandSlice[0]

		if command == 1 {
			i, j := commandSlice[1], commandSlice[2]
			newState = State{bookCount: currentState.bookCount, shelfIdxs: currentState.shelfIdxs}
			if shelves[currentState.shelfIdxs[i]][j] == 0 {
				newShelf = make([]byte, m, m)
				copy(newShelf, shelves[currentState.shelfIdxs[i]])
				newShelf[j] = 1

				newShelfIdxs := make([]int, n, n)
				copy(newShelfIdxs, currentState.shelfIdxs)
				newState.shelfIdxs = newShelfIdxs

				shelves = append(shelves, newShelf)
				newState.shelfIdxs[i] = len(shelves) - 1
				newState.bookCount += 1
			}
		} else if command == 2 {
			i, j := commandSlice[1], commandSlice[2]
			newState = State{bookCount: currentState.bookCount, shelfIdxs: currentState.shelfIdxs}
			if shelves[currentState.shelfIdxs[i]][j] == 1 {
				newShelf = make([]byte, m, m)
				copy(newShelf, shelves[currentState.shelfIdxs[i]])
				newShelf[j] = 0

				newShelfIdxs := make([]int, n, n)
				copy(newShelfIdxs, currentState.shelfIdxs)
				newState.shelfIdxs = newShelfIdxs

				shelves = append(shelves, newShelf)
				newState.shelfIdxs[i] = len(shelves) - 1
				newState.bookCount -= 1
			}

		} else if command == 3 {
			i := commandSlice[1]
			newState = State{bookCount: currentState.bookCount, shelfIdxs: currentState.shelfIdxs}
			newShelf = make([]byte, m, m)
			copy(newShelf, shelves[currentState.shelfIdxs[i]])
			newBookCount := 0
			for idx, value := range newShelf {
				if value == 1 {
					newShelf[idx] = 0
				} else {
					newShelf[idx] = 1
					newBookCount += 1
				}
			}

			newShelfIdxs := make([]int, n, n)
			copy(newShelfIdxs, currentState.shelfIdxs)
			newState.shelfIdxs = newShelfIdxs

			shelves = append(shelves, newShelf)
			newState.shelfIdxs[i] = len(shelves) - 1
			newState.bookCount = currentState.bookCount - (m - newBookCount) + newBookCount

		} else {
			i := commandSlice[1]
			newState = State{bookCount: states[i].bookCount, shelfIdxs:states[i].shelfIdxs}
		}
		if _, exists := statesToStore[opNo]; exists {
			states[opNo+1] = newState
		}
		currentState = newState
		writer.WriteString(strconv.Itoa(newState.bookCount))
		writer.WriteByte('\n')
	}
}

package main

import (
	"bufio"
	"strconv"
	"os"
	//"fmt"
)

var scanner *bufio.Scanner
var writer *bufio.Writer

func getI64() int64 {
  scanner.Scan()
  x, _ := strconv.ParseInt(scanner.Text(), 10, 64)
  return x
}

func getI() int {
  return int(getI64())
}

func getS() string {
  scanner.Scan()
  return scanner.Text()
}

type State struct {
	bookCount int
	shelfIdxs []int
}

type Command struct {
	command int

}

func main()  {
	var (
		m, n, q int
		newShelf []byte
		newState State
		shelves [][]byte
		commands [][]int
	)

	scanner = bufio.NewScanner(os.Stdin)
	scanner.Split(bufio.ScanWords)

	writer = bufio.NewWriter(os.Stdout)
	defer writer.Flush()

	n = getI()
	m = getI()
	q = getI()

	for opNo := 0; opNo < q; opNo++ {
		command := getI()
		if command == 1 {
			commands = append(commands, []int{command, getI() - 1, getI() - 1})
		} else if command == 2 {
			commands = append(commands, []int{command, getI() - 1, getI() - 1})
		} else if command == 3 {
			commands = append(commands, []int{command, getI() - 1})
		} else {
			commands = append(commands, []int{command, getI()})
		}
	}

	statesToStore := make(map[int]bool)
	for _, commandSlice := range commands {
		if commandSlice[0] == 4 {
			statesToStore[commandSlice[1]] = true
		}
	}

	shelves = make([][]byte, 1, 1)
	shelves[0] = make([]byte, m, m)

	states := make(map[int]State)
	states[0] = State{bookCount: 0, shelfIdxs: make([]int, n, n)}
	currentState := State{bookCount: 0, shelfIdxs: make([]int, n, n)}

	for opNo, commandSlice := range commands {
		command := commandSlice[0]

		if command == 1 {
			i, j := commandSlice[1], commandSlice[2]
			newState = State{bookCount: currentState.bookCount, shelfIdxs: currentState.shelfIdxs}
			if shelves[currentState.shelfIdxs[i]][j] == 0 {
				newShelf = make([]byte, m, m)
				copy(newShelf, shelves[currentState.shelfIdxs[i]])
				newShelf[j] = 1

				newShelfIdxs := make([]int, n, n)
				copy(newShelfIdxs, currentState.shelfIdxs)
				newState.shelfIdxs = newShelfIdxs

				shelves = append(shelves, newShelf)
				newState.shelfIdxs[i] = len(shelves) - 1
				newState.bookCount += 1
			}
		} else if command == 2 {
			i, j := commandSlice[1], commandSlice[2]
			newState = State{bookCount: currentState.bookCount, shelfIdxs: currentState.shelfIdxs}
			if shelves[currentState.shelfIdxs[i]][j] == 1 {
				newShelf = make([]byte, m, m)
				copy(newShelf, shelves[currentState.shelfIdxs[i]])
				newShelf[j] = 0

				newShelfIdxs := make([]int, n, n)
				copy(newShelfIdxs, currentState.shelfIdxs)
				newState.shelfIdxs = newShelfIdxs

				shelves = append(shelves, newShelf)
				newState.shelfIdxs[i] = len(shelves) - 1
				newState.bookCount -= 1
			}

		} else if command == 3 {
			i := commandSlice[1]
			newState = State{bookCount: currentState.bookCount, shelfIdxs: currentState.shelfIdxs}
			newShelf = make([]byte, m, m)
			copy(newShelf, shelves[currentState.shelfIdxs[i]])
			newBookCount := 0
			for idx, value := range newShelf {
				if value == 1 {
					newShelf[idx] = 0
				} else {
					newShelf[idx] = 1
					newBookCount += 1
				}
			}

			newShelfIdxs := make([]int, n, n)
			copy(newShelfIdxs, currentState.shelfIdxs)
			newState.shelfIdxs = newShelfIdxs

			shelves = append(shelves, newShelf)
			newState.shelfIdxs[i] = len(shelves) - 1
			newState.bookCount = currentState.bookCount - (m - newBookCount) + newBookCount

		} else {
			i := commandSlice[1]
			newState = State{bookCount: states[i].bookCount, shelfIdxs:states[i].shelfIdxs}
		}

		if _, exists := statesToStore[opNo]; exists {
			states[opNo] = newState
		}

		currentState = newState
		writer.WriteString(strconv.Itoa(newState.bookCount))
		writer.WriteByte('\n')
	}
}

package main

import (
	"bufio"
	"strconv"
	"os"
	//"fmt"
)

var scanner *bufio.Scanner
var writer *bufio.Writer

func getI64() int64 {
  scanner.Scan()
  x, _ := strconv.ParseInt(scanner.Text(), 10, 64)
  return x
}

func getI() int {
  return int(getI64())
}

func getS() string {
  scanner.Scan()
  return scanner.Text()
}

type State struct {
	bookCount int
	shelfIdxs []int
}

type Command struct {
	command int

}

func main()  {
	var (
		m, n, q int
		newShelf []byte
		newState State
		shelves [][]byte
		commands [][]int
	)

	scanner = bufio.NewScanner(os.Stdin)
	scanner.Split(bufio.ScanWords)

	writer = bufio.NewWriter(os.Stdout)
	defer writer.Flush()

	n = getI()
	m = getI()
	q = getI()

	for opNo := 0; opNo < q; opNo++ {
		command := getI()
		if command == 1 {
			commands = append(commands, []int{command, getI() - 1, getI() - 1})
		} else if command == 2 {
			commands = append(commands, []int{command, getI() - 1, getI() - 1})
		} else if command == 3 {
			commands = append(commands, []int{command, getI() - 1})
		} else {
			commands = append(commands, []int{command, getI()})
		}
	}

	statesToStore := make(map[int]bool)
	for _, commandSlice := range commands {
		if commandSlice[0] == 4 {
			statesToStore[commandSlice[1]] = true
		}
	}

	shelves = make([][]byte, 1, 1)
	shelves[0] = make([]byte, m, m)

	states := make(map[int]State)
	states[0] = State{bookCount: 0, shelfIdxs: make([]int, n, n)}
	currentState := State{bookCount: 0, shelfIdxs: make([]int, n, n)}

	for opNo, commandSlice := range commands {
		command := commandSlice[0]

		if command == 1 {
			i, j := commandSlice[1], commandSlice[2]
			newState = currentState
			if shelves[currentState.shelfIdxs[i]][j] == 0 {
				newShelf = make([]byte, m, m)
				copy(newShelf, shelves[currentState.shelfIdxs[i]])
				newShelf[j] = 1

				shelves = append(shelves, newShelf)
				newState.shelfIdxs[i] = len(shelves) - 1
				newState.bookCount += 1
			}
		} else if command == 2 {
			i, j := commandSlice[1], commandSlice[2]
			newState = currentState
			if shelves[currentState.shelfIdxs[i]][j] == 1 {
				newShelf = make([]byte, m, m)
				copy(newShelf, shelves[currentState.shelfIdxs[i]])
				newShelf[j] = 0

				shelves = append(shelves, newShelf)
				newState.shelfIdxs[i] = len(shelves) - 1
				newState.bookCount -= 1
			}

		} else if command == 3 {
			i := commandSlice[1]
			newState = currentState
			newShelf = make([]byte, m, m)
			copy(newShelf, shelves[currentState.shelfIdxs[i]])
			newBookCount := 0
			for idx, value := range newShelf {
				if value == 1 {
					newShelf[idx] = 0
				} else {
					newShelf[idx] = 1
					newBookCount += 1
				}
			}

			shelves = append(shelves, newShelf)
			newState.shelfIdxs[i] = len(shelves) - 1
			newState.bookCount = currentState.bookCount - (m - newBookCount) + newBookCount

		} else {
			i := commandSlice[1]
			newState = State{bookCount: states[i].bookCount, shelfIdxs:states[i].shelfIdxs}
		}

		if _, exists := statesToStore[opNo+1]; exists {
			newShelfIdxs := make([]int, n, n)
			copy(newShelfIdxs, newState.shelfIdxs)
			states[opNo+1] = State{bookCount: newState.bookCount, shelfIdxs: newShelfIdxs}
		}

		currentState = newState
		writer.WriteString(strconv.Itoa(newState.bookCount))
		writer.WriteByte('\n')
	}
}

package main

import "bufio"
import "strconv"
import "os"

type Query struct {
	cat int
	row int
	col int
}

var n, m, q, total int
var queries []Query
var adj, next, last, sum, inv, res []int
var book [][]int

func add(u int, v int) {
	adj = append(adj, v)
	next = append(next, last[u])
	last[u] = len(next) - 1
}

func has(row int, col int) bool {
	return (book[row][col] ^ inv[row]) == 1
}

func toggle(row int, col int) {
	old := book[row][col]
	new := old ^ 1
	book[row][col] = new
	delta := (new ^ inv[row]) - (old ^ inv[row])
	sum[row] += delta
	total += delta
}

func invert(row int) {
	old := sum[row]
	new := m - sum[row]
	sum[row] = new
	inv[row] ^= 1
	total += new - old
}

func dfs(u int) {
	row := queries[u].row
	col := queries[u].col

	switch queries[u].cat {
	case 1:
		if !has(row, col) {
			toggle(row, col)
		}
	case 2:
		if has(row, col) {
			toggle(row, col)
		}
	case 3:
		invert(row)
	}

	res[u] = total
	for e := last[u]; e != -1; e = next[e] {
		v := adj[e]
		dfs(v)
	}

	switch queries[u].cat {
	case 1:
		if has(row, col) {
			toggle(row, col)
		}
	case 2:
		if !has(row, col) {
			toggle(row, col)
		}
	case 3:
		invert(row)
	}
}

func main() {
	in := bufio.NewScanner(os.Stdin)
	out := bufio.NewWriter(os.Stdout)

	in.Split(bufio.ScanWords)
	defer out.Flush()

	in.Scan()
	n, _ = strconv.Atoi(in.Text())

	in.Scan()
	m, _ = strconv.Atoi(in.Text())

	in.Scan()
	q, _ = strconv.Atoi(in.Text())

	sum = make([]int, n+1)
	inv = make([]int, n+1)
	book = make([][]int, n+1)
	for i := 0; i <= n; i++ {
		sum[i] = 0
		inv[i] = 0
		book[i] = make([]int, m+1)
		for j := 0; j <= m; j++ {
			book[i][j] = 0
		}
	}

	queries = append(queries, Query{
		cat: 0,
		row: 0,
		col: 0,
	})

	for i := 0; i <= q; i++ {
		last = append(last, -1)
		res = append(res, -1)
	}

	res[0] = 0
	cur := 0

	for i := 1; i <= q; i++ {
		in.Scan()
		cat, _ := strconv.Atoi(in.Text())

		in.Scan()
		row, _ := strconv.Atoi(in.Text())

		col := 0
		if cat <= 2 {
			in.Scan()
			col, _ = strconv.Atoi(in.Text())
		}

		queries = append(queries, Query{
			cat: cat,
			row: row,
			col: col,
		})

		if cat <= 3 {
			add(cur, i)
			cur = i
		} else {
			cur = row
		}
	}

	total = 0
	dfs(0)

	for i := 1; i <= q; i++ {
		if queries[i].cat == 4 {
			res[i] = res[queries[i].row]
		}
		out.WriteString(strconv.Itoa(res[i]))
		out.WriteByte('\n')
	}
}

package main

import "bufio"
import "strconv"
import "os"

type Query struct {
	cat int
	row int
	col int
}

var n, m, q, total int
var queries []Query
var adj, next, last, sum, inv, res []int
var book [][]int

func add(u int, v int) {
	adj = append(adj, v)
	next = append(next, last[u])
	last[u] = len(next) - 1
}

func toggle(row int, col int) {
	old := book[row][col]
	new := old ^ 1
	book[row][col] = new
	delta := (new ^ inv[row]) - (old ^ inv[row])
	sum[row] += delta
	total += delta
}

func invert(row int) {
	old := sum[row]
	new := m - sum[row]
	sum[row] = new
	inv[row] ^= 1
	total += new - old
}

func dfs(u int) {
	row := queries[u].row
	col := queries[u].col

	switch queries[u].cat {
	case 1, 2:
		toggle(row, col)
	case 3:
		invert(row)
	}

	res[u] = total
	for e := last[u]; e != -1; e = next[e] {
		v := adj[e]
		dfs(v)
	}

	switch queries[u].cat {
	case 1, 2:
		toggle(row, col)
	case 3:
		invert(row)
	}
}

func main() {
	in := bufio.NewScanner(os.Stdin)
	out := bufio.NewWriter(os.Stdout)

	in.Split(bufio.ScanWords)
	defer out.Flush()

	in.Scan()
	n, _ = strconv.Atoi(in.Text())

	in.Scan()
	m, _ = strconv.Atoi(in.Text())

	in.Scan()
	q, _ = strconv.Atoi(in.Text())

	sum = make([]int, n+1)
	inv = make([]int, n+1)
	book = make([][]int, n+1)
	for i := 0; i <= n; i++ {
		sum[i] = 0
		inv[i] = 0
		book[i] = make([]int, m+1)
		for j := 0; j <= m; j++ {
			book[i][j] = 0
		}
	}

	queries = append(queries, Query{
		cat: 0,
		row: 0,
		col: 0,
	})

	for i := 0; i <= q; i++ {
		last = append(last, -1)
		res = append(res, -1)
	}

	res[0] = 0
	cur := 0

	for i := 1; i <= q; i++ {
		in.Scan()
		cat, _ := strconv.Atoi(in.Text())

		in.Scan()
		row, _ := strconv.Atoi(in.Text())

		col := 0
		if cat <= 2 {
			in.Scan()
			col, _ = strconv.Atoi(in.Text())
		}

		queries = append(queries, Query{
			cat: cat,
			row: row,
			col: col,
		})

		if cat <= 3 {
			add(cur, i)
			cur = i
		} else {
			cur = row
		}
	}

	total = 0
	dfs(0)

	for i := 1; i <= q; i++ {
		if queries[i].cat == 4 {
			res[i] = res[queries[i].row]
		}
		out.WriteString(strconv.Itoa(res[i]))
		out.WriteByte('\n')
	}
}

package main

import "bufio"
import "strconv"
import "os"

type Query struct {
	cat int
	row int
	col int
}

var n, m, q, total int
var queries []Query
var adj, next, last, sum, inv, res []int
var book [][]int

func add(u int, v int) {
	adj = append(adj, v)
	next = append(next, last[u])
	last[u] = len(next) - 1
}

func has(row int, col int) bool {
	return (book[row][col] ^ inv[row]) == 1
}

func toggle(row int, col int) {
	old := book[row][col]
	new := old ^ 1
	book[row][col] = new
	delta := (new ^ inv[row]) - (old ^ inv[row])
	sum[row] += delta
	total += delta
}

func invert(row int) {
	old := sum[row]
	new := m - sum[row]
	sum[row] = new
	inv[row] ^= 1
	total += new - old
}

func dfs(u int) {
	cat := queries[u].cat
	row := queries[u].row
	col := queries[u].col

	hasbook := has(row, col)
	good := ((cat == 1) && !hasbook) || ((cat == 2) && hasbook)

	switch queries[u].cat {
	case 1, 2:
		if good {
			toggle(row, col)
		}
	case 3:
		invert(row)
	}

	res[u] = total
	for e := last[u]; e != -1; e = next[e] {
		v := adj[e]
		dfs(v)
	}

	switch queries[u].cat {
	case 1, 2:
		if good {
			toggle(row, col)
		}
	case 3:
		invert(row)
	}
}

func main() {
	in := bufio.NewScanner(os.Stdin)
	out := bufio.NewWriter(os.Stdout)

	in.Split(bufio.ScanWords)
	defer out.Flush()

	in.Scan()
	n, _ = strconv.Atoi(in.Text())

	in.Scan()
	m, _ = strconv.Atoi(in.Text())

	in.Scan()
	q, _ = strconv.Atoi(in.Text())

	sum = make([]int, n+1)
	inv = make([]int, n+1)
	book = make([][]int, n+1)
	for i := 0; i <= n; i++ {
		sum[i] = 0
		inv[i] = 0
		book[i] = make([]int, m+1)
		for j := 0; j <= m; j++ {
			book[i][j] = 0
		}
	}

	queries = append(queries, Query{
		cat: 0,
		row: 0,
		col: 0,
	})

	for i := 0; i <= q; i++ {
		last = append(last, -1)
		res = append(res, -1)
	}

	res[0] = 0
	cur := 0

	for i := 1; i <= q; i++ {
		in.Scan()
		cat, _ := strconv.Atoi(in.Text())

		in.Scan()
		row, _ := strconv.Atoi(in.Text())

		col := 0
		if cat <= 2 {
			in.Scan()
			col, _ = strconv.Atoi(in.Text())
		}

		queries = append(queries, Query{
			cat: cat,
			row: row,
			col: col,
		})

		if cat <= 3 {
			add(cur, i)
			cur = i
		} else {
			cur = row
		}
	}

	total = 0
	dfs(0)

	for i := 1; i <= q; i++ {
		if queries[i].cat == 4 {
			res[i] = res[queries[i].row]
		}
		out.WriteString(strconv.Itoa(res[i]))
		out.WriteByte('\n')
	}
}

package main

import (
	"bufio"
	"os"
	"strconv"
	"fmt"
)

type node struct {
	children  [] int
	queryType int
	r         int
	c         int
	k         int
	i         int
	ans       int
}

var library [][]bool
var graph []node
var n, m, q int

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	scanner.Split(bufio.ScanWords)
	n, m, q = readInt(scanner), readInt(scanner), readInt(scanner)

	library = make([][]bool, n)
	for i, _ := range library {
		library[i] = make([]bool, m)
	}

	graph = make([]node, q+1)
	graph[0] = node{}

	for i := 1; i <= q; i++ {
		queryType := readInt(scanner)
		if queryType == 1 || queryType == 2 {
			r, c := readInt(scanner)-1, readInt(scanner)-1
			graph[i] = node{queryType: queryType, r: r, c: c}
			graph[i-1].children = append(graph[i-1].children, i)
		} else if queryType == 3 {
			k := readInt(scanner) - 1
			graph[i] = node{queryType: queryType, k: k}
			graph[i-1].children = append(graph[i-1].children, i)
		} else if queryType == 4 {
			to := readInt(scanner)
			graph[i] = node{queryType: queryType, i: to}
		}
	}

	dfs(&graph[0], 0)

	for i := 1; i <= q; i++ {
		if graph[i].queryType == 4 {
			fmt.Println(graph[graph[i].i].ans)
		} else {
			fmt.Println(graph[i].ans)
		}
	}
}

func readInt(scanner *bufio.Scanner) int {
	scanner.Scan()
	ret, _ := strconv.Atoi(scanner.Text())
	return ret
}

func dfs(current *node, count int) {
	changed := false

	if current.queryType == 4 {
		current = &graph[current.i]
	}

	if current.queryType == 1 && !library[current.r][current.c] {
		library[current.r][current.c] = true
		count++
		changed = true
	} else if current.queryType == 2 && library[current.r][current.c] {
		library[current.r][current.c] = false
		count--
		changed = true
	} else if current.queryType == 3 {
		changed = true
		for i := 0; i < m; i++ {
			library[current.k][i] = !library[current.k][i]
			if library[current.k][i] {
				count++
			} else {
				count--
			}
		}
	}

	current.ans = count
	for _, v := range current.children {
		dfs(&graph[v], count)
	}

	if !changed {
		return
	}

	if current.queryType == 1 {
		library[current.r][current.c] = false
	} else if current.queryType == 2 {
		library[current.r][current.c] = true
	} else if current.queryType == 3 {
		for i := 0; i < m; i++ {
			library[current.k][i] = !library[current.k][i]
		}
	}
}

package main

import (
	"bufio"
	"os"
	"strconv"
	"fmt"
)

type node struct {
	children  [] int
	queryType int
	r         int
	c         int
	k         int
	i         int
	ans       int
}

var library [][]bool
var graph []node
var n, m, q int

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	scanner.Split(bufio.ScanWords)
	n, m, q = readInt(scanner), readInt(scanner), readInt(scanner)

	library = make([][]bool, n)
	for i, _ := range library {
		library[i] = make([]bool, m)
	}

	graph = make([]node, q+1)
	graph[0] = node{}

	for i := 1; i <= q; i++ {
		queryType := readInt(scanner)
		if queryType == 1 || queryType == 2 {
			r, c := readInt(scanner)-1, readInt(scanner)-1
			graph[i] = node{queryType: queryType, r: r, c: c}
			graph[i-1].children = append(graph[i-1].children, i)
		} else if queryType == 3 {
			k := readInt(scanner) - 1
			graph[i] = node{queryType: queryType, k: k}
			graph[i-1].children = append(graph[i-1].children, i)
		} else if queryType == 4 {
			to := readInt(scanner)
			graph[i] = node{queryType: queryType, i: to}
		}
	}

	dfs(&graph[0], 0)

	for i := 1; i <= q; i++ {
		fmt.Println(graph[i].ans)
	}
}

func readInt(scanner *bufio.Scanner) int {
	scanner.Scan()
	ret, _ := strconv.Atoi(scanner.Text())
	return ret
}

func dfs(current *node, count int) {
	changed := false

	if current.queryType == 4 {
		current = &graph[current.i]
	}

	if current.queryType == 1 && !library[current.r][current.c] {
		library[current.r][current.c] = true
		count++
		changed = true
	} else if current.queryType == 2 && library[current.r][current.c] {
		library[current.r][current.c] = false
		count--
		changed = true
	} else if current.queryType == 3 {
		changed = true
		for i := 0; i < m; i++ {
			library[current.k][i] = !library[current.k][i]
			if library[current.k][i] {
				count++
			} else {
				count--
			}
		}
	}

	current.ans = count
	for _, v := range current.children {
		dfs(&graph[v], count)
	}

	if !changed {
		return
	}

	if current.queryType == 1 {
		library[current.r][current.c] = false
	} else if current.queryType == 2 {
		library[current.r][current.c] = true
	} else if current.queryType == 3 {
		for i := 0; i < m; i++ {
			library[current.k][i] = !library[current.k][i]
		}
	}
}


// Author: sighduck
// URL: https://codeforces.com/problemset/problem/225/C

package main

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

func min(x int, y int) int {
	if x < y {
		return x
	}
	return y
}

func initDP(m int) [][]int {
	dp := make([][]int, 2)
	for i := 0; i < 2; i++ {
		dp[i] = make([]int, m+1)
		for j := 0; j <= m; j++ {
			dp[i][j] = 1e8
		}
	}
	dp[0][0] = 0
	dp[1][0] = 0
	return dp
}

func initPrefix(whites []int, n int, m int) [][]int {
	prefix := make([][]int, 2)
	for i := 0; i < 2; i++ {
		prefix[i] = make([]int, m+1)
	}
	for i := 1; i <= m; i++ {
		prefix[0][i] = prefix[0][i-1] + whites[i-1]
		prefix[1][i] = prefix[1][i-1] + n - whites[i-1]
	}
	return prefix
}

func Solve(n int, m int, x int, y int, picture []string) int {
	whites := make([]int, m)
	for i := 0; i < n; i++ {
		for j := 0; j < m; j++ {
			if string(picture[i][j]) == "." {
				whites[j] += 1
			}
		}
	}
	dp := initDP(m)
	prefix := initPrefix(whites, n, m)
	for i := 1; i <= m; i++ {
		for a := x; a <= y; a++ {
			if i-a >= 0 {
				dp[0][i] = min(dp[0][i], dp[1][i-a]+prefix[0][i]-prefix[0][i-a])
				dp[1][i] = min(dp[1][i], dp[0][i-a]+prefix[1][i]-prefix[1][i-a])
			}
		}
	}
	return min(dp[0][m], dp[1][m])
}

func main() {
	reader := bufio.NewReader(os.Stdin)
	writer := bufio.NewWriter(os.Stdout)
	defer writer.Flush()

	var n, m, x, y int
	fmt.Fscanf(reader, "%d %d %d %d\n", &n, &m, &x, &y)
	picture := make([]string, n)
	for i := 0; i < n; i++ {
		fmt.Fscanf(reader, "%s\n", &picture[i])
	}

	fmt.Fprintf(writer, "%d\n", Solve(n, m, x, y, picture))
}

package main

import (
	"bufio"
	. "fmt"
	"io"
	"os"
)

// github.com/EndlessCheng/codeforces-go
func Sol225C(reader io.Reader, writer io.Writer) {
	min := func(a, b int) int {
		if a <= b {
			return a
		}
		return b
	}
	in := bufio.NewReader(reader)
	out := bufio.NewWriter(writer)
	defer out.Flush()

	var n, m, x, y int
	Fscan(in, &n, &m, &x, &y)
	cnt := make([]int, m)
	var s string
	for i := 0; i < n; i++ {
		Fscan(in, &s)
		for j, c := range s {
			if c == '.' {
				cnt[j]++
			}
		}
	}

	sum := make([][2]int, m+1)
	for i := 1; i <= m; i++ {
		sum[i][0] = sum[i-1][0] + cnt[i-1]
		sum[i][1] = sum[i-1][1] + n - cnt[i-1]
	}
	dp := make([][2]int, m+1)
	for i := range dp {
		dp[i][0] = 1e8
		dp[i][1] = 1e8
	}
	dp[0][0] = 0
	dp[0][1] = 0
	for i := 1; i <= m; i++ {
		for j := x; j <= y; j++ {
			if i-j < 0 {
				break
			}
			dp[i][0] = min(dp[i][0], dp[i-j][1]+sum[i][0]-sum[i-j][0])
			dp[i][1] = min(dp[i][1], dp[i-j][0]+sum[i][1]-sum[i-j][1])
		}
	}
	Fprint(out, min(dp[m][0], dp[m][1]))
}

func main() {
	Sol225C(os.Stdin, os.Stdout)
}

package main

import (
	"bufio"
	. "fmt"
	"io"
	"os"
)

// github.com/EndlessCheng/codeforces-go
func Sol225C(reader io.Reader, writer io.Writer) {
	min := func(a, b int) int {
		if a <= b {
			return a
		}
		return b
	}
	in := bufio.NewReader(reader)
	out := bufio.NewWriter(writer)
	defer out.Flush()

	var n, m, x, y int
	Fscan(in, &n, &m, &x, &y)
	cnt := make([]int, m)
	pic := make([]string, n)
	for i := range pic {
		Fscan(in, &pic[i])
		for j, c := range pic[i] {
			if c == '.' {
				cnt[j]++
			}
		}
	}

	dp := make([][][2]int, m)
	for i := range dp {
		dp[i] = make([][2]int, m)
		for j := range dp[i] {
			dp[i][j][0] = -1
			dp[i][j][1] = -1
		}
	}

	var f func(int, int8, int) int
	f = func(i int, isDot int8, con int) (res int) {
		if i == m {
			if con-1 < x || con-1 > y {
				return 1e8
			}
			return
		}
		if con-1 >= y {
			return 1e8
		}
		if val := dp[i][con][isDot]; val != -1 {
			return val
		}
		if isDot == 0 { // #
			res = f(i+1, 0, con+1) + cnt[i]
			if con >= x {
				res = min(res, f(i+1, 1, 1)+n-cnt[i]) // .
			}
		} else { // .
			res = f(i+1, 1, con+1) + n - cnt[i]
			if con >= x {
				res = min(res, f(i+1, 0, 1)+cnt[i]) // #
			}
		}
		if res < 1e8{
			dp[i][con][isDot] = res
		}
		return
	}
	Fprint(out, min(f(1, 0, 1)+cnt[0], f(1, 1, 1)+n-cnt[0]))
}

func main() {
	Sol225C(os.Stdin, os.Stdout)
}

package main

import (
	"bufio"
	. "fmt"
	"io"
	"os"
)

// github.com/EndlessCheng/codeforces-go
func Sol225C(reader io.Reader, writer io.Writer) {
	min := func(a, b int) int {
		if a <= b {
			return a
		}
		return b
	}
	in := bufio.NewReader(reader)
	out := bufio.NewWriter(writer)
	defer out.Flush()

	var n, m, x, y int
	Fscan(in, &n, &m, &x, &y)
	cnt := make([]int, m)
	pic := make([]string, n)
	for i := range pic {
		Fscan(in, &pic[i])
		for j, c := range pic[i] {
			if c == '.' {
				cnt[j]++
			}
		}
	}

	dp := make([][][2]int, m)
	for i := range dp {
		dp[i] = make([][2]int, m)
		for j := range dp[i] {
			dp[i][j][0] = -1
			dp[i][j][1] = -1
		}
	}

	var f func(int, int8, int) int
	f = func(i int, isDot int8, con int) (res int) {
		if i == m {
			if con-1 < x || con-1 > y {
				return 1e8
			}
			return
		}
		if con-1 >= y {
			return 1e8
		}
		if val := dp[i][con][isDot]; val != -1 {
			return val
		}
		if isDot == 0 { // #
			res = f(i+1, 0, con+1) + cnt[i]
			if con >= x {
				res = min(res, f(i+1, 1, 1)+n-cnt[i]) // .
			}
		} else { // .
			res = f(i+1, 1, con+1) + n - cnt[i]
			if con >= x {
				res = min(res, f(i+1, 0, 1)+cnt[i]) // #
			}
		}
		dp[i][con][isDot] = res
		return
	}
	Fprint(out, min(f(1, 0, 1)+cnt[0], f(1, 1, 1)+n-cnt[0]))
}

func main() {
	Sol225C(os.Stdin, os.Stdout)
}

package main

import (
	"bufio"
	. "fmt"
	"io"
	"os"
)

// github.com/EndlessCheng/codeforces-go
func Sol225C(reader io.Reader, writer io.Writer) {
	min := func(a, b int) int {
		if a <= b {
			return a
		}
		return b
	}
	in := bufio.NewReader(reader)
	out := bufio.NewWriter(writer)
	defer out.Flush()

	var n, m, x, y int
	Fscan(in, &n, &m, &x, &y)
	cnt := make([]int, m)
	pic := make([]string, n)
	for i := range pic {
		Fscan(in, &pic[i])
		for j, c := range pic[i] {
			if c == '.' {
				cnt[j]++
			}
		}
	}

	cache := map[string]int{}
	var f func(int, int8, int) int
	f = func(i int, isDot int8, con int) (res int) {
		if i == m {
			return
		}
		if con > y {
			return 1e8
		}
		hash := Sprintf("%d;%d;%d", i, isDot, con)
		if val, ok := cache[hash]; ok {
			return val
		}
		if isDot == 0 { // #
			res = f(i+1, isDot, con+1) + cnt[i]
			if con >= x {
				res = min(res, f(i+1, isDot^1, 1)+n-cnt[i]) // .
			}
		} else { // .
			res = f(i+1, isDot, con+1) + n - cnt[i]
			if con >= x {
				res = min(res, f(i+1, isDot^1, 1)+cnt[i]) // #
			}
		}
		cache[hash] = res
		return
	}
	Fprint(out, min(f(1, 0, 1)+cnt[0], f(1, 1, 1)+n-cnt[0]))
}

func main() {
	Sol225C(os.Stdin, os.Stdout)
}

// Author: sighduck
// URL: https://codeforces.com/problemset/problem/225/C

package main

import (
	"bufio"
	"fmt"
	"math"
	"os"
)

func min(x int, y int) int {
	if x < y {
		return x
	}
	return y
}

func initDP(m int) [][]int {
	dp := make([][]int, 2)
	for i := 0; i < 2; i++ {
		dp[i] = make([]int, m+1)
		for j := 0; j <= m; j++ {
			dp[i][j] = math.MaxInt32
		}
	}
	dp[0][0] = 0
	dp[1][0] = 0
	return dp
}

func initPrefix(whites []int, n int, m int) [][]int {
	prefix := make([][]int, 2)
	for i := 0; i < 2; i++ {
		prefix[i] = make([]int, m+1)
	}
	for i := 1; i <= m; i++ {
		prefix[0][i] = prefix[0][i-1] + whites[i-1]
		prefix[1][i] = prefix[1][i-1] + n - whites[i-1]
	}
	return prefix
}

func sum(prefix []int, start int, end int) int {
	return prefix[end] - prefix[start-1]
}

func Solve(n int, m int, x int, y int, picture []string) int {
	whites := make([]int, m)
	for i := 0; i < n; i++ {
		for j := 0; j < m; j++ {
			if string(picture[i][j]) == "." {
				whites[j] += 1
			}
		}
	}
	dp := initDP(m)
	prefix := initPrefix(whites, n, m)
	for i := 0; i <= m; i++ {
		for a := x; a <= y; a++ {
			if i-a >= 0 {
				dp[0][i] = min(dp[0][i], dp[1][i-a]+sum(prefix[0], i-a+1, i))
				dp[1][i] = min(dp[1][i], dp[0][i-a]+sum(prefix[1], i-a+1, i))
			}
		}
	}
	return min(dp[0][m], dp[1][m])
}

func main() {
	reader := bufio.NewReader(os.Stdin)
	writer := bufio.NewWriter(os.Stdout)
	defer writer.Flush()

	var n, m, x, y int
	fmt.Fscanf(reader, "%d %d %d %d\n", &n, &m, &x, &y)
	picture := make([]string, n)
	for i := 0; i < n; i++ {
		fmt.Fscanf(reader, "%s\n", &picture[i])
	}

	fmt.Fprintf(writer, "%d\n", Solve(n, m, x, y, picture))
}

// Author: sighduck
// URL: https://codeforces.com/problemset/problem/225/C

package main

import (
	"bufio"
	"fmt"
	"math"
	"os"
)

func min(x int, y int) int {
	if x < y {
		return x
	}
	return y
}

func initDP(m int) [][]int {
	dp := make([][]int, 2)
	for i := 0; i < 2; i++ {
		dp[i] = make([]int, m+1)
		for j := 0; j <= m; j++ {
			dp[i][j] = math.MaxInt16
		}
	}
	dp[0][0] = 0
	dp[1][0] = 0
	return dp
}

func initPrefix(whites []int, n int, m int) [][]int {
	prefix := make([][]int, 2)
	for i := 0; i < 2; i++ {
		prefix[i] = make([]int, m+1)
	}
	for i := 1; i <= m; i++ {
		prefix[0][i] = prefix[0][i-1] + whites[i-1]
		prefix[1][i] = prefix[1][i-1] + n - whites[i-1]
	}
	return prefix
}

func sum(prefix []int, start int, end int) int {
	return prefix[end] - prefix[start-1]
}

func Solve(n int, m int, x int, y int, picture []string) int {
	whites := make([]int, m)
	for i := 0; i < n; i++ {
		for j := 0; j < m; j++ {
			if string(picture[i][j]) == "." {
				whites[j] += 1
			}
		}
	}
	dp := initDP(m)
	prefix := initPrefix(whites, n, m)
	for i := 1; i <= m; i++ {
		for a := x; a <= y; a++ {
			if i-a >= 0 {
				dp[0][i] = min(dp[0][i], dp[1][i-a]+sum(prefix[0], i-a+1, i))
				dp[1][i] = min(dp[1][i], dp[0][i-a]+sum(prefix[1], i-a+1, i))
			}
		}
	}
	return min(dp[0][m], dp[1][m])
}

func main() {
	reader := bufio.NewReader(os.Stdin)
	writer := bufio.NewWriter(os.Stdout)
	defer writer.Flush()

	var n, m, x, y int
	fmt.Fscanf(reader, "%d %d %d %d\n", &n, &m, &x, &y)
	picture := make([]string, n)
	for i := 0; i < n; i++ {
		fmt.Fscanf(reader, "%s\n", &picture[i])
	}

	fmt.Fprintf(writer, "%d\n", Solve(n, m, x, y, picture))
}

// Author: sighduck
// URL: https://codeforces.com/problemset/problem/225/C

package main

import (
	"bufio"
	"fmt"
	"math"
	"os"
)

func min(x int, y int) int {
	if x < y {
		return x
	}
	return y
}

func initDP(m int) [][]int {
	dp := make([][]int, 2)
	for i := 0; i < 2; i++ {
		dp[i] = make([]int, m+1)
		for j := 0; j <= m; j++ {
			dp[i][j] = math.MaxInt16
		}
	}
	dp[0][0] = 0
	dp[1][0] = 0
	return dp
}

func initPrefix(whites []int, n int, m int) [][]int {
	prefix := make([][]int, 2)
	for i := 0; i < 2; i++ {
		prefix[i] = make([]int, m+1)
	}
	for i := 1; i <= m; i++ {
		prefix[0][i] = prefix[0][i-1] + whites[i-1]
		prefix[1][i] = prefix[1][i-1] + n - whites[i-1]
	}
	return prefix
}

func sum(prefix []int, start int, end int) int {
	return prefix[end] - prefix[start-1]
}

func Solve(n int, m int, x int, y int, picture []string) int {
	whites := make([]int, m)
	for i := 0; i < n; i++ {
		for j := 0; j < m; j++ {
			if string(picture[i][j]) == "." {
				whites[j] += 1
			}
		}
	}
	dp := initDP(m)
	prefix := initPrefix(whites, n, m)
	for i := 0; i <= m; i++ {
		for a := x; a <= y; a++ {
			if i-a >= 0 {
				dp[0][i] = min(dp[0][i], dp[1][i-a]+sum(prefix[0], i-a+1, i))
				dp[1][i] = min(dp[1][i], dp[0][i-a]+sum(prefix[1], i-a+1, i))
			}
		}
	}
	return min(dp[0][m], dp[1][m])
}

func main() {
	reader := bufio.NewReader(os.Stdin)
	writer := bufio.NewWriter(os.Stdout)
	defer writer.Flush()

	var n, m, x, y int
	fmt.Fscanf(reader, "%d %d %d %d\n", &n, &m, &x, &y)
	picture := make([]string, n)
	for i := 0; i < n; i++ {
		fmt.Fscanf(reader, "%s\n", &picture[i])
	}

	fmt.Fprintf(writer, "%d\n", Solve(n, m, x, y, picture))
}


package main

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

const maxN = 100023

func rev(l int, r int, s *[maxN]int64) {
  for i, j := l, r; i <= j; i, j = i+1, j-1 {
    (*s)[i], (*s)[j] = (*s)[j], (*s)[i]
  }
}

func min(a, b int64) int64 {
  if a < b {
    return a
  }
  return b
}

func main() {
  in := bufio.NewReader(os.Stdin)
  out := bufio.NewWriter(os.Stdout)
  defer out.Flush()
  var tt int
  fmt.Fscan(in, &tt)
  for tc := 1; tc <= tt; tc++ {
    var n, k, mx int64
    fmt.Fscan(in, &n, &k)
    k--
    mx = 62
    if k >= (1 << min((n-1), mx)) {
      fmt.Fprintln(out, -1)
      continue
    }
    var perm[maxN] int64
    for i := 0; i < int(n); i++ {
      perm[i] = int64(i)
    }
    for r := 0 ; int64(r) < min(n-1, mx); {
      if k & (1 << r) != 0 {
        st := r
        for ; true; {
          r++
          if k & (1 << r) != 0 {
            continue
          }else {
            break
          }
        }
        rev(int(n) - 1 - r, int(n) - st - 1, &perm)
      }else {
        r++
        continue
      }
    }
    for i := 0; i < int(n); i++ {
      fmt.Fprint(out, perm[i]+1, " ")
    }
    fmt.Fprintln(out)
  }
}

package main

import (
	"bufio"
	. "fmt"
	"io"
	"os"
)

// github.com/EndlessCheng/codeforces-go
func CF1508B(_r io.Reader, _w io.Writer) {
	in := bufio.NewReader(_r)
	out := bufio.NewWriter(_w)
	defer out.Flush()

	var T, n int
	var k int64
	for Fscan(in, &T); T > 0; T-- {
		Fscan(in, &n, &k)
		if n < 61 && k > 1<<(n-1) {
			Fprintln(out, -1)
			continue
		}
		k--
		cur := 1
		for i := n - 2; i >= 0; i-- {
			if i > 59 || k>>i&1 == 0 {
				Fprint(out, cur, " ")
				cur++
				continue
			}
			st := i
			for ; i >= 0 && k>>i&1 > 0; i-- {
			}
			for j := st; j >= i; j-- {
				Fprint(out, cur+j-i, " ")
			}
			cur += st - i + 1
		}
		if cur == n {
			Fprint(out, n)
		}
		Fprintln(out)
	}
}
func main() { CF1508B(os.Stdin, os.Stdout) }

package main

import (
	"bufio"
	. "fmt"
	"os"
)

// github.com/EndlessCheng/codeforces-go
func main() {
	o := bufio.NewWriter(os.Stdout)
	var T, n int
	var k int64
	for Scan(&T); T > 0; T-- {
		Scan(&n, &k)
		if n < 61 && k > 1<<(n-1) {
			Fprintln(o, -1)
			continue
		}
		k--
		x := 1
		for i := n - 2; i >= 0; i-- {
			if i > 59 || k>>i&1 == 0 {
				Fprint(o, x, " ")
				x++
				continue
			}
			l := i
			for ; i >= 0 && k>>i&1 > 0; i-- {
			}
			for j := l; j >= i; j-- {
				Fprint(o, x+j-i, " ")
			}
			x += l - i + 1
		}
		if x == n {
			Fprint(o, n)
		}
		Fprintln(o)
	}
	o.Flush()
}

package main

import (
	"bufio"
	. "fmt"
	"io"
	"os"
)

// github.com/EndlessCheng/codeforces-go
func CF1508B(_r io.Reader, _w io.Writer) {
	in := bufio.NewReader(_r)
	out := bufio.NewWriter(_w)
	defer out.Flush()

	var T, n int
	var k int64
	for Fscan(in, &T); T > 0; T-- {
		Fscan(in, &n, &k)
		if n < 61 && k > 1<<(n-1) {
			Fprintln(out, -1)
			continue
		}
		k--
		cur := 1
		for i := n - 2; i >= 0; i-- {
			if i > 60 || k>>i&1 == 0 {
				Fprint(out, cur, " ")
				cur++
				continue
			}
			st := i
			for ; i >= 0 && k>>i&1 > 0; i-- {
			}
			for j := st; j >= i; j-- {
				Fprint(out, cur+j-i, " ")
			}
			cur += st - i + 1
		}
		if cur == n {
			Fprint(out, n)
		}
		Fprintln(out)
	}
}

func main() { CF1508B(os.Stdin, os.Stdout) }

package main

import (
	"bufio"
	"bytes"
	"fmt"
	"os"
)

func main() {
	reader := bufio.NewReader(os.Stdin)
	var buf bytes.Buffer

	tc := readNum(reader)

	for tc > 0 {
		tc--
		s, _ := reader.ReadBytes('\n')
		var n int
		pos := readInt(s, 0, &n)
		var k uint64
		readUint64(s, pos+1, &k)

		res := solve(n, int64(k))

		if len(res) == 0 {
			buf.WriteString("-1\n")
		} else {
			for i := 0; i < n; i++ {
				buf.WriteString(fmt.Sprintf("%d ", res[i]))
			}
			buf.WriteByte('\n')
		}
	}
	fmt.Print(buf.String())
}

func readInt(bytes []byte, from int, val *int) int {
	i := from
	sign := 1
	if bytes[i] == '-' {
		sign = -1
		i++
	}
	tmp := 0
	for i < len(bytes) && bytes[i] >= '0' && bytes[i] <= '9' {
		tmp = tmp*10 + int(bytes[i]-'0')
		i++
	}
	*val = tmp * sign
	return i
}

func readNum(reader *bufio.Reader) (a int) {
	bs, _ := reader.ReadBytes('\n')
	readInt(bs, 0, &a)
	return
}

func readTwoNums(reader *bufio.Reader) (a int, b int) {
	res := readNNums(reader, 2)
	a, b = res[0], res[1]
	return
}

func readThreeNums(reader *bufio.Reader) (a int, b int, c int) {
	res := readNNums(reader, 3)
	a, b, c = res[0], res[1], res[2]
	return
}

func readNNums(reader *bufio.Reader, n int) []int {
	res := make([]int, n)
	x := 0
	bs, _ := reader.ReadBytes('\n')
	for i := 0; i < n; i++ {
		for x < len(bs) && (bs[x] < '0' || bs[x] > '9') && bs[x] != '-' {
			x++
		}
		x = readInt(bs, x, &res[i])
	}
	return res
}

func readUint64(bytes []byte, from int, val *uint64) int {
	i := from

	var tmp uint64
	for i < len(bytes) && bytes[i] >= '0' && bytes[i] <= '9' {
		tmp = tmp*10 + uint64(bytes[i]-'0')
		i++
	}
	*val = tmp

	return i
}

const N = 100010

var F [N]int64

func init() {
	F[0] = 1
	F[1] = 1
	var sum int64 = 2

	for i := 2; i < N; i++ {
		F[i] = sum
		sum += F[i]
	}
}

func solve(n int, k int64) []int {
	if n < 62 && k > 1<<uint64(n-1) {
		return nil
	}
	k--
	P := make([]int, n)

	for b := 0; b <= min(60, n-1); b++ {
		if (k>>b)&1 == 1 {
			P[n-2-b] = 1
		}
	}
	ans := make([]int, 0, n)
	cur, sz := 1, 1
	for i := 0; i < n; i++ {
		if P[i] == 0 {
			for j := cur + sz - 1; j >= cur; j-- {
				ans = append(ans, j)
			}
			cur += sz
			sz = 1
		} else {
			sz++
		}
	}

	return ans
}

func min(a, b int) int {
	if a <= b {
		return a
	}
	return b
}

func reverse(arr []int) {
	for i, j := 0, len(arr)-1; i < j; i, j = i+1, j-1 {
		arr[i], arr[j] = arr[j], arr[i]
	}
}

package main

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

func main() {
	in := bufio.NewReader(os.Stdin)
	out := bufio.NewWriter(os.Stdout)
	defer out.Flush()
	var t int
	fmt.Fscan(in, &t)
	for t > 0 {
		t--
		var n int
		var k int64
		fmt.Fscan(in, &n, &k)
		dp := make([]int64, n+1)
		dp[n] = 1
		for i := n-1;i>=0;i-- {
			for j := 1; j <= n-i; j++ {
				dp[i] += dp[i+j]
				if dp[i] > k {
					dp[i] = k
					break
				}
			}
		}
		if dp[0] < k {
			fmt.Fprintln(out, -1)
			continue
		}
		for i := 0; i < n; i++ {
			for j := 1; j <= n-i; j++ {
				if dp[i+j] >= k {
					for k := i+j-1; k >= i; k-- {
						fmt.Fprint(out, k+1, " ")
					}
					i+=j-1
					break
				}else{
					k -= dp[i+j]
				}
			}
		}
		fmt.Fprint(out, "\n")
	}
}

package main

import (
	"bufio"
	"bytes"
	"fmt"
	"os"
)

func main() {
	reader := bufio.NewReader(os.Stdin)
	var buf bytes.Buffer

	tc := readNum(reader)

	for tc > 0 {
		tc--
		s, _ := reader.ReadBytes('\n')
		var n int
		pos := readInt(s, 0, &n)
		var k uint64
		readUint64(s, pos+1, &k)

		res := solve(n, int64(k))

		if len(res) == 0 {
			buf.WriteString("-1\n")
		} else {
			for i := 0; i < n; i++ {
				buf.WriteString(fmt.Sprintf("%d ", res[i]))
			}
			buf.WriteByte('\n')
		}
	}
	fmt.Print(buf.String())
}

func readInt(bytes []byte, from int, val *int) int {
	i := from
	sign := 1
	if bytes[i] == '-' {
		sign = -1
		i++
	}
	tmp := 0
	for i < len(bytes) && bytes[i] >= '0' && bytes[i] <= '9' {
		tmp = tmp*10 + int(bytes[i]-'0')
		i++
	}
	*val = tmp * sign
	return i
}

func readNum(reader *bufio.Reader) (a int) {
	bs, _ := reader.ReadBytes('\n')
	readInt(bs, 0, &a)
	return
}

func readTwoNums(reader *bufio.Reader) (a int, b int) {
	res := readNNums(reader, 2)
	a, b = res[0], res[1]
	return
}

func readThreeNums(reader *bufio.Reader) (a int, b int, c int) {
	res := readNNums(reader, 3)
	a, b, c = res[0], res[1], res[2]
	return
}

func readNNums(reader *bufio.Reader, n int) []int {
	res := make([]int, n)
	x := 0
	bs, _ := reader.ReadBytes('\n')
	for i := 0; i < n; i++ {
		for x < len(bs) && (bs[x] < '0' || bs[x] > '9') && bs[x] != '-' {
			x++
		}
		x = readInt(bs, x, &res[i])
	}
	return res
}

func readUint64(bytes []byte, from int, val *uint64) int {
	i := from

	var tmp uint64
	for i < len(bytes) && bytes[i] >= '0' && bytes[i] <= '9' {
		tmp = tmp*10 + uint64(bytes[i]-'0')
		i++
	}
	*val = tmp

	return i
}

const N = 100010

var F [N]int64

func init() {
	F[0] = 1
	F[1] = 1
	var sum int64 = 2

	for i := 2; i < N; i++ {
		F[i] = sum
		sum += F[i]
	}
}

func solve(n int, k int64) []int {
	if F[n] < k {
		return nil
	}

	P := make([]int, n)
	i := n
	cur := 1

	for i > 0 {
		j := i
		for i > 0 && F[i-1] < k {
			k -= F[i-1]
			i--
			cur++
		}
		i--
		// F[i-1] >= k
		x := cur
		for j > i {
			P[j-1] = x
			x--
			j--
		}
		cur++
	}
	reverse(P)
	return P
}

func reverse(arr []int) {
	for i, j := 0, len(arr)-1; i < j; i, j = i+1, j-1 {
		arr[i], arr[j] = arr[j], arr[i]
	}
}


package main

import (
	"fmt"
	// "time"
	// "log"
	"bufio"
	"os"
)

const N = 1007
var d [N]string
var n, m int

var root [N * 2]int
var adj [N * 2][]int
var ans[N * 2] int
var check[N * 2] int
var cycle bool = false

func get_root(r int) int {
	if root[r] < 0 {
		return r
	} else {
		root[r] = get_root(root[r])
		return root[r]
	}
}

func union(u, v int) {
	u = get_root(u)
	v = get_root(v)
	if u == v {
		return
	}
	if root[u] > root[v] {
		u, v = v, u
	}
	root[u] += root[v];
	root[v] = u
}

func dfs(u int) {
	if cycle || check[u] == 1 {
		cycle = true
		return
	}
	if check[u] == 2 {
		return
	}
	check[u] = 1
	ans[u] = 1
	for i := range(adj[u]) {
		v := adj[u][i]
		dfs(v)
		if ans[v] >= ans[u] {
			ans[u] = ans[v] + 1
		}
	}

	check[u] = 2
}

func main() {
	scanner := bufio.NewReader(os.Stdin)
	fmt.Fscanln(scanner, &n, &m)
	for i := 0; i < n + m; i++ {
		root[i] = -1
	}

	for i := 0; i < n; i++ {
		fmt.Fscanln(scanner, &d[i])
		for j := 0; j < m; j++ {
			if d[i][j] == '=' {
				union(i, j + n)
			}
		}
	}

	for i := 0; i < n; i++ {
		for j := 0; j < m && !cycle; j++ {
			if d[i][j] == '=' {
				continue
			}
			u, v := get_root(i), get_root(j + n)
			if u == v {
				cycle = true
			} else if d[i][j] == '>' {
				adj[u] = append(adj[u], v)
			} else if d[i][j] == '<' {
				adj[v] = append(adj[v], u)
			}
		}
	}

	for i := 0; i < n + m && !cycle; i++ {
		if get_root(i) == i && check[i] == 0 {
			dfs(i)
		}
	}
	if cycle {
		fmt.Println("No")
	} else {
		fmt.Println("Yes")
		for i := 0; i < n; i++ {
			fmt.Print(ans[get_root(i)], " ")
		}
		fmt.Println("")
		for i := 0; i < m; i++ {
			fmt.Print(ans[get_root(i + n)], " ")
		}
	}
}

package main

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

var (
	pre   []int
	incnt []int
	headD []*LinkD
	tailD []*LinkD
)

type LinkD struct {
	next *LinkD
	id   int
}

func findD(p int) int {
	if pre[p] == p {
		return p
	}
	pre[p] = findD(pre[p])
	return pre[p]
}
func mergeD(a, b int) {
	pa := findD(a)
	pb := findD(b)
	if pa == pb {
		return
	}

	pre[pa] = pb
}
func addD(from, to int) bool {
	pfrom := findD(from)
	pto := findD(to)
	if pfrom == pto {
		//	fmt.Printf("==%d %d %d %d\n",pfrom,pto,from,to)
		return false
	}
	p := &LinkD{
		next: headD[pfrom],
		id:   pto,
	}
	headD[pfrom] = p
	incnt[pto]++

	return true
}
func main() {
	var n int
	var m int
	buf := bufio.NewReader(os.Stdin)
	fmt.Fscanf(buf, "%d %d\n", &n, &m)
	strm := make([][]byte, n)
	ans := make([]int, n+m)
	pre = make([]int, n+m)
	incnt = make([]int, n+m)
	headD = make([]*LinkD, n+m)
	visit := make([]bool,m+n+1)
	for i := 0; i < n+m; i++ {
		pre[i] = i
		headD[i] = nil
	}
	for i := 0; i < n; i++ {
		strm[i] = make([]byte, m)
		fmt.Fscanf(buf, "%s\n", &strm[i])
		for j := 0; j < m; j++ {
			if strm[i][j] == '=' {
				mergeD(i, n+j)
			}
		}

	}
	//for i:= 0;i < n;i++{
	//	fmt.Printf("%s\n",strm[i])
	//}
	flag := true
	for i := 0; i < n; i++ {
		for j := 0; j < m; j++ {
			if strm[i][j] == '<' {
				if false == addD(i, j+n) {
					flag = false
				}
			} else if strm[i][j] == '>' {
				if false == addD(j+n, i) {
					flag = false
				}
			}
		}
	}
	//fmt.Printf("%v\n",incnt)
	if flag == false {
		fmt.Printf("No\n")
		return
	}
	que := make([]int, m+n+1)
	front := 0
	rear := 0
	for i := 0; i < n+m; i++ {
		if incnt[findD(i)] == 0 && visit[findD(i)]==false{
			que[rear] = findD(i)
			visit[que[rear]] = true
			//	fmt.Printf("d %d\n",que[rear])
			rear++
		}
	}
	for front < rear {
		to := headD[que[front]]

		for to != nil {
			nextp := findD(to.id)

			incnt[nextp]--
			if incnt[nextp] < 0{
				fmt.Printf("ERROR! front=%d nextp=%d ",que[front],nextp)
				return
			}
			if ans[nextp] < ans[que[front]]+1 {
				ans[nextp] = ans[que[front]] + 1
			}
			if incnt[nextp] == 0 {
				que[rear] = nextp
				rear++
			}
			to = to.next
		}
		front++
	}
	for i := 0; i < m+n; i++ {
		if incnt[findD(i)] > 0 {
			fmt.Printf("No\n")
			return
		}
	}
	fmt.Printf("Yes\n")
	for i := 0; i < n; i++ {
		fmt.Printf(" %d", ans[findD(i)]+1)

	}
	fmt.Printf("\n")
	for i := 0; i < m; i++ {
		fmt.Printf(" %d", ans[findD(n+i)]+1)
	}
	fmt.Printf("\n")
}

/**
3 3
<<<
<<=
<<=

3 2
<>
<=
>>

10 24
<><>>>><>>><>>>>>>>><<>>
<><>>>><>>><>>>>>>>><<>>
>><>>>><>>><>>>>>>>><>>>
<<<><><<<<<<><<><>>><<<>
<<<=<=<<<<<<><<=<>==<<<>
>><>>>><>>><>>>>>>>><>>>
>>>>>>>>>>>>>>>>>>>>>>>>
<<<<<<<<<<<<=<<<<=<<<<<<
<><>>>><>>><>>>>>>>><<>>
<><>>>><>>><>>>>>>>><<>>
 */

package main

import (
	"fmt"
	// "time"
	// "log"
	"bufio"
	"os"
)

const N = 1007
var d [N]string
var n, m int

var root [N * 2]int
var adj [N * 2][]int
var ans[N * 2] int
var check[N * 2] int
var cycle bool = false

func get_root(r int) int {
	if root[r] < 0 {
		return r
	} else {
		root[r] = get_root(root[r])
		return root[r]
	}
}

func union(u, v int) {
	u = get_root(u)
	v = get_root(v)
	if u == v {
		return
	}
	if root[u] > root[v] {
		u, v = v, u
	}
	root[u] += root[v];
	root[v] = u
}

func dfs(u int) {
	if cycle || check[u] == 1 {
		cycle = true
		return
	}
	if check[u] == 2 {
		return
	}
	check[u] = 1
	ans[u] = 1
	for i := range(adj[u]) {
		v := adj[u][i]
		dfs(v)
		if ans[v] >= ans[u] {
			ans[u] = ans[v] + 1
		}
	}

	check[u] = 2
}

func main() {
	scanner := bufio.NewReader(os.Stdin)
	fmt.Fscanf(scanner, "%d %d", &n, &m)

	for i := 0; i < n + m; i++ {
		root[i] = -1
	}

	for i := 0; i < n; i++ {
	  temp := ""
		fmt.Fscanf(scanner, "%s", &temp)
		fmt.Fscanf(scanner, "%s", &d[i])
		for j := 0; j < m; j++ {
			if d[i][j] == '=' {
				union(i, j + n)
			}
		}
	}

	for i := 0; i < n; i++ {
		for j := 0; j < m && !cycle; j++ {
			if d[i][j] == '=' {
				continue
			}
			u, v := get_root(i), get_root(j + n)
			if u == v {
				cycle = true
			} else if d[i][j] == '>' {
				adj[u] = append(adj[u], v)
			} else if d[i][j] == '<' {
				adj[v] = append(adj[v], u)
			}
		}
	}

	for i := 0; i < n + m && !cycle; i++ {
		if get_root(i) == i && check[i] == 0 {
			dfs(i)
		}
	}
	if cycle {
		fmt.Println("No")
	} else {
		fmt.Println("Yes")
		for i := 0; i < n; i++ {
			fmt.Print(ans[get_root(i)], " ")
		}
		fmt.Println("")
		for i := 0; i < m; i++ {
			fmt.Print(ans[get_root(i + n)], " ")
		}
	}
}

package main

import (
	"bufio"
	. "fmt"
	"io"
	"os"
)

func Sol1131D(reader io.Reader, writer io.Writer) {
	in := bufio.NewReader(reader)
	out := bufio.NewWriter(writer)
	defer out.Flush()

	var n, m int
	Fscan(in, &n, &m)
	fa := make([]int, n+m)
	for i := range fa {
		fa[i] = i
	}
	var find func(int) int
	find = func(x int) int {
		if fa[x] != x {
			fa[x] = find(fa[x])
		}
		return fa[x]
	}
	merge := func(from, to int) { fa[find(from)] = find(to) }

	cp := make([]string, n)
	for i := range cp {
		Fscan(in, &cp[i])
		for j, c := range cp[i] {
			if c == '=' {
				merge(n+j, i)
			}
		}
	}
	for i := range fa {
		find(i)
	}

	g := make([][]int, n+m)
	inDeg := make([]int, n+m)
	for i, s := range cp {
		for j, c := range s {
			if c == '=' {
				continue
			}
			v, w := fa[i], fa[n+j]
			if v == w {
				Fprint(out, "No")
				return
			}
			if c == '>' {
				v, w = w, v
			}
			g[v] = append(g[v], w)
			inDeg[w]++
		}
	}
	queue := []int{}
	ans := make([]int, n+m)
	cnt := 0
	for i, deg := range inDeg {
		if deg == 0 {
			queue = append(queue, i)
			ans[i] = 1
			cnt++
		}
	}
	for len(queue) > 0 {
		var v int
		v, queue = queue[0], queue[1:]
		for _, w := range g[v] {
			inDeg[w]--
			if inDeg[w] == 0 {
				queue = append(queue, w)
				ans[w] = ans[v] + 1
				cnt++
			}
		}
	}
	if cnt < n+m {
		Fprint(out, "No")
		return
	}
	Fprintln(out, "Yes")
	for i, o := range fa {
		if i == n {
			Fprintln(out)
		}
		Fprint(out, ans[o], " ")
	}
}

func main() {
	Sol1131D(os.Stdin, os.Stdout)
}

package main

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

var (
	pre   []int
	incnt []int
	headD []*LinkD
	tailD []*LinkD
)

type LinkD struct {
	next *LinkD
	id   int
}

func findD(p int) int {
	if pre[p] == p {
		return p
	}
	pre[p] = findD(pre[p])
	return pre[p]
}
func mergeD(a, b int) {
	pa := findD(a)
	pb := findD(b)
	if pa == pb {
		return
	}

	pre[pa] = pb
}
func addD(from, to int)bool {
	pfrom := findD(from)
	pto := findD(to)
	if pfrom==pto{
	//	fmt.Printf("==%d %d %d %d\n",pfrom,pto,from,to)
		return false
	}
	p := &LinkD{
		next: headD[pfrom],
		id:   pto,
	}
	headD[pfrom] = p
	incnt[pto]++
	//fmt.Printf("pf =%d pto=%d\n",pfrom ,pto)
	return true
}
func main() {
	var n int
	var m int
	buf := bufio.NewReader(os.Stdin)
	fmt.Fscanf(buf, "%d %d\n", &n, &m)
	strm := make([][]byte, n)
	ans := make([]int, n+m)
	pre = make([]int, n+m)
	incnt = make([]int, n+m)
	headD = make([]*LinkD, n+m)
	for i := 0; i < n+m; i++ {
		pre[i] = i
		headD[i] = nil
	}
	for i := 0; i < n; i++ {
		strm[i] = make([]byte,m)
		fmt.Fscanf(buf, "%s\n", &strm[i])
		for j := 0; j < m; j++ {
			if strm[i][j] == '=' {
				mergeD(i, n+j)
			}
		}

	}
	//for i:= 0;i < n;i++{
	//	fmt.Printf("%s\n",strm[i])
	//}
	flag := true
	for i := 0; i < n; i++ {
		for j := 0; j < m; j++ {
			if strm[i][j] == '<' {
				if false == addD(i, j+n){
					flag=false
				}
			} else if strm[i][j] == '>' {
				if false == addD(j+n, i){
					flag=false
				}
			}
		}
	}
	if flag == false{
		fmt.Printf("No\n")
		return
	}
	que := make([]int, m+n+1)
	front := 0
	rear := 0
	for i := 0; i < n+m; i++ {
		if incnt[findD(i)] == 0 {
			que[rear] = findD(i)
		//	fmt.Printf("d %d\n",que[rear])
			rear++
		}
	}
	for front<rear {
		to := headD[que[front]]
	//	nowp := headD[que[front]]
		for to!=nil {
			nextp := findD(to.id)
			incnt[nextp]--
			if ans[nextp] < ans[que[front]]+1{
				ans[nextp] = ans[que[front]]+1
			}
			if incnt[nextp] == 0 {
			//	fmt.Printf("d %d\n",nextp)
				que[rear] = nextp

				rear++
			}
			to = to.next
		}
		front++
	}
		for i:=0;i < m+n;i++ {
			if incnt[findD(i)] > 0 {
				fmt.Printf("No\n")
				return
			}
		}
	fmt.Printf("Yes\n")
	for i := 0; i < n; i++ {

		fmt.Printf(" %d", ans[findD(i)]+1)

	}
	fmt.Printf("\n")
	for i := 0; i < m; i++ {

		fmt.Printf(" %d", ans[findD(n+i)]+1)

	}
	fmt.Printf("\n")
}
/**
3 3
<<<
<<=
<<=

3 2
<>
<=
>>
 */

package main

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

var (
	pre   []int
	incnt []int
	headD []*LinkD
	tailD []*LinkD
)

type LinkD struct {
	next *LinkD
	id   int
}

func findD(p int) int {
	if pre[p] == p {
		return p
	}
	pre[p] = findD(pre[p])
	return pre[p]
}
func mergeD(a, b int) {
	pa := findD(a)
	pb := findD(b)
	if pa == pb {
		return
	}

	pre[pa] = pb
}
func addD(from, to int)bool {
	pfrom := findD(from)
	pto := findD(to)
	if pfrom==pto{
	//	fmt.Printf("==%d %d %d %d\n",pfrom,pto,from,to)
		return false
	}
	p := &LinkD{
		next: headD[pfrom],
		id:   pto,
	}
	headD[pfrom] = p
	incnt[pto]++
	//fmt.Printf("pf =%d pto=%d\n",pfrom ,pto)
	return true
}
func main() {
	var n int
	var m int
	buf := bufio.NewReader(os.Stdin)
	fmt.Fscanf(buf, "%d %d\n", &n, &m)
	strm := make([][]byte, n)
	ans := make([]int, n+m)
	pre = make([]int, n+m)
	incnt = make([]int, n+m)
	headD = make([]*LinkD, n+m)
	for i := 0; i < n+m; i++ {
		pre[i] = i
		headD[i] = nil
	}
	for i := 0; i < n; i++ {
		strm[i] = make([]byte,m)
		fmt.Fscanf(buf, "%s\n", &strm[i])
		for j := 0; j < m; j++ {
			if strm[i][j] == '=' {
				mergeD(i, n+j)
			}
		}
	}
	flag := true
	for i := 0; i < n; i++ {
		for j := 0; j < m; j++ {
			if strm[i][j] == '<' {
				if false == addD(i, j+n){
					flag=false
				}
			} else if strm[i][j] == '>' {
				if false == addD(j+n, i){
					flag=false
				}
			}
		}
	}
	if flag == false{
		fmt.Printf("No\n")
		return
	}
	que := make([]int, m+n+1)
	front := 0
	rear := 0
	for i := 0; i < n+m; i++ {
		if incnt[findD(i)] == 0 {
			que[rear] = findD(i)
		//	fmt.Printf("d %d\n",que[rear])
			rear++
		}
	}
	for front<rear {
		to := headD[que[front]]
	//	nowp := headD[que[front]]
		for to!=nil {
			nextp := findD(to.id)
			incnt[nextp]--
			if incnt[nextp] == 0 {
			//	fmt.Printf("d %d\n",nextp)
				que[rear] = nextp
				if ans[nextp] < ans[que[front]]+1{
					ans[nextp] = ans[que[front]]+1
				}
				rear++
			}
			to = to.next
		}
		front++
	}
		for i:=0;i < m+n;i++ {
			if incnt[findD(i)] > 0 {
				fmt.Printf("No\n")
				return
			}
		}
	fmt.Printf("Yes\n")
	for i := 0; i < n; i++ {

		fmt.Printf(" %d", ans[findD(i)]+1)

	}
	fmt.Printf("\n")
	for i := 0; i < m; i++ {

		fmt.Printf(" %d", ans[findD(n+i)]+1)

	}
	fmt.Printf("\n")
}
/**
3 3
<<<
<<=
<<=
 */

package main

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

var (
	pre   []int
	incnt []int
	headD []*LinkD
	tailD []*LinkD
)

type LinkD struct {
	next *LinkD
	id   int
}

func findD(p int) int {
	if pre[p] == p {
		return p
	}
	pre[p] = findD(pre[p])
	return pre[p]
}
func mergeD(a, b int) {
	pa := findD(a)
	pb := findD(b)
	if pa == pb {
		return
	}

	pre[pa] = pb
}
func addD(from, to int)bool {
	pfrom := findD(from)
	pto := findD(to)
	if pfrom==pto{
		return false
	}
	p := &LinkD{
		next: headD[pfrom],
		id:   pto,
	}
	headD[pfrom] = p
	incnt[pto]++
	//fmt.Printf("pf =%d pto=%d\n",pfrom ,pto)
	return true
}
func main() {
	var n int
	var m int
	buf := bufio.NewReader(os.Stdin)
	fmt.Fscanf(buf, "%d %d\n", &n, &m)
	strm := make([][]byte, n)
	ans := make([]int, n+m)
	pre = make([]int, n+m)
	incnt = make([]int, n+m)
	headD = make([]*LinkD, n+m)
	for i := 0; i < n+m; i++ {
		pre[i] = i
		headD[i] = nil
	}
	for i := 0; i < n; i++ {
		strm[i] = make([]byte,m)
		fmt.Fscanf(buf, "%s\n", &strm[i])
		for j := 0; j < m; j++ {
			if strm[i][j] == '=' {
				mergeD(i, n+j)
			}
		}
	}
	flag := true
	for i := 0; i < n; i++ {
		for j := 0; j < m; j++ {
			if strm[i][j] == '<' {
				if false == addD(i, j+n){
					flag=false
				}
			} else if strm[i][j] == '>' {
				if false == addD(j+n, i){
					flag=false
				}
			}
		}
	}
	if flag == false{
		fmt.Printf("No\n")
		return
	}
	que := make([]int, m+n+1)
	front := 0
	rear := 0
	for i := 0; i < n+m; i++ {
		if incnt[findD(i)] == 0 {
			que[rear] = findD(i)
		//	fmt.Printf("d %d\n",que[rear])
			rear++
		}
	}
	for front<rear {
		to := headD[que[front]]
	//	nowp := headD[que[front]]
		for to!=nil {
			nextp := findD(to.id)
			incnt[nextp]--
			if incnt[nextp] == 0 {
			//	fmt.Printf("d %d\n",nextp)
				que[rear] = nextp
				if ans[nextp] < ans[que[front]]+1{
					ans[nextp] = ans[que[front]]+1
				}
				rear++
			}
			to = to.next
		}
		front++
	}
	if front < n+m{
		fmt.Printf("No\n")
		return
	}
	fmt.Printf("Yes\n")
	for i := 0; i < n; i++ {

		fmt.Printf(" %d", ans[findD(i)]+1)

	}
	fmt.Printf("\n")
	for i := 0; i < m; i++ {

		fmt.Printf(" %d", ans[findD(n+i)]+1)

	}
	fmt.Printf("\n")
}

package main

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

var (
	strm [][]byte
)

func fuD(a, b int) byte {
	if a < b {
		return '<'
	} else if a > b {
		return '>'
	}
	return '='
}
func main() {
	var n int
	var m int
	buf := bufio.NewReader(os.Stdin)
	fmt.Fscanf(buf, "%d %d\n", &n, &m)
	strm = make([][]byte, n)
	ansm := make([]int, m)
	ansn := make([]int, n)
	for i := 0; i < n; i++ {
		strm[i] = make([]byte, m+1)
		fmt.Fscanf(buf, "%s\n", &strm[i])
	}

	flag := make([]bool, 8)
	ansn[0] = 4
	flag[4] = true
	for j := 0; j < m; j++ {
		if strm[0][j] == '=' {
			ansm[j] = 4
		} else if strm[0][j] == '<' {
			ansm[j] = 6

		} else {
			ansm[j] = 2
		}
		flag[ansm[j]] = true
	}

	pp := []int{4, 2, 6, 3, 5, 1, 7}
	ansf := true
	for i := 1; ansf && i < n; i++ {
		for k := 0; k < 7; k++ {
			tf := true
			for j := 0; j < m; j++ {
				if fuD(pp[k], ansm[j]) != strm[i][j] {
					tf = false
					break
				}
			}
			if tf {
				ansn[i] = pp[k]
				flag[pp[k]] = true
				break
			}
		}
		if ansn[i] <= 0 {
			ansf = false
		}
	}
//	fmt.Printf("ansm=%v\n",ansm)
//	fmt.Printf("ansn=%v\n",ansn)
	if ansf == false {
		fmt.Printf("No\n")
		return
	}
	pre := make([]int, 8)
	cnt := 0

	for i := 1; i <= 7; i++ {
		if flag[i] {
			cnt++
		}
		pre[i] = cnt
	}
	fmt.Printf("Yes\n")
	for i := 0; i < n; i++ {

		fmt.Printf(" %d", pre[ansn[i]])

	}
	fmt.Printf("\n")
	for i := 0; i < m; i++ {

		fmt.Printf(" %d", pre[ansm[i]])

	}
	fmt.Printf("\n")
}

package main

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

var (
	strm [][]byte
)

func fuD(a, b int) byte {
	if a < b {
		return '<'
	} else if a > b {
		return '>'
	}
	return '='
}
func main() {
	var n int
	var m int
	buf := bufio.NewReader(os.Stdin)
	fmt.Fscanf(buf, "%d %d\n", &n, &m)
	strm = make([][]byte, n)
	ansm := make([]int, m)
	ansn := make([]int, n)
	for i := 0; i < n; i++ {
		strm[i] = make([]byte, m+1)
		fmt.Fscanf(buf, "%s\n", &strm[i])
	}

	flag := make([]bool, 8)
	ansn[0] = 4
	for j := 0; j < m; j++ {
		if strm[0][j] == '=' {
			ansm[j] = 4
		} else if strm[0][j] == '<' {
			ansm[j] = 6

		} else {
			ansm[j] = 2
		}
		flag[ansm[j]] = true
	}

	pp := []int{4, 2, 6, 3, 5, 1, 7}
	ansf := true
	for i := 1; ansf && i < n; i++ {
		for k := 0; k < 7; k++ {
			tf := true
			for j := 0; j < m; j++ {
				if fuD(pp[k], ansm[j]) != strm[i][j] {
					tf = false
					break
				}
			}
			if tf {
				ansn[i] = pp[k]
				flag[pp[k]] = true
				break
			}
		}
		if ansn[i] <= 0 {
			ansf = false
		}
	}
//	fmt.Printf("ansm=%v\n",ansm)
//	fmt.Printf("ansn=%v\n",ansn)
	if ansf == false {
		fmt.Printf("No\n")
		return
	}
	pre := make([]int, 8)
	cnt := 0

	for i := 1; i <= 7; i++ {
		if flag[i] {
			cnt++
		}
		pre[i] = cnt
	}
	fmt.Printf("Yes\n")
	for i := 0; i < n; i++ {

		fmt.Printf(" %d", pre[ansn[i]])

	}
	fmt.Printf("\n")
	for i := 0; i < m; i++ {

		fmt.Printf(" %d", pre[ansm[i]])

	}
	fmt.Printf("\n")
}

package main

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

var (
	strm [][]byte
)

func fuD(a, b int) byte {
	if a < b {
		return '<'
	} else if a > b {
		return '>'
	}
	return '='
}
func main() {
	var n int
	var m int
	buf := bufio.NewReader(os.Stdin)
	fmt.Fscanf(buf, "%d %d\n", &n, &m)
	strm = make([][]byte, n)
	ansm := make([]int, m)
	ansn := make([]int, n)
	for i := 0; i < n; i++ {
		strm[i] = make([]byte, m+1)
		fmt.Fscanf(buf, "%s\n", &strm[i])
	}

	flag := make([]bool, 8)
	ansn[0] = 4
	for j := 0; j < m; j++ {
		if strm[0][j] == '=' {
			ansm[j] = 4
		} else if strm[0][j] == '<' {
			ansm[j] = 6

		} else {
			ansm[j] = 2
		}
		flag[ansm[j]] = true
	}

	pp := []int{4, 2, 6, 3, 5, 1, 7}
	ansf := true
	for i := 1; ansf && i < n; i++ {
		for k := 0; k < 7; k++ {
			tf := true
			for j := 0; j < m; j++ {
				if fuD(pp[k], ansm[j]) != strm[i][j] {
					tf = false
					break
				}
			}
			if tf {
				ansn[i] = pp[k]
				flag[pp[k]] = true
				break
			}
		}
		if ansn[i] <= 0 {
			ansf = false
		}
	}
//	fmt.Printf("ansm=%v\n",ansm)
//	fmt.Printf("ansn=%v\n",ansn)
	if ansf == false {
		fmt.Printf("No\n")
		return
	}
	pre := make([]int, 8)
	cnt := 0

	for i := 1; i <= 7; i++ {
		if flag[i] {
			cnt++
		}
		pre[i] = cnt
	}
	fmt.Printf("Yes\n")
	for i := 0; i < n; i++ {

		fmt.Printf("%d", pre[ansn[i]])

	}
	fmt.Printf("\n")
	for i := 0; i < m; i++ {

		fmt.Printf("%d", pre[ansm[i]])

	}
	fmt.Printf("\n")
}

package main

import (
	"bufio"
	. "fmt"
	"io"
	"os"
	"sort"
)

func Sol1131D(reader io.Reader, writer io.Writer) {
	min := func(a, b int) int {
		if a <= b {
			return a
		}
		return b
	}
	max := func(a, b int) int {
		if a >= b {
			return a
		}
		return b
	}
	unique := func(arr []int) (newArr []int) {
		n := len(arr)
		newArr = make([]int, 1, n)
		newArr[0] = arr[0]
		for i := 1; i < n; i++ {
			if arr[i] != arr[i-1] {
				newArr = append(newArr, arr[i])
			}
		}
		return
	}
	discrete := func(arr []int, start int) (newArr []interface{}) {
		n := len(arr)
		uniqueArr := make([]int, n)
		copy(uniqueArr, arr)
		sort.Ints(uniqueArr)
		uniqueArr = unique(uniqueArr)
		newArr = make([]interface{}, n)
		for i, v := range arr {
			newArr[i] = start + sort.Search(len(uniqueArr), func(j int) bool { return uniqueArr[j] >= v })
		}
		return
	}
	type dish struct {
		l, r int
	}

	in := bufio.NewReader(reader)
	out := bufio.NewWriter(writer)
	defer out.Flush()

	var n, m int
	Fscan(in, &n, &m)
	dishes1 := make([]dish, n)
	dishes2 := make([]dish, m)

	var symbols string
	Fscan(in, &symbols)
	for j, c := range symbols {
		d2 := &dishes2[j]
		if c == '<' {
			d2.l, d2.r = 1, 2000
		} else if c == '>' {
			d2.l, d2.r = -2000, -1
		}
	}
	for i := 1; i < n; i++ {
		l, r := -4000, 4000
		Fscan(in, &symbols)
		for j, c := range symbols {
			d2 := &dishes2[j]
			if c == '=' {
				if l == -4000 {
					l = d2.l
				} else if l != d2.l {
					Fprintln(out, "No")
					return
				}
				if r == 4000 {
					r = d2.r
				} else if r != d2.r {
					Fprintln(out, "No")
					return
				}
			} else if c == '<' {
				r = min(r, d2.l-1)
			} else {
				l = max(l, d2.r+1)
			}
			if l > r {
				Fprintln(out, "No")
				return
			}
		}
		dishes1[i].l, dishes1[i].r = l, r
	}

	var shown [8001]bool
	ans := []int{}
	for _, d := range append(dishes1, dishes2...) {
		if d.l >= 0 {
			d.l += 4000
		} else {
			d.l = d.r + 4000
		}
		shown[d.l] = true
		ans = append(ans, d.l)
	}
	var cnt [8001]int
	for i := 1; i < 8001; i++ {
		if shown[i] {
			cnt[i] = cnt[i-1] + 1
		}
	}

	pAns := discrete(ans, 1)
	Fprintln(out, "Yes")
	Fprintln(out, pAns[:len(dishes1)]...)
	Fprintln(out, pAns[len(dishes1):]...)
}

func main() {
	Sol1131D(os.Stdin, os.Stdout)
}

package main

import (
	"fmt"
)

const N = 1007
var d [N]string
var n, m int

var root [N * 2]int
var adj [N * 2][]int
var ans[N * 2] int
var check[N * 2] int
var cycle bool = false

func get_root(r int) int {
	if root[r] < 0 {
		return r
	} else {
		root[r] = get_root(root[r])
		return root[r]
	}
}

func union(u, v int) {
	u = get_root(u)
	v = get_root(v)
	if u == v {
		return
	}
	if root[u] > root[v] {
		u, v = v, u
	}
	root[u] += root[v];
	root[v] = u
}

func dfs(u int) {
	if cycle || check[u] == 1 {
		cycle = true
		return
	}
	check[u] = 1
	ans[u] = 1
	for i := range(adj[u]) {
		v := adj[u][i]
		dfs(v)
		if ans[v] >= ans[u] {
			ans[u] = ans[v] + 1
		}
	}

	check[u] = 2
}

func main() {
	fmt.Scan(&n, &m)
	for i := 0; i < n + m; i++ {
		root[i] = -1;
	}

	for i := 0; i < n; i++ {
		fmt.Scan(&d[i])
		for j := 0; j < m; j++ {
			if d[i][j] == '=' {
				union(i, j + n)
			}
		}
	}

	for i := 0; i < n; i++ {
		fmt.Scan(&d[i])
		for j := 0; j < m && !cycle; j++ {
			u, v := get_root(i), get_root(j + n)
			if u == v && d[u][v] == '=' {
				cycle = true
			} else if d[i][j] == '>' {
				adj[get_root(i)] = append(adj[get_root(i)], get_root(j + n))
			} else if d[i][j] == '<' {
				adj[get_root(j + n)] = append(adj[get_root(j + n)], get_root(i))
			}
		}
	}

	for i := 0; i < n + m && !cycle; i++ {
		if get_root(i) == i && check[i] == 0 {
			dfs(i)
		}
	}
	if cycle {
		fmt.Println("No")
	} else {
		fmt.Println("Yes")
		for i := 0; i < n; i++ {
			fmt.Print(ans[get_root(i)], " ")
		}
		fmt.Println("")
		for i := 0; i < m; i++ {
			fmt.Print(ans[get_root(i + n)], " ")
		}
	}
}


package main

import (
    "fmt"
    // "os"
)

func Btoi(b bool) int {
    if b {
        return 1
    }
    return 0
 }

func main()  {
    var (
        n int
        d bool = false
        ans string
        a string
    )

    fmt.Scan(&n)
    fmt.Scan(&a)

    d = ((n & 1) ^ 1) == 1

    for i := 0; i < n; i++ {
        if d {
            ans = string(a[i]) + ans
            d = false
        } else {
            ans = ans + string(a[i])
            d = true
        }
    }

    fmt.Println(ans)
}

package main

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

var reader = bufio.NewReader(os.Stdin)
var writer = bufio.NewWriter(os.Stdout)

func scanf(f string, a ...interface{})  { fmt.Fscanf(reader, f, a...) }
func printf(f string, a ...interface{}) { fmt.Fprintf(writer, f, a...) }

func getLine() string {
	s, _ := reader.ReadString('\n')
	if strings.HasSuffix(s, "\r\n") {
		s = s[:len(s)-2]
	} else if strings.HasSuffix(s, "\n") {
		s = s[:len(s)-1]
	}
	return s
}
func getLine2Int() (n int) {
	scanf("%d\n", &n)
	return
}
func getLine2Int2() (a, b int64) {
	scanf("%d %d\n", &a, &b)
	return
}
func getLine2Ints(n int) []int64 {
	ans := make([]int64, n)
	for i := 0; i < n; i++ {
		scanf("%d ", &ans[i])
	}
	scanf("%d\n", &ans[n-1])
	return ans
}

func pcheck(i bool) {
	if i {
		printf("Yes\n")
	} else {
		printf("No\n")
	}
}

var debug = true

func see(a interface{}) {
	if debug {
		printf("DEBUG:%v\n", a)
	}
}

func main() {
	defer writer.Flush()

	m := getLine2Int()
	s := getLine()
	m = (len(s) + 1) / 2
	d := make([]byte, len(s))
	left, right, j := m, m, m
	for i := 0; i < len(s); i++ {
		d[j-1] = s[i]
		if j*2 <= len(s) {
			right++
			j = right
		} else {
			left--
			j = left
		}
	}
	printf("%s\n", string(d))
}

package main

import "fmt"

func main() {
	var n int
	fmt.Scan(&n)
	var d bool
	if n%2 == 0 {
		d = true
	}
	var dec string
	fmt.Scan(&dec)
	var s string
	for i := 0; i < n; i++ {
		if d {
			s = string(dec[i]) + s
			d = false
		} else {
			s = s + string(dec[i])
			d = true
		}
	}
	fmt.Println(s)
}

	package main

	import (
		"fmt"
	)

	func main() {
		var n int
		var decodedWord string
		fmt.Scan(&n, &decodedWord)

		if n == 1 {
			fmt.Println(decodedWord)
			return
		}

		decodedWordRune := []rune(decodedWord)
		var encodedWord []rune
		var index = n - 2
		for ; index >= 0; index -= 2 {
			encodedWord = append(encodedWord, decodedWordRune[index])
		}

		index += 2
		index ^= 1

		for ; index < n; index += 2 {
			encodedWord = append(encodedWord, decodedWordRune[index])
		}

		fmt.Println(string(encodedWord))
	}

package main

import "fmt"
func main() {
	var n int
	var s string
	fmt.Scan(&n, &s)
	a := 0
	b := n - 1
	r := make([]byte, n)
	nowA := false
	for i := 0; i < n; i++ {
	    if nowA {
	        r[a] = s[n - i - 1]
	        a ++
	    } else {
	        r[b] = s[n - i - 1]
	        b --
	    }
	    nowA = !nowA
	}
	for _, b := range r {
	    fmt.Printf("%c", b)
	}
}

package main

import "fmt"
func main() {
	var n int
	var s string
	fmt.Scan(&n, &s)
	a := 0
	b := n - 1
	r := make([]byte, n)
	nowA := !true
	for i := 0; i < n; i++ {
	    if nowA {
	        r[a] = s[n - i - 1]
	        a ++
	    } else {
	        r[b] = s[n - i - 1]
	        b --
	    }
	    nowA = !nowA
	}
	for _, b := range r {
	    fmt.Printf("%c", b)
	}
}

package main

import "fmt"

func main() {
	n, s := 0, ""
	fmt.Scan(&n, &s)

	result := ""
	if n%2 == 1 {
		result, s, n = s[0:1], s[1:], n-1
	}

	for i := 0; i < n; i += 2 {
		result = s[i:i+1] + result + s[i+1:i+2]
	}
	fmt.Println(result)
}

package main

import (
	"fmt"
)

func main() {
	var str_len int
	var my_string string
	var output_string []byte
	fmt.Scan( &str_len,&my_string)

	input_slice := []byte(my_string)
	for i, v := range input_slice {
		if i%2 == 0 {
			output_string = append([]byte{v}, output_string...)

		} else {
			output_string = append(output_string, v)
		}
	}
	if str_len%2 != 0 {
		//reverse string
		l := len(output_string) - 1
		for i := 0; i < l; i++ {
			output_string[i], output_string[l] = output_string[l], output_string[i]

			l--
		}
	}
	fmt.Println(string(output_string))
}

package main

import "fmt"

func main() {
	var n int
	var word string
	fmt.Scanf("%d\n%s", &n, &word)

	var ans []rune

	for i, c := range word {
		if i%2 == 0 && n%2 == 1 || i%2 == 1 && n%2 == 0 {
			ans = append(ans, c)
		} else {
			ans = append([]rune{c}, ans...)
		}
	}

	fmt.Println(string(ans))
}

package main

import "fmt"

func main() {
	var n, i int
	var s, result string
	fmt.Scan(&n, &s)
	if n%2 == 1 {
		result = string(s[0])
		i++
	}
	for ; i < n; i += 2 {
		result = string(s[i]) + result + string(s[i+1])
	}
	fmt.Println(result)
}

package main

import "fmt"

func main() {
	var n, i int
	var s, result string
	fmt.Scan(&n, &s)
	if n%2 == 1 {
		result = string(s[0])
		i++
	}
	for ; i < n; {
		result = string(s[i]) + result + string(s[i+1])
		i += 2
	}
	fmt.Println(result)
}

package main

import (
	"bufio"
	"fmt"
	"math"
	"os"
	"sort"
	"strconv"
	"strings"
	"sync"
)

func main() {

	n := ScanInt64()
	s := ScanWord()
	ans := make([]byte, n)
	atTheEnd := true
	end := n - 1
	begin := 0
	for ; n > 0; n-- {
		if atTheEnd {
			ans[end] = s[n-1]
			end--
		} else {
			ans[begin] = s[n-1]
			begin++
		}
		atTheEnd = !atTheEnd

	}
	fmt.Println(string(ans))

}

/*********************** I/O ***********************/

var O chan string
var in *bufio.Scanner
var oWg *sync.WaitGroup
var P func(a ...interface{}) (n int, err error)

func init() {
	P = fmt.Println

	in = bufio.NewScanner(os.Stdin)
	in.Buffer(make([]byte, 1024), int(1e+9))
	in.Split(bufio.ScanWords)

	O = make(chan string, 16)
	oWg = &sync.WaitGroup{}
	oWg.Add(1)

	writer := bufio.NewWriter(os.Stdout)
	go func() {
		defer oWg.Done()
		defer writer.Flush()

		for line := range O {
			writer.WriteString(line + "\n")
		}
	}()
}

func ScanWord() string { in.Scan(); return in.Text() }
func ScanInt() int     { i, _ := strconv.Atoi(ScanWord()); return i }
func ScanInt64() int64 { i, _ := strconv.ParseInt(ScanWord(), 10, 64); return i }
func ScanStringSlice(n int) []string {
	s := make([]string, n)
	for i := 0; i < n; i++ {
		s[i] = ScanWord()
	}
	return s
}
func ScanIntSlice(n int) []int {
	arr := make([]int, n)
	for i := 0; i < n; i++ {
		arr[i] = ScanInt()
	}
	return arr
}
func ScanInt64Slice(n int) []int64 {
	arr := make([]int64, n)
	for i := 0; i < n; i++ {
		arr[i] = ScanInt64()
	}
	return arr
}

/*********************** Utils ***********************/

func S(v interface{}) string { return fmt.Sprintf("%v", v) }
func SArr(a []int) string {
	sb := strings.Builder{}
	sb.Grow(len(a) * 9)
	for i := range a {
		sb.WriteString(strconv.Itoa(a[i]) + " ")
	}
	return sb.String()
}
func SArr64(a []int64) string {
	sb := strings.Builder{}
	sb.Grow(len(a) * 9)
	for i := range a {
		sb.WriteString(strconv.FormatInt(a[i], 10) + " ")
	}
	return sb.String()
}
func MnMx(args []int64) (int64, int64) {
	minVal, maxVal := int64(math.MaxInt64), int64(math.MinInt64)
	for _, v := range args {
		if v < minVal {
			minVal = v
		}
		if v > maxVal {
			maxVal = v
		}
	}
	return minVal, maxVal
}
func Mn(args []int64) int64 { mn, _ := MnMx(args); return mn }
func Mx(args []int64) int64 { _, mx := MnMx(args); return mx }
func LCM(a, b int64) int64  { return a / GCD(a, b) * b }
func GCD(a, b int64) int64 {
	if a == 0 {
		return b
	}
	return GCD(b%a, a)
}
func sortInt64Slice(a []int64) { sort.Slice(a, func(i, j int) bool { return a[i] < a[j] }) }
func abs(x int64) int64 {
	if x < 0 {
		return -x
	}
	return x
}
func MinimumMaximum(a, b int64) (int64, int64) {
	if a < b {
		return a, b
	}
	return b, a

}
func Minimum(a, b int64) int64 {
	min, _ := MinimumMaximum(a, b)
	return min

}
func Maximum(a, b int64) int64 {
	_, max := MinimumMaximum(a, b)
	return max

}

package main

import "fmt"

func main() {
	var n int
	var s string
	var r []byte

	fmt.Scanf("%d\n", &n)
	fmt.Scanf("%s\n", &s)

	if n%2 == 0 {
		var mundur int = 2
		var maju int = 1
		r = make([]byte, n)

		r[n/2-1] = s[0]

		for i := n/2 - 1 - 1; i > -1; i-- {
			r[i] = s[mundur]
			mundur += 2
		}

		for i := n / 2; i < n; i++ {
			r[i] = s[maju]
			maju += 2
		}
	} else {
		var mundur int = 1
		var maju int = 2
		r = make([]byte, n)

		r[n/2] = s[0]

		for i := n/2 - 1; i > -1; i-- {
			r[i] = s[mundur]
			mundur += 2
		}

		for i := n/2 + 1; i < n; i++ {
			r[i] = s[maju]
			maju += 2
		}
	}

	fmt.Println(string(r))
}

package main

import (
	"bufio"
	"fmt"
	"io"
	"os"
	"regexp"
)

func main() {
	var n int
	if _, err := fmt.Scanf("%d\n", &n); err != nil {
		return
	}

	reader := bufio.NewReader(os.Stdin)
	re := regexp.MustCompile(`\r?\n`)

	if s, err := reader.ReadString('\n'); err != nil {
		if err != io.EOF {
			return
		}
	} else {
		s = re.ReplaceAllString(s, "")

		o := make([]rune, n)
		l := 0
		r := n - 1
		for i := 0; i < n; i++ {
			j := n - i - 1
			if i%2 == 0 {
				o[r] = rune(s[j])
				r--
			} else {
				o[l] = rune(s[j])
				l++
			}
		}

		fmt.Println(string(o))
	}
}

package main

import "fmt"

func main() {
	var n, i int
	var s, result string
	fmt.Scan(&n, &s)
	fmt.Println(s[:n])
	if n%2 == 1 {
		result = string(s[0])
		i++
	}
	for ; i < n; i += 2 {
		result = string(s[i]) + result + string(s[i+1])
	}
	fmt.Println(result)
}

package main

import "fmt"

func main() {
	var n int
	var ss string
	var output []rune
	fmt.Scan(&n)
	fmt.Scan(&ss)
	s := []rune(ss)
	mid := n / 2
	if n%2 != 0 {
		output = append(output, s[mid])
		for i := 1; i <= mid; i++ {
			output = append(output, s[mid-i])
			output = append(output, s[mid+i])
		}
	} else {
		mid--
		for i := 0; i <= mid; i++ {
			output = append(output, s[mid-i])
			output = append(output, s[mid+i+1])
		}
	}
	fmt.Println(string(output))
}

package main

import (
	"fmt"
)

func main()  {
	var str_len int
	var my_string string
	var output_string []byte
	fmt.Scanf("%d",&str_len)
	fmt.Scanf("%s",&my_string)
	input_slice := []byte(my_string)
		for i,v := range input_slice{
			if i % 2 == 0{
				output_string = append([]byte{v},output_string...)

			}else {
				output_string = append(output_string,v)
			}
		}
		if str_len % 2 !=0{
			//reverse string
			l:=len(output_string)-1
			for i:=0 ; i < l ;i++{
				output_string[i] , output_string[l] = output_string[l] , output_string[i]

				l--
			}
		}
		fmt.Println(string(output_string))
}

package main

import (
	"fmt"
)

func main()  {
	var str_len int
	var my_string string
	var output_string []byte
	fmt.Scanf("%d",&str_len)
	fmt.Scanf("%s",&my_string)
	input_slice := []byte(my_string)
		for i,v := range input_slice{
			if i % 2 == 0{
				output_string = append([]byte{v},output_string...)

			}else {
				output_string = append(output_string,v)
			}
		}
		if str_len % 2 !=0{
			//reverse string
			l:=len(output_string)-1
			for i:=0 ; i < l ;i++{
				output_string[i] , output_string[l] = output_string[l] , output_string[i]

				l--
			}
		}
		fmt.Printf("%s",output_string)
}

package main

import (
	"fmt"
)

func main()  {
	var str_len int
	var my_string string
	var output_string []byte
	fmt.Scanf("%d",&str_len)
	fmt.Scanf("%s",&my_string)
	input_slice := []byte(my_string)
fmt.Println(input_slice)
		for i,v := range input_slice{
			if i % 2 == 0{
				output_string = append([]byte{v},output_string...)

			}else {
				output_string = append(output_string,v)
			}
		}
		if str_len % 2 !=0{
			//reverse string
			l:=len(output_string)-1
			for i:=0 ; i < l ;i++{
				output_string[i] , output_string[l] = output_string[l] , output_string[i]

				l--
			}
		}

		fmt.Printf("%s",output_string)

}