package main
import (
"bufio"
"fmt"
"os"
"strconv"
)
const INF = 1e9
type Edge struct {
to, cap, flow, rev int
}
var graph [][]Edge
var level []int
var ptr []int
var scanner *bufio.Scanner
func nextInt() int {
scanner.Scan()
res, _ := strconv.Atoi(scanner.Text())
return res
}
func addEdge(from, to, cap int) {
graph[from] = append(graph[from], Edge{to, cap, 0, len(graph[to])})
graph[to] = append(graph[to], Edge{from, 0, 0, len(graph[from]) - 1})
}
func bfs(s, t int) bool {
for i := range level {
level[i] = -1
}
level[s] = 0
queue := []int{s}
for len(queue) > 0 {
v := queue[0]
queue = queue[1:]
for _, edge := range graph[v] {
if edge.cap-edge.flow > 0 && level[edge.to] == -1 {
level[edge.to] = level[v] + 1
queue = append(queue, edge.to)
}
}
}
return level[t] != -1
}
func dfs(v, t, pushed int) int {
if pushed == 0 {
return 0
}
if v == t {
return pushed
}
for i := ptr[v]; i < len(graph[v]); i++ {
ptr[v] = i
edge := graph[v][i]
tr := edge.to
if level[v]+1 != level[tr] || edge.cap-edge.flow == 0 {
continue
}
push := pushed
if edge.cap-edge.flow < push {
push = edge.cap - edge.flow
}
p := dfs(tr, t, push)
if p == 0 {
continue
}
graph[v][i].flow += p
graph[tr][edge.rev].flow -= p
return p
}
return 0
}
func dinic(s, t int) int {
flow := 0
for bfs(s, t) {
for i := range ptr {
ptr[i] = 0
}
for {
pushed := dfs(s, t, INF)
if pushed == 0 {
break
}
flow += pushed
}
}
return flow
}
func main() {
scanner = bufio.NewScanner(os.Stdin)
scanner.Split(bufio.ScanWords)
buf := make([]byte, 1024*1024)
scanner.Buffer(buf, 1024*1024)
if !scanner.Scan() {
return
}
n, _ := strconv.Atoi(scanner.Text())
m := nextInt()
s := make([]int, n+1)
for i := 1; i <= n; i++ {
s[i] = nextInt()
}
a := make([]int, n+1)
for i := 1; i <= n; i++ {
a[i] = nextInt()
}
type InputEdge struct {
u, v int
from, to int
idx int
}
inputEdges := make([]InputEdge, m)
initialB := make([]int, n+1)
graph = make([][]Edge, n+4)
level = make([]int, n+4)
ptr = make([]int, n+4)
for i := 0; i < m; i++ {
u := nextInt()
v := nextInt()
inputEdges[i] = InputEdge{u: u, v: v}
initialB[u]--
initialB[v]++
from := v
to := u
inputEdges[i].from = from
inputEdges[i].to = to
inputEdges[i].idx = len(graph[from])
addEdge(from, to, 1)
}
R := n + 1
SS := n + 2
TT := n + 3
reqFlow := 0
balR := 0
writer := bufio.NewWriter(os.Stdout)
defer writer.Flush()
for i := 1; i <= n; i++ {
if s[i] == 1 {
diff := a[i] - initialB[i]
if diff < 0 {
diff = -diff
}
if diff%2 != 0 {
fmt.Fprintln(writer, "NO")
return
}
bal := (initialB[i] - a[i]) / 2
if bal > 0 {
addEdge(SS, i, bal)
reqFlow += bal
} else if bal < 0 {
addEdge(i, TT, -bal)
}
balR -= bal
} else {
addEdge(i, R, INF)
addEdge(R, i, INF)
}
}
if balR > 0 {
addEdge(SS, R, balR)
reqFlow += balR
} else if balR < 0 {
addEdge(R, TT, -balR)
}
maxFlow := dinic(SS, TT)
if maxFlow != reqFlow {
fmt.Fprintln(writer, "NO")
} else {
fmt.Fprintln(writer, "YES")
for i := 0; i < m; i++ {
from := inputEdges[i].from
idx := inputEdges[i].idx
if graph[from][idx].flow > 0 {
fmt.Fprintf(writer, "%d %d\n", inputEdges[i].v, inputEdges[i].u)
} else {
fmt.Fprintf(writer, "%d %d\n", inputEdges[i].u, inputEdges[i].v)
}
}
}
}