← Home
```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)
		}
	}
}
```