← Home
package main

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

type Edge struct {
	to    int
	index int
}

func main() {
	reader := bufio.NewReader(os.Stdin)
	writer := bufio.NewWriter(os.Stdout)
	defer writer.Flush()

	var n, m int
	if _, err := fmt.Fscan(reader, &n, &m); err != nil {
		return
	}

	req := make([]int64, n+1)
	for i := 1; i <= n; i++ {
		fmt.Fscan(reader, &req[i])
	}

	adj := make([][]Edge, n+1)
	for i := 1; i <= m; i++ {
		var u, v int
		fmt.Fscan(reader, &u, &v)
		adj[u] = append(adj[u], Edge{v, i})
		adj[v] = append(adj[v], Edge{u, i})
	}

	visited := make([]bool, n+1)
	color := make([]int, n+1)
	parentNode := make([]int, n+1)
	parentEdge := make([]int, n+1)
	postOrder := make([]int, 0, n)

	odd_edge_idx := -1
	odd_edge_u := -1
	odd_edge_v := -1

	var dfs func(u, p, pEdge, c int)
	dfs = func(u, p, pEdge, c int) {
		visited[u] = true
		color[u] = c
		parentNode[u] = p
		parentEdge[u] = pEdge
		for _, edge := range adj[u] {
			v := edge.to
			idx := edge.index
			if v == p {
				continue
			}
			if visited[v] {
				if color[v] == color[u] && odd_edge_idx == -1 {
					odd_edge_idx = idx
					odd_edge_u = u
					odd_edge_v = v
				}
			} else {
				dfs(v, u, idx, c^1)
			}
		}
		postOrder = append(postOrder, u)
	}

	dfs(1, 0, 0, 0)

	var S0, S1 int64
	for i := 1; i <= n; i++ {
		if color[i] == 0 {
			S0 += req[i]
		} else {
			S1 += req[i]
		}
	}

	ans := make([]int64, m+1)

	if S0 != S1 {
		if odd_edge_idx == -1 {
			fmt.Fprintln(writer, "NO")
			return
		}
		W := (S0 - S1) / 2
		if color[odd_edge_u] == 1 {
			W = (S1 - S0) / 2
		}
		ans[odd_edge_idx] = W
		req[odd_edge_u] -= W
		req[odd_edge_v] -= W
	}

	for _, u := range postOrder {
		if parentNode[u] != 0 {
			w := req[u]
			ans[parentEdge[u]] = w
			req[u] -= w
			req[parentNode[u]] -= w
		}
	}

	if req[postOrder[len(postOrder)-1]] != 0 {
		fmt.Fprintln(writer, "NO")
		return
	}

	fmt.Fprintln(writer, "YES")
	for i := 1; i <= m; i++ {
		fmt.Fprintln(writer, ans[i])
	}
}