← Home
package main

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

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	scanner.Split(bufio.ScanWords)
	scanner.Buffer(make([]byte, 1024*1024), 10*1024*1024)

	if !scanner.Scan() {
		return
	}
	n, _ := strconv.Atoi(scanner.Text())
	scanner.Scan()
	m, _ := strconv.Atoi(scanner.Text())
	scanner.Scan()
	k, _ := strconv.Atoi(scanner.Text())

	patterns := make(map[string]int, n)
	for i := 1; i <= n; i++ {
		scanner.Scan()
		patterns[scanner.Text()] = i
	}

	adj := make([][]int, n+1)

	for j := 0; j < m; j++ {
		scanner.Scan()
		s := scanner.Text()
		scanner.Scan()
		mt, _ := strconv.Atoi(scanner.Text())

		matched := false
		limit := 1 << k
		for mask := 0; mask < limit; mask++ {
			cand := make([]byte, k)
			for i := 0; i < k; i++ {
				if (mask & (1 << i)) != 0 {
					cand[i] = s[i]
				} else {
					cand[i] = '_'
				}
			}
			if idx, exists := patterns[string(cand)]; exists {
				if idx == mt {
					matched = true
				} else {
					adj[mt] = append(adj[mt], idx)
				}
			}
		}

		if !matched {
			fmt.Println("NO")
			return
		}
	}

	state := make([]int, n+1)
	topo := make([]int, 0, n)

	var dfs func(int) bool
	dfs = func(u int) bool {
		state[u] = 1
		for _, v := range adj[u] {
			if state[v] == 1 {
				return false
			}
			if state[v] == 0 {
				if !dfs(v) {
					return false
				}
			}
		}
		state[u] = 2
		topo = append(topo, u)
		return true
	}

	for i := 1; i <= n; i++ {
		if state[i] == 0 {
			if !dfs(i) {
				fmt.Println("NO")
				return
			}
		}
	}

	fmt.Println("YES")
	out := bufio.NewWriter(os.Stdout)
	for i := len(topo) - 1; i >= 0; i-- {
		fmt.Fprintf(out, "%d", topo[i])
		if i > 0 {
			fmt.Fprint(out, " ")
		}
	}
	fmt.Fprintln(out)
	out.Flush()
}