```go
package main
import (
"bufio"
"fmt"
"os"
)
const INF = 1e9
type Edge struct {
to int
rev int
cap int
flow int
}
var (
head [][]int
edges []Edge
level []int
ptr []int
)
func addEdge(from, to, cap int) int {
id := len(edges)
edges = append(edges, Edge{to, id + 1, cap, 0})
edges = append(edges, Edge{from, id, 0, 0})
head[from] = append(head[from], id)
head[to] = append(head[to], id + 1)
return id
}
func bfs(s, t int) bool {
for i := range level {
level[i] = -1
}
level[s] = 0
q := []int{s}
for len(q) > 0 {
u := q[0]
q = q[1:]
for _, id := range head[u] {
e := edges[id]
if e.cap-e.flow > 0 && level[e.to] == -1 {
level[e.to] = level[u] + 1
q = append(q, e.to)
}
}
}
return level[t] != -1
}
func dfs(u, t, pushed int) int {
if pushed == 0 || u == t {
return pushed
}
for ; ptr[u] < len(head[u]); ptr[u]++ {
id := head[u][ptr[u]]
e := edges[id]
if level[u]+1 != level[e.to] || e.cap-e.flow == 0 {
continue
}
tr := dfs(e.to, t, min(pushed, e.cap-e.flow))
if tr == 0 {
continue
}
edges[id].flow += tr
edges[edges[id].rev].flow -= tr
return tr
}
return 0
}
func min(a, b int) int {
if a < b {
return a
}
return b
}
func main() {
reader := bufio.NewReader(os.Stdin)
writer := bufio.NewWriter(os.Stdout)
defer writer.Flush()
var n, m int
fmt.Fscan(reader, &n, &m)
s := make([]int, n)
for i := 0; i < n; i++ {
fmt.Fscan(reader, &s[i])
}
a := make([]int, n)
for i := 0; i < n; i++ {
fmt.Fscan(reader, &a[i])
}
us := make([]int, m)
vs := make([]int, m)
deg := make([]int, n)
for i := 0; i < m; i++ {
fmt.Fscan(reader, &us[i], &vs[i])
us[i]--
vs[i]--
deg[us[i]]++
deg[vs[i]]++
}
for i := 0; i < n; i++ {
if s[i] == 1 {
val := a[i] + deg[i]
if val%2 != 0 || a[i] > deg[i] || a[i] < -deg[i] {
fmt.Fprintln(writer, "NO")
return
}
}
}
din := make([]int, n)
for i := 0; i < m; i++ {
din[vs[i]]++
}
source := n
sink := n + 1
numNodes := n + 2
head = make([][]int, numNodes)
level = make([]int, numNodes)
ptr = make([]int, numNodes)
edges = make([]Edge, 0, 2*m+4*n)
edgeToFlowIdx := make([]int, m)
for i := 0; i < m; i++ {
edgeToFlowIdx[i] = addEdge(vs[i], us[i], 1)
}
type Check struct {
edgeIdx int
req int
}
var checks []Check
for i := 0; i < n; i++ {
if s[i] == 1 {
req := (a[i] + deg[i]) / 2
diff := req - din[i]
if diff > 0 {
idx := addEdge(i, sink, diff)
checks = append(checks, Check{idx, diff})
} else if diff < 0 {
idx := addEdge(source, i, -diff)
checks = append(checks, Check{idx, -diff})
}
} else {
addEdge(source, i, INF)
addEdge(i, sink, INF)
}
}
for bfs(source, sink) {
for i := range ptr {
ptr[i] = 0
}
for {
pushed := dfs(source, sink, INF)
if pushed == 0 {
break
}
}
}
for _, c := range checks {
if edges[c.edgeIdx].flow != c.req {
fmt.Fprintln(writer, "NO")
return
}
}
fmt.Fprintln(writer, "YES")
for i := 0; i < m; i++ {
fIdx := edgeToFlowIdx[i]
u, v := us[i]+1, vs[i]+1
if edges[fIdx].flow == 1 {
fmt.Fprintln(writer, v, u)
} else {
fmt.Fprintln(writer, u, v)
}
}
}
```