```go
package main
import (
"bufio"
"fmt"
"os"
)
type DSU struct {
parent []int
rank []int
parity []int
}
func NewDSU(n int) *DSU {
parent := make([]int, n+1)
rank := make([]int, n+1)
parity := make([]int, n+1)
for i := 1; i <= n; i++ {
parent[i] = i
}
return &DSU{parent: parent, rank: rank, parity: parity}
}
func (d *DSU) find(x int) (int, int) {
if d.parent[x] == x {
return x, 0
}
root, par := d.find(d.parent[x])
d.parity[x] ^= par
d.parent[x] = root
return d.parent[x], d.parity[x]
}
func (d *DSU) union(x, y, par int) bool {
rx, px := d.find(x)
ry, py := d.find(y)
if rx == ry {
return (px^py) == par
}
if d.rank[rx] < d.rank[ry] {
rx, ry = ry, rx
px, py = py, px
}
d.parent[ry] = rx
d.parity[ry] = px ^ py ^ par
if d.rank[rx] == d.rank[ry] {
d.rank[rx]++
}
return true
}
func main() {
in := bufio.NewReader(os.Stdin)
out := bufio.NewWriter(os.Stdout)
defer out.Flush()
var n, m, q int
fmt.Fscan(in, &n, &m, &q)
id := make(map[string]int, n)
for i := 1; i <= n; i++ {
var s string
fmt.Fscan(in, &s)
id[s] = i
}
dsu := NewDSU(n)
for i := 0; i < m; i++ {
var t int
var x, y string
fmt.Fscan(in, &t, &x, &y)
u := id[x]
v := id[y]
want := 0
if t == 2 {
want = 1
}
if dsu.union(u, v, want) {
fmt.Fprintln(out, "YES")
} else {
fmt.Fprintln(out, "NO")
}
}
for i := 0; i < q; i++ {
var x, y string
fmt.Fscan(in, &x, &y)
u := id[x]
v := id[y]
ru, pu := dsu.find(u)
rv, pv := dsu.find(v)
if ru != rv {
fmt.Fprintln(out, 3)
} else {
if (pu ^ pv) == 0 {
fmt.Fprintln(out, 1)
} else {
fmt.Fprintln(out, 2)
}
}
}
}
```