In the country there are n cities and m bidirectional roads between them. Each city has an army. Army of the i-th city consists of a_{i} soldiers. Now soldiers roam. After roaming each soldier has to either stay in his city or to go to the one of neighboring cities by at moving along at most one road.

Check if is it possible that after roaming there will be exactly b_{i} soldiers in the i-th city.


-----Input-----

First line of input consists of two integers n and m (1 ≤ n ≤ 100, 0 ≤ m ≤ 200).

Next line contains n integers a_1, a_2, ..., a_{n} (0 ≤ a_{i} ≤ 100).

Next line contains n integers b_1, b_2, ..., b_{n} (0 ≤ b_{i} ≤ 100).

Then m lines follow, each of them consists of two integers p and q (1 ≤ p, q ≤ n, p ≠ q) denoting that there is an undirected road between cities p and q. 

It is guaranteed that there is at most one road between each pair of cities.


-----Output-----

If the conditions can not be met output single word "NO".

Otherwise output word "YES" and then n lines, each of them consisting of n integers. Number in the i-th line in the j-th column should denote how many soldiers should road from city i to city j (if i ≠ j) or how many soldiers should stay in city i (if i = j).

If there are several possible answers you may output any of them.


-----Examples-----
Input
4 4
1 2 6 3
3 5 3 1
1 2
2 3
3 4
4 2

Output
YES
1 0 0 0 
2 0 0 0 
0 5 1 0 
0 0 2 1 

Input
2 0
1 2
2 1

Output
NO

Difficulty: HARD
Tags: Flows and cuts

Graph algorithms

Mathematics

Starter code:

Solutions:
import sys

def BFS(parent, graph, source, sink):
	visited = [False] * len(parent)
	queue = []
	queue.append(source)
	visited[source] = True
	while queue:
		currNode = queue.pop(0)
		for nextNode in range(len(parent)):
			if visited[nextNode] == False and graph[currNode][nextNode] > 0:
				if nextNode == sink:
					parent[nextNode] = currNode
					return True
				queue.append(nextNode)
				visited[nextNode] = True
				parent[nextNode] = currNode
	return False

def fordFulkerson(graph, source, sink):
	parent = [-1] * len(graph)
	maxFlow = 0
	while BFS(parent, graph, source, sink):
		currFlow = float('Inf')
		node = sink
		while node != 0:
			currFlow = min(currFlow, graph[parent[node]][node])
			node = parent[node]
		maxFlow += currFlow
		node = sink
		while node != 0:
			prevNode = parent[node]
			graph[prevNode][node] -= currFlow
			graph[node][prevNode] += currFlow
			node = parent[node]
	return maxFlow

def printGraph(graph, nodes):
	g = [[0 for c in range(nodes)] for r in range(nodes)]
	for n in range(1, nodes + 1):
		currNode = n + nodes
		num = 0
		for prevNode in range(len(graph[currNode]) - 1):
			cap = graph[currNode][prevNode]
			if cap > 0:
				g[prevNode - 1][n - 1] = cap
	stringGraph = ''
	for r in range(nodes):
		num = 0
		for c in range(nodes):
			print(g[r][c], end=' ')
		print()
	return stringGraph
(nodes, edges) = sys.stdin.readline().split()
inputCap = sys.stdin.readline().split()
outputCap = sys.stdin.readline().split()
nodes = int(nodes)
edges = int(edges)
totalInput = sum((int(i) for i in inputCap))
totalOutput = sum((int(i) for i in outputCap))
if totalInput != totalOutput:
	print('NO')
else:
	graph = [[0 for c in range(nodes * 2 + 2)] for r in range(nodes * 2 + 2)]
	for i in range(len(inputCap)):
		cap = int(inputCap[i])
		graph[0][i + 1] = cap
		graph[i + 1][i + 1 + nodes] = cap
	for i in range(1, len(outputCap) + 1):
		cap = int(outputCap[i - 1])
		graph[i + nodes][nodes * 2 + 1] = cap
	for i in range(edges):
		(u, v) = sys.stdin.readline().split()
		u = int(u)
		v = int(v)
		graph[u][v + nodes] = int(inputCap[u - 1])
		graph[v][u + nodes] = int(inputCap[v - 1])
	source = 0
	sink = nodes * 2 + 1
	actual = fordFulkerson(graph, source, sink)
	if actual == totalOutput:
		print('YES')
		printGraph(graph, nodes)
	else:
		print('NO')


from sys import stdin, stdout, stderr
from collections import deque
INF = 1061109567

class Dinic:

	def __init__(self, N):
		self.N = N
		self.e = 0
		self.cap = []
		self.flow = []
		self.eid = []
		self.adj = [[] for i in range(N)]

	def add_edge(self, a, b, c, i=-1):
		self.adj[a].append((b, self.e))
		self.cap.append(c)
		self.flow.append(0)
		self.eid.append(i)
		self.e += 1
		self.adj[b].append((a, self.e))
		self.cap.append(0)
		self.flow.append(0)
		self.eid.append(i)
		self.e += 1

	def bfs(self, s, t):
		self.L = [INF for i in range(self.N)]
		self.nxte = [0 for i in range(self.N)]
		q = deque()
		q.append(s)
		self.L[s] = 0
		while q:
			u = q.pop()
			for (v, e) in self.adj[u]:
				if self.flow[e] < self.cap[e] and self.L[v] == INF:
					q.append(v)
					self.L[v] = self.L[u] + 1
		return self.L[t] < INF

	def dfs(self, u, t, f):
		if u == t:
			return f
		pushed = 0
		lim = len(self.adj[u])
		while self.nxte[u] < lim:
			(v, e) = self.adj[u][self.nxte[u]]
			if self.flow[e] < self.cap[e] and self.L[v] == self.L[u] + 1:
				cur = self.dfs(v, t, min(self.cap[e] - self.flow[e], f - pushed))
				self.flow[e] += cur
				self.flow[e ^ 1] -= cur
				pushed += cur
			if pushed == f:
				break
			self.nxte[u] += 1
		return pushed

	def maxflow(self, s, t):
		ans = 0
		while self.bfs(s, t):
			ans += self.dfs(s, t, INF)
		return ans
(n, m) = list(map(int, stdin.readline().split()))
ai = [int(x) for x in stdin.readline().split()]
bi = [int(x) for x in stdin.readline().split()]
graph = Dinic(2 * n + 2)
(s, t) = (0, 2 * n + 1)
for i in range(m):
	(a, b) = list(map(int, stdin.readline().split()))
	graph.add_edge(a, n + b, INF)
	graph.add_edge(b, n + a, INF)
for i in range(n):
	graph.add_edge(s, i + 1, ai[i])
	graph.add_edge(n + i + 1, t, bi[i])
	graph.add_edge(i + 1, n + i + 1, INF)
ans = graph.maxflow(s, t)
if ans != sum(ai) or ans != sum(bi):
	stdout.write('NO\n')
else:
	stdout.write('YES\n')
	grid = [[0 for j in range(n)] for i in range(n)]
	for u in range(1, n + 1):
		for (v, e) in graph.adj[u]:
			if graph.flow[e] > 0 and 1 <= v - n and (v - n <= n):
				grid[u - 1][v - n - 1] += graph.flow[e]
	stdout.write('\n'.join([' '.join([str(x) for x in line]) for line in grid]) + '\n')


from collections import deque
import sys
(n, m) = input().split(' ')
(n, m) = (int(n), int(m))
starts = [int(x) for x in input().split(' ')]
ends = [int(x) for x in input().split(' ')]
num_soldiers = sum(ends)
if sum(starts) != sum(ends):
	print('NO')
	sys.exit()
f_size = 2 + 2 * n
flow_matrix = [[0] * f_size for _ in range(f_size)]
edge_list = [[] for _ in range(f_size)]

def get_index(i, is_start):
	if is_start:
		return 2 + i
	else:
		return 2 + n + i
for i in range(n):
	flow_matrix[0][get_index(i, True)] = starts[i]
	flow_matrix[get_index(i, False)][1] = ends[i]
	flow_matrix[get_index(i, True)][get_index(i, False)] = num_soldiers
for i in range(m):
	ends = input().split(' ')
	(a, b) = (int(ends[0]), int(ends[1]))
	a -= 1
	b -= 1
	flow_matrix[get_index(a, True)][get_index(b, False)] = num_soldiers
	flow_matrix[get_index(b, True)][get_index(a, False)] = num_soldiers
flow_matrix_copy = [x.copy() for x in flow_matrix]
for i in range(f_size):
	for j in range(f_size):
		if flow_matrix[i][j] != 0 or flow_matrix[j][i] != 0:
			edge_list[i].append(j)

def run_bfs(m):
	parent = [None for _ in range(len(m))]
	flow_from_s = [None for _ in range(len(m))]
	q = deque([])
	q.append(0)
	parent[0] = 0
	flow_from_s[0] = 2 ** 20
	found_target = False
	t = 1
	while len(q) > 0 and (not found_target):
		front = q.popleft()
		for neighbor in edge_list[front]:
			if flow_matrix[front][neighbor] > 0 and parent[neighbor] is None:
				parent[neighbor] = front
				flow_from_s[neighbor] = min(flow_from_s[front], flow_matrix[front][neighbor])
				q.append(neighbor)
				if neighbor == t:
					found_target = True
					break
	if not found_target:
		return 0
	cur = t
	flow = flow_from_s[t]
	while parent[cur] != cur:
		prev = parent[cur]
		flow_matrix[prev][cur] -= flow
		flow_matrix[cur][prev] += flow
		cur = prev
	return flow

def run_flow(m):
	total_flow = 0
	while True:
		flow = run_bfs(m)
		total_flow += flow
		if flow == 0:
			break
	return total_flow
if run_flow(flow_matrix) == num_soldiers:
	print('YES')
	for i in range(n):
		for j in range(n):
			num_along = flow_matrix_copy[get_index(i, True)][get_index(j, False)] - flow_matrix[get_index(i, True)][get_index(j, False)]
			print(str(num_along), end=' ')
		print('')
else:
	print('NO')


import sys
import copy
import os
(n, m) = map(lambda x: int(x), input().strip().split())
a = [_ for _ in map(lambda x: int(x), input().strip().split())]
b = [_ for _ in map(lambda x: int(x), input().strip().split())]
INF = 2 << 40
G = [[0 for _ in range(2 * n + 2)] for i in range(2 * n + 2)]
F = [[0 for _ in range(2 * n + 2)] for i in range(2 * n + 2)]
for i in range(1, n + 1):
	G[0][i] = a[i - 1]
	G[i][i + n] = INF
	G[i + n][2 * n + 1] = b[i - 1]
for i in range(m):
	(p, q) = map(lambda x: int(x), input().strip().split())
	G[p][q + n] = INF
	G[q][p + n] = INF
Vs = [False for i in range(2 * n + 2)]
total = 0

def dfs(st, t, v):
	global find, V, minv, total, G
	V[st] = True
	i = 0
	while i <= 2 * n + 1:
		if G[st][i] > 0 and (not V[i]):
			if i == t:
				V[i] = True
				find = True
				minv = min([v, G[st][i]])
				G[st][i] = G[st][i] - minv
				G[i][st] = G[i][st] + minv
				F[st][i] += minv
				if F[i][st] > 0:
					F[i][st] -= minv
				total += minv
				return minv
			mv = dfs(i, t, min([v, G[st][i]]))
			if mv > 0:
				F[st][i] += minv
				if F[i][st] > 0:
					F[i][st] -= minv
				G[st][i] = G[st][i] - minv
				G[i][st] = G[i][st] + minv
				return mv
		i += 1
	return 0
while True:
	find = False
	V = copy.deepcopy(Vs)
	minv = 2 << 40
	mv = dfs(0, 2 * n + 1, minv)
	if not find:
		break
if total == sum(a) and total == sum(b):
	print('YES')
	for i in range(1, n + 1):
		for j in range(1, n + 1):
			if i == j:
				print(F[i][i + n], end=' ')
			else:
				print(F[i][j + n], end=' ')
		print()
else:
	print('NO')


class Dinic:

	class Edge:

		def __init__(self, to, cap, rev):
			self.to = to
			self.cap = cap
			self.rev = rev

		def __repr__(self):
			return '(to: {0} cap: {1} rev: {2})'.format(self.to, self.cap, self.rev)

	def __init__(self, V):
		self.V = V
		self.size = [0 for i in range(V)]
		self.G = [[] for i in range(V)]

	def add_edge(self, _from, to, cap):
		self.G[_from].append(self.Edge(to, cap, self.size[to]))
		self.G[to].append(self.Edge(_from, 0, self.size[_from]))
		self.size[_from] += 1
		self.size[to] += 1

	def bfs(self, s):
		level = [-1 for i in range(self.V)]
		level[s] = 0
		q = []
		q.append(s)
		while q != []:
			v = q.pop(0)
			for u in self.G[v]:
				if u.cap > 0 and level[u.to] < 0:
					level[u.to] = level[v] + 1
					q.append(u.to)
		return level

	def dfs(self, v, t, f):
		if v == t:
			return f
		while self.iterator[v] < self.size[v]:
			edge = self.G[v][self.iterator[v]]
			if edge.cap > 0 and self.level[v] < self.level[edge.to]:
				d = self.dfs(edge.to, t, f if f < edge.cap else edge.cap)
				if d > 0:
					self.G[v][self.iterator[v]].cap -= d
					self.G[edge.to][edge.rev].cap += d
					return d
			self.iterator[v] += 1
		return 0

	def max_flow(self, s, t):
		flow = 0
		while True:
			self.level = self.bfs(s)
			if self.level[t] < 0:
				return flow
			self.iterator = [0 for i in range(self.V)]
			while True:
				f = self.dfs(s, t, float('inf'))
				if f == 0:
					break
				flow += f
(N, M) = map(int, input().split())
A = list(map(int, input().split()))
B = list(map(int, input().split()))
ff = Dinic(N * 2 + 2)
S = 1
T = N + 1
for i in range(M):
	(p, q) = map(int, input().split())
	ff.add_edge(p, T + q - 1, 10 ** 9)
	ff.add_edge(q, T + p - 1, 10 ** 9)
for i in range(N):
	ff.add_edge(i + 1, T + i, 10 ** 9)
	ff.add_edge(0, S + i, A[i])
	ff.add_edge(T + i, 2 * N + 1, B[i])
ans = [[0 for i in range(N)] for j in range(N)]
ff.max_flow(0, 2 * N + 1)
for i in range(1, N + 1):
	for v in ff.G[i]:
		if v.to != 0:
			ans[i - 1][v.to - T] = ff.G[v.to][v.rev].cap
if sum(A) != sum(B):
	print('NO')
	quit()
if [sum([ans[i][j] for i in range(N)]) for j in range(N)] == B:
	print('YES')
	for a in ans:
		print(' '.join(map(str, a)))
else:
	print('NO')


import sys

class Graph:
	verticies = {}
	nodesCount = 0

	class Vertex:

		def __init__(self, label):
			self.label = label
			self.edges = []
			self.visitedToken = 0

	class Edge:
		residual = None

		def __init__(self, from_, to_, isResidual, maxCapacity):
			self.from_ = from_
			self.to_ = to_
			self.isResidual = isResidual
			self.capacity = maxCapacity
			self.flow = 0

		def augment(self, bootleneck):
			self.flow += bootleneck
			self.residual.flow -= bootleneck

		def remainingCapacity(self):
			return self.capacity - self.flow

	def addEdge(self, from_, to_, capacity):
		from_ = self.verticies[from_]
		to_ = self.verticies[to_]
		main = self.Edge(from_, to_, False, capacity)
		residual = self.Edge(to_, from_, True, 0)
		main.residual = residual
		residual.residual = main
		from_.edges.append(main)
		to_.edges.append(residual)

	def addVertex(self, label):
		self.nodesCount += 1
		self.verticies[label] = self.Vertex(label)

	def maxFlow(self, f, t):
		f = self.verticies[f]
		t = self.verticies[t]
		visitedToken = 1
		flow = 0

		def dfs(node, bootleneck=sys.maxsize):
			node.visitedToken = visitedToken
			bootleneck_backup = bootleneck
			if node == t:
				return bootleneck
			for edge in node.edges:
				if edge.remainingCapacity() == 0 or edge.to_.visitedToken == visitedToken:
					continue
				bootleneck = dfs(edge.to_, min(bootleneck, edge.remainingCapacity()))
				if bootleneck:
					edge.augment(bootleneck)
					return bootleneck
				else:
					bootleneck = bootleneck_backup
			return 0
		while True:
			bootleneck = dfs(f)
			if not bootleneck:
				break
			flow += bootleneck
			visitedToken += 1
		return flow
g = Graph()
(n, m) = map(int, input().split())
a = [0] + list(map(int, input().split()))
b = [0] + list(map(int, input().split()))
g.addVertex(0)
for i in range(1, n + 1):
	g.addVertex(i)
	g.addVertex(n + i)
g.addVertex(2 * n + 1)
for i in range(m):
	(x, y) = map(int, input().split())
	g.addEdge(x, n + y, a[x])
	g.addEdge(y, n + x, a[y])
for i in range(1, n + 1):
	g.addEdge(0, i, a[i])
	g.addEdge(n + i, 2 * n + 1, b[i])
	g.addEdge(i, n + i, a[i])
if g.maxFlow(0, 2 * n + 1) == sum(a) == sum(b):
	print('YES')
	for i in range(1, n + 1):
		row = [0 for _ in range(n)]
		for e in g.verticies[i].edges:
			if not e.isResidual:
				row[e.to_.label - n - 1] = e.flow
		print(' '.join(map(str, row)))
else:
	print('NO')


from collections import defaultdict
from collections import deque
(n, m) = map(int, input().split(' '))
graph = {}
mxFlow = 0
a = list(map(int, input().split(' ')))
b = list(map(int, input().split(' ')))
graph[0] = {}
graph[n + n + 1] = {}
for i in range(n + n + 1):
	graph[i] = {}
	for j in range(n + n + 1):
		graph[i][j] = 0
for (i, val) in enumerate(a):
	graph[0][i + 1] = val
	graph[i + 1] = {0: 0}
for (i, val) in enumerate(b):
	graph[n + i + 1][n + n + 1] = val
	graph[n + n + 1][n + i + 1] = 0
for i in range(m):
	(s, e) = map(int, input().split(' '))
	graph[s][n + e] = float('inf')
	graph[e][n + s] = float('inf')
for i in range(1, n + 1):
	graph[i][i + n] = float('inf')

def bfs(source, sink):
	prev = {}
	q = deque()
	q.append((source, float('inf')))
	while q:
		(node, bottleneck) = q.popleft()
		for (dest, cap) in graph[node].items():
			if dest == sink and cap > 0:
				path = [sink, node]
				while node in prev and node != source:
					path.append(prev[node])
					node = prev[node]
				return (path[::-1], min(cap, bottleneck))
			if dest not in prev and cap > 0:
				prev[dest] = node
				q.append((dest, min(cap, bottleneck)))
	return ([], -1)

def ff(source, sink):
	flow = 0
	flows = defaultdict(lambda : defaultdict(int))
	while True:
		(path, bottleneck) = bfs(source, sink)
		if not path:
			break
		flow += bottleneck
		for ind in range(len(path) - 1):
			graph[path[ind]][path[ind + 1]] -= bottleneck
			graph[path[ind + 1]][path[ind]] += bottleneck
			if path[ind] != 0 and path[ind + 1] != n + 1:
				flows[path[ind]][path[ind + 1]] += bottleneck
	return (flow, flows)
(flow, flows) = ff(0, n + n + 1)
if sum(a) == flow and sum(b) == flow:
	print('YES')
	for i in range(1, n + 1):
		for j in range(1, n + 1):
			print(graph[j + n][i], end=' ')
		print()
else:
	if a[0] == 25 and a[1] == 29:
		print(flow, sum(a), sum(b))
	print('NO')


import math

def dfs(u, t, bottleneck, graph, visited):
	if u == t:
		return bottleneck
	visited[u] = True
	for e in graph[u]:
		residual = e.cap - e.flow
		if residual > 0 and (not visited[e.v]):
			augment = dfs(e.v, t, min(bottleneck, residual), graph, visited)
			if augment > 0:
				e.flow += augment
				e.reverse.flow -= augment
				return augment
	return 0

def max_flow(G, s, t):
	flow = 0
	augment = 1
	while augment > 0:
		visited = [False] * len(G)
		augment = dfs(s, t, math.inf, G, visited)
		flow += augment
	return flow

class Edge:

	def __init__(self, v, cap, reverse=None):
		self.cap = cap
		self.v = v
		self.reverse = reverse
		self.flow = 0

	def __repr__(self):
		return str(self.v) + ' (' + str(self.flow) + ')'
(n, m) = map(int, input().strip().split())
a = list(map(int, input().strip().split()))
b = list(map(int, input().strip().split()))
sum_a = sum(a)
sum_b = sum(b)
graph = [[] for _ in range(2 * n + 2)]
for (i, c) in enumerate(a, 1):
	graph[0].append(Edge(i, c))
t = len(graph) - 1
for (i, c) in enumerate(b, 1 + n):
	graph[i].append(Edge(t, c))
max_cap = math.inf
for i in range(1, len(a) + 1):
	graph[i].append(Edge(i + n, max_cap))
for _ in range(m):
	(u, v) = map(int, input().strip().split())
	graph[u].append(Edge(v + n, max_cap))
	graph[v].append(Edge(u + n, max_cap))
for (u, edges) in enumerate(graph):
	for edge in edges:
		if edge.reverse is None:
			new_edge = Edge(u, 0, edge)
			edge.reverse = new_edge
			graph[edge.v].append(new_edge)
if sum_a == sum_b and sum_a == max_flow(graph, 0, len(graph) - 1):
	print('YES')
	for i in range(1, n + 1):
		flows = [0] * n
		tot_out = 0
		for edge in graph[i]:
			if edge.v != i + n and edge.flow > 0:
				flows[edge.v - n - 1] = edge.flow
				tot_out += edge.flow
		flows[i - 1] = a[i - 1] - tot_out
		print(' '.join(map(str, flows)))
else:
	print('NO')


from collections import defaultdict
import sys
(N, M) = input().split(' ')
(N, M) = (int(N), int(M))
A = input().split(' ')
A = list(map(int, A))
B = input().split(' ')
B = list(map(int, B))
if sum(A) != sum(B):
	print('NO')
	sys.exit(0)
neighbours = defaultdict(lambda : defaultdict(int))
flow = defaultdict(int)

def left(i):
	return 'l ' + str(i)

def right(i):
	return 'r ' + str(i)
for i in range(1, N + 1):
	for j in range(1, N + 1):
		flow[left(i), right(j)] = 0
		flow[right(i), left(j)] = 0
for (i, capacity) in enumerate(A):
	neighbours['source'][left(i + 1)] = capacity
for (i, capacity) in enumerate(B):
	neighbours[right(i + 1)]['sink'] = capacity
for i in range(1, N + 1):
	neighbours[left(i)][right(i)] = float('inf')
for m in range(M):
	(p, q) = input().split(' ')
	(p, q) = (int(p), int(q))
	neighbours[left(p)][right(q)] = float('inf')
	neighbours[left(q)][right(p)] = float('inf')

def search():
	visited = set()

	def dfs(v):
		if v in visited:
			return False
		if v == 'sink':
			return ['sink']
		visited.add(v)
		for n in neighbours[v]:
			capacity = neighbours[v][n]
			if capacity > 0:
				res = dfs(n)
				if res:
					return [v] + res
	return dfs('source')
total_flow = 0

def augment_edge(a, b, amount):
	neighbours[a][b] -= amount
	neighbours[b][a] += amount
	flow[a, b] += amount

def augment(path):
	capacity = float('inf')
	for i in range(len(path) - 1):
		capacity = min(capacity, neighbours[path[i]][path[i + 1]])
	for i in range(len(path) - 1):
		augment_edge(path[i], path[i + 1], capacity)
	global total_flow
	total_flow += capacity
while True:
	res = search()
	if res is None:
		break
	else:
		augment(res)
if total_flow == sum(A):
	print('YES')
	for i in range(1, N + 1):
		for j in range(1, N + 1):
			print(flow[left(i), right(j)] - flow[right(j), left(i)], end=' ')
		print()
else:
	print('NO')


from collections import deque
from sys import stdin, stdout
maxNum = 200000

def retrieveFlow(theMap):
	countNodes = len(theMap)
	parent = [-1] * countNodes
	ans = 0
	while bfs(theMap, parent):
		curr_flow = maxNum + 1
		temp = countNodes - 1
		while temp != 0:
			curr_flow = min(curr_flow, theMap[parent[temp]][temp])
			temp = parent[temp]
		ans += curr_flow
		temp = countNodes - 1
		while temp != 0:
			par = parent[temp]
			theMap[par][temp] -= curr_flow
			theMap[temp][par] += curr_flow
			temp = par
	return ans

def bfs(theMap, parent):
	queue = deque([])
	queue.append(0)
	countNodes = len(theMap)
	beenThere = [False] * countNodes
	beenThere[0] = True
	while queue:
		temp = queue.popleft()
		for i in range(countNodes):
			if theMap[temp][i] > 0 and (not beenThere[i]):
				queue.append(i)
				beenThere[i] = True
				parent[i] = temp
				if i == countNodes - 1:
					return True
	return beenThere[countNodes - 1]

def soldierTraveling():
	(n, m) = [int(_) for _ in stdin.readline().rstrip().split()]
	readAll = stdin.readlines()
	firstNum = [int(_) for _ in readAll[0].split()]
	LastNum = [int(_) for _ in readAll[1].split()]
	if sum(LastNum) != sum(firstNum):
		stdout.write('NO\n')
		return
	theMap = [[0] * (n * 2 + 2) for _ in range(n * 2 + 2)]
	theEdges = [(_, _) for _ in range(1, n + 1)]
	for i in range(n):
		theMap[0][i + 1] = firstNum[i]
		theMap[n + i + 1][n * 2 + 2 - 1] = LastNum[i]
		theMap[i + 1][n + i + 1] = firstNum[i]
	for index in range(m):
		(i, j) = [int(_) for _ in readAll[2 + index].split()]
		theMap[i][n + j] = firstNum[i - 1]
		theMap[j][n + i] = firstNum[j - 1]
		theEdges.append((i, j))
	theMaxFlow = retrieveFlow(theMap)
	if sum(firstNum) != theMaxFlow:
		stdout.write('NO\n')
		return
	tempM = [[0] * n for _ in range(n)]
	for (i, j) in theEdges:
		tempM[i - 1][j - 1] = firstNum[i - 1] - theMap[i][n + j]
		tempM[j - 1][i - 1] = firstNum[j - 1] - theMap[j][n + i]
	stdout.write('YES\n')
	for i in tempM:
		stdout.write(' '.join((str(_) for _ in i)))
		stdout.write('\n')
soldierTraveling()
stdout.close()


class ford_fulkerson:

	class Edge:

		def __init__(self, to, cap, rev):
			self.to = to
			self.cap = cap
			self.rev = rev

		def __repr__(self):
			return 'to : {0} cap : {1} rev : {2}'.format(self.to, self.cap, self.rev)

	def __init__(self, V):
		self.V = V
		self.size = [0 for i in range(V)]
		self.G = [[] for i in range(V)]

	def add_edge(self, _from, to, cap):
		self.size[_from]
		self.G[_from].append(self.Edge(to, cap, self.size[to]))
		self.G[to].append(self.Edge(_from, 0, self.size[_from]))
		self.size[_from] += 1
		self.size[to] += 1

	def dfs(self, v, t, f):
		if v == t:
			return f
		self.used[v] = True
		for i in range(len(self.G[v])):
			edge = self.G[v][i]
			if self.used[edge.to] is False and edge.cap > 0:
				d = self.dfs(edge.to, t, f if f < edge.cap else edge.cap)
				if d > 0:
					self.G[v][i].cap -= d
					self.G[edge.to][edge.rev].cap += d
					return d
		return 0

	def max_flow(self, s, t):
		flow = 0
		while True:
			self.used = [False for _ in range(self.V)]
			f = self.dfs(s, t, float('inf'))
			if f == 0:
				return flow
			flow += f
(N, M) = map(int, input().split())
A = list(map(int, input().split()))
B = list(map(int, input().split()))
ff = ford_fulkerson(N * 2 + 2)
S = 1
T = N + 1
for i in range(M):
	(p, q) = map(int, input().split())
	ff.add_edge(p, T + q - 1, 10 ** 9)
	ff.add_edge(q, T + p - 1, 10 ** 9)
for i in range(N):
	ff.add_edge(i + 1, T + i, 10 ** 9)
	ff.add_edge(0, S + i, A[i])
	ff.add_edge(T + i, 2 * N + 1, B[i])
ans = [[0 for i in range(N)] for j in range(N)]
ff.max_flow(0, 2 * N + 1)
for i in range(1, N + 1):
	for v in ff.G[i]:
		if v.to != 0:
			ans[i - 1][v.to - T] = ff.G[v.to][v.rev].cap
if M == 0:
	if A == B:
		print('YES')
		for i in range(N):
			for j in range(N):
				ans[i][j] = A[i] if i == j else 0
		for a in ans:
			print(' '.join(map(str, a)))
	else:
		print('NO')
elif [sum([ans[i][j] for i in range(N)]) for j in range(N)] == B:
	print('YES')
	for a in ans:
		print(' '.join(map(str, a)))
else:
	print('NO')


import math
import sys

class FordFulkerson:

	class Edge:

		def __init__(self, to, cap, rev):
			self.to = to
			self.cap = cap
			self.rev = rev

	def __init__(self, V):
		self.V = V
		self.size = [0 for i in range(V)]
		self.G = [[] for i in range(V)]

	def add_edge(self, _from, to, cap):
		self.G[_from].append(self.Edge(to, cap, self.size[to]))
		self.G[to].append(self.Edge(_from, 0, self.size[_from]))
		self.size[_from] += 1
		self.size[to] += 1

	def dfs(self, v, t, f):
		if v == t:
			return f
		self.used[v] = True
		for i in range(self.size[v]):
			edge = self.G[v][i]
			if self.used[edge.to] is False and edge.cap > 0:
				d = self.dfs(edge.to, t, f if f < edge.cap else edge.cap)
				if d > 0:
					self.G[v][i].cap -= d
					self.G[edge.to][edge.rev].cap += d
					return d
		return 0

	def max_flow(self, s, t):
		result = 0
		while True:
			self.used = [False for _ in range(self.V)]
			f = self.dfs(s, t, math.inf)
			if f == 0:
				return result
			result += f

def solve(r, w):
	(num_cities, num_roads) = map(int, input().split())
	original = list(map(int, input().split()))
	result = list(map(int, input().split()))
	flow_ford = FordFulkerson(num_cities * 2 + 2)
	T = num_cities + 1
	for i in range(num_roads):
		(p, q) = map(int, input().split())
		flow_ford.add_edge(p, T + q - 1, 10 ** 9)
		flow_ford.add_edge(q, T + p - 1, 10 ** 9)
	for i in range(num_cities):
		flow_ford.add_edge(i + 1, T + i, 10 ** 9)
		flow_ford.add_edge(0, 1 + i, original[i])
		flow_ford.add_edge(T + i, 2 * num_cities + 1, result[i])
	ans = [[0 for i in range(num_cities)] for j in range(num_cities)]
	flow_ford.max_flow(0, 2 * num_cities + 1)
	for i in range(1, num_cities + 1):
		for v in flow_ford.G[i]:
			if v.to != 0:
				ans[i - 1][v.to - T] = flow_ford.G[v.to][v.rev].cap
	if sum(original) != sum(result):
		print('NO')
		return
	if [sum([ans[i][j] for i in range(num_cities)]) for j in range(num_cities)] == result:
		print('YES')
		for a in ans:
			print(' '.join(map(str, a)))
	else:
		print('NO')
solve(sys.stdin, sys.stdout)


from sys import stdin
from collections import deque

def bfs(g, el, source, dest, pre):
	q = deque()
	pre.clear()
	pre.extend([None] * len(g))
	q.append(source)
	while q:
		u = q.popleft()
		for e in g[u]:
			(v, c, f) = (el[e][1], el[e][2], el[e][3])
			if pre[v] is None and f < c and (v != source):
				pre[v] = e
				q.append(v)
		if pre[dest] is not None:
			return True
	return False

def max_flow(g, el, source, sink):
	total_flow = 0
	pre = []
	while bfs(g, el, source, sink, pre):
		e = pre[sink]
		flow = int(1000000000.0)
		path = []
		while True:
			flow = min(flow, el[e][2] - el[e][3])
			path.append(e)
			e = pre[el[e][0]]
			if e is None:
				break
		for e in path:
			el[e][3] += flow
			el[el[e][4]][3] -= flow
		total_flow += flow
	return total_flow

def add_edge(g, el, u, v, c):
	el.append([u, v, c, 0, len(el) + 1])
	el.append([v, u, 0, 0, len(el) - 1])
	g[u].append(len(el) - 2)
	g[v].append(len(el) - 1)

def main():
	(n, m) = [int(_) for _ in stdin.readline().split()]
	a = [int(_) for _ in stdin.readline().split()]
	b = [int(_) for _ in stdin.readline().split()]
	g = [[] for _ in range(n * 2 + 2)]
	el = []
	source = n * 2
	sink = n * 2 + 1
	inf = int(1000000000.0)
	for line in stdin.readlines():
		(u, v) = [int(_) - 1 for _ in line.split()]
		add_edge(g, el, u, v + n, inf)
		add_edge(g, el, v, u + n, inf)
	for i in range(n):
		add_edge(g, el, i, i + n, a[i])
		add_edge(g, el, source, i, a[i])
		add_edge(g, el, i + n, sink, b[i])
	if sum(a) != sum(b) or max_flow(g, el, source, sink) != sum(a):
		print('NO')
	else:
		print('YES')
		tr = [[0 for j in range(n)] for i in range(n)]
		edges = [e for e in el if e[3] > 0 and e[0] < n * 2 and (e[1] < n * 2)]
		for edge in edges:

			def rev_idx(u):
				return u if u < n else u - n
			tr[rev_idx(edge[0])][rev_idx(edge[1])] = edge[3]
		print('\n'.join((' '.join((str(x) for x in row)) for row in tr)))
main()


from sys import stdin, stdout, stderr
from collections import deque
(n, m) = map(int, stdin.readline().split())
ai = [int(x) for x in stdin.readline().split()]
bi = [int(x) for x in stdin.readline().split()]
N = 2 * n + 2
M = 4 * m + 6 * n
cap = [None for i in range(M)]
flow = [0 for i in range(M)]
adj = [[] for i in range(N)]
s = 0
t = 2 * n + 1
INF = 1061109567
eid = 0

def add_edge(a, b, c):
	global eid, adj, cap
	adj[a].append((b, eid))
	cap[eid] = c
	eid += 1
for i in range(m):
	(a, b) = map(int, stdin.readline().split())
	add_edge(a, n + b, INF)
	add_edge(n + b, a, 0)
	add_edge(b, n + a, INF)
	add_edge(n + a, b, 0)
for i in range(n):
	add_edge(s, i + 1, ai[i])
	add_edge(i + 1, s, 0)
	add_edge(n + i + 1, t, bi[i])
	add_edge(t, n + i + 1, 0)
	add_edge(i + 1, n + i + 1, INF)
	add_edge(n + i + 1, i + 1, 0)
ans = 0
while True:
	par = [None for i in range(N)]
	minf = [INF for i in range(N)]
	bfs = deque()
	bfs.append(s)
	par[s] = (-1, -1)
	while bfs:
		u = bfs.pop()
		if u == t:
			break
		for (v, e) in adj[u]:
			if par[v] is None and flow[e] < cap[e]:
				bfs.append(v)
				par[v] = (u, e)
				minf[v] = min(minf[u], cap[e] - flow[e])
	v = t
	if par[t] is None:
		break
	while par[v][0] != -1:
		(u, e) = par[v]
		flow[e] += minf[t]
		flow[e ^ 1] -= minf[t]
		v = u
	ans += minf[t]
if ans != sum(ai) or ans != sum(bi):
	stdout.write('NO\n')
else:
	stdout.write('YES\n')
	grid = [[0 for j in range(n)] for i in range(n)]
	for u in range(1, n + 1):
		for (v, e) in adj[u]:
			if flow[e] > 0 and 1 <= v - n and (v - n <= n):
				grid[u - 1][v - n - 1] += flow[e]
	stdout.write('\n'.join([' '.join([str(x) for x in line]) for line in grid]) + '\n')


import math, string, itertools, fractions, heapq, collections, re, array, bisect, copy
from itertools import chain, dropwhile, permutations, combinations
from collections import defaultdict, deque

def VI():
	return list(map(int, input().split()))

def I():
	return int(input())

def LIST(n, m=None):
	return [0] * n if m is None else [[0] * m for i in range(n)]

def ELIST(n):
	return [[] for i in range(n)]

def yes(A):
	print('YES')
	for l in A:
		print(' '.join([str(x) for x in l]))

def no():
	print('NO')

class FlowEdge:

	def __init__(self, v, w, capacity):
		self.v = v
		self.w = w
		self.capacity = capacity
		self.flow = 0

	def other(self, v):
		return self.w if self.v == v else self.v

	def residual_capacity_to(self, v):
		if v == self.v:
			return self.flow
		elif v == self.w:
			return self.capacity - self.flow
		else:
			raise Exception()

	def add_residual_flow_to(self, v, delta):
		if v == self.v:
			self.flow -= delta
		elif v == self.w:
			self.flow += delta
		else:
			raise Exception()

	def __str__(self):
		return '{}-{}: {:.0f}/{:.0f} '.format(self.v, self.w, self.flow, self.capacity)

class FlowNetwork:

	def __init__(self, nv=0):
		self.nv = nv
		self.al = ELIST(self.nv)

	def add_edge(self, e):
		self.al[e.v].append(e)
		self.al[e.w].append(e)

	def reset(self):
		for v in self.al:
			for e in v:
				e.flow = 0

class FordFulkerson:

	def __init__(self, g, s, t):
		self.g = g
		self.s = s
		self.t = t
		self.value = 0
		infty = 1000000000.0
		while self.has_augmenting_path():
			bottle = infty
			v = t
			while v != s:
				bottle = min(bottle, self.edge_to[v].residual_capacity_to(v))
				v = self.edge_to[v].other(v)
			v = t
			while v != s:
				self.edge_to[v].add_residual_flow_to(v, bottle)
				v = self.edge_to[v].other(v)
			self.value += bottle

	def has_augmenting_path(self, log=False):
		self.edge_to = [None] * self.g.nv
		self.marked = [False] * self.g.nv
		queue = deque()
		queue.append(self.s)
		self.marked[self.s] = True
		if log:
			i = 0
		while len(queue) != 0:
			v = queue.popleft()
			for e in self.g.al[v]:
				w = e.other(v)
				if e.residual_capacity_to(w) > 0 and (not self.marked[w]):
					self.edge_to[w] = e
					self.marked[w] = True
					queue.append(w)
		return self.marked[self.t]

def main(info=0):
	(n, m) = VI()
	a = VI()
	b = VI()
	(s, t) = (0, 1 + 2 * n)
	fg = FlowNetwork(nv=n * 2 + 2)
	infty = 10000000
	for i in range(n):
		fg.add_edge(FlowEdge(s, 1 + i, a[i]))
		fg.add_edge(FlowEdge(1 + n + i, t, b[i]))
		fg.add_edge(FlowEdge(1 + i, 1 + n + i, infty))
	for i in range(m):
		(u, v) = VI()
		fg.add_edge(FlowEdge(1 + u - 1, 1 + n + v - 1, infty))
		fg.add_edge(FlowEdge(1 + v - 1, 1 + n + u - 1, infty))
	ff = FordFulkerson(fg, s, t)
	if ff.value == sum(a) == sum(b):
		A = LIST(n, n)
		for i in range(n):
			for e in fg.al[i + 1]:
				A[i][e.w - n - 1] = e.flow
		yes(A)
	else:
		no()
main()


def dfs(graph, capacity, source, target):
	fringe = []
	fringe.append(([source], 9999999))
	visited = set()
	while len(fringe) != 0:
		(currPath, currBottleneck) = fringe.pop()
		currNode = currPath[-1]
		if currNode == target:
			return (currPath, currBottleneck)
		if currNode not in visited:
			visited.add(currNode)
			for (nextNode, capacity) in zip(graph[currNode], capacities[currNode]):
				if nextNode not in visited and capacity > 0:
					nextPath = currPath + [nextNode]
					nextBottleNeck = min(capacity, currBottleneck)
					fringe.append((nextPath, nextBottleNeck))
	return (None, None)

def ford_fulkerson(graph, capacities, source, sink):
	total = 0
	while True:
		(path, bottleneck) = dfs(graph, capacities, source, sink)
		if path is None:
			break
		total += bottleneck
		for i in range(len(path) - 1):
			(u, v) = (path[i], path[i + 1])
			indexOfVInGraphU = graph[u].index(v)
			capacities[u][indexOfVInGraphU] -= bottleneck
			indexOfUInGraphV = graph[v].index(u)
			capacities[v][indexOfUInGraphV] += bottleneck
			assert capacities[u][indexOfVInGraphU] >= 0 and capacities[v][indexOfUInGraphV] >= 0
	return total
(n, m) = [int(x) for x in input().split(' ')]
ais = [int(x) for x in input().split(' ')]
bis = [int(x) for x in input().split(' ')]
if sum(ais) != sum(bis):
	print('NO')
	return
graph = [[] for _ in range(2 * n + 2)]
capacities = [[] for _ in range(2 * n + 2)]
INF = 9999999
for v in range(1, n + 1):
	graph[0].append(v)
	capacities[0].append(ais[v - 1])
for u in range(n + 1, 2 * n + 1):
	graph[u].append(2 * n + 1)
	capacities[u].append(bis[u - n - 1])
for u in range(1, n + 1):
	graph[u].append(n + u)
	capacities[u].append(INF)
for _ in range(m):
	(u, v) = [int(x) for x in input().split(' ')]
	graph[u].append(n + v)
	capacities[u].append(INF)
	graph[v].append(n + u)
	capacities[v].append(INF)
for u in range(2 * n + 2):
	for v in graph[u]:
		if u not in graph[v]:
			graph[v].append(u)
			capacities[v].append(0)
maxFlow = ford_fulkerson(graph, capacities, 0, 2 * n + 1)
if maxFlow < sum(ais):
	print('NO')
	return
else:
	print('YES')
	for u in range(1, n + 1):
		for v in range(n + 1, 2 * n + 1):
			try:
				indexOfUInGraphV = graph[v].index(u)
				print(capacities[v][indexOfUInGraphV], end=' ')
			except:
				print(0, end=' ')
		print()


from queue import Queue

def bfs(graph, source, sink, previous, maxFlow):
	for i in range(len(previous)):
		previous[i] = -1
	for i in range(len(maxFlow)):
		maxFlow[i] = -1
	queue = Queue()
	queue.put(source)
	maxFlow[source] = float('inf')
	foundSink = False
	while not queue.empty():
		location = queue.get()
		flow = maxFlow[location]
		foundSink |= location == sink
		for nextLocation in range(len(graph)):
			capacity = graph[location][nextLocation]
			if previous[nextLocation] == -1 and capacity > 0:
				previous[nextLocation] = location
				maxFlow[nextLocation] = min(flow, capacity)
				queue.put(nextLocation)
	return foundSink

def fordFulkerson(graph, source, sink):
	flow = 0
	maxFlow = [0] * len(graph)
	previous = [0] * len(graph)
	while bfs(graph, source, sink, previous, maxFlow):
		currentFlow = maxFlow[sink]
		flow += currentFlow
		node = sink
		while node != source:
			previousNode = previous[node]
			graph[previousNode][node] -= currentFlow
			graph[node][previousNode] += currentFlow
			node = previousNode
	return flow
[N, M] = list(map(int, input().split()))
A = list(map(int, input().split()))
B = list(map(int, input().split()))
roads = []
for i in range(M):
	[p, q] = list(map(int, input().split()))
	roads.append([p - 1, q - 1])
numVertices = 2 * N + 2
source = 2 * N
sink = 2 * N + 1
graph = [[0] * numVertices for i in range(numVertices)]
for i in range(N):
	start = i
	graph[source][start] = A[i]
for i in range(N):
	finish = i + N
	graph[finish][sink] = B[i]
for i in range(N):
	graph[i][i + N] = 10000000
for road in roads:
	[p, q] = road
	graph[p][q + N] = 10000000
	graph[q][p + N] = 10000000
if sum(A) != sum(B):
	print('NO')
else:
	maxCorrectEndingSoldiers = fordFulkerson(graph, source, sink)
	if maxCorrectEndingSoldiers != sum(B):
		print('NO')
	else:
		print('YES')
		for i in range(N):
			for j in range(N):
				print(graph[j + N][i], end=' ')
			print()


import math

class Edge:

	def __init__(self, c, f, t, rev=None):
		self.capacity = c
		self.flow = f
		self.target = t
		self.rev = rev

	def __repr__(self):
		return '<e: (cap: {}, target: {}, flow: {}>'.format(self.capacity, self.target, self.flow)

def search(u, t, smallest, visited, graph):
	if u == t:
		return smallest
	visited[u] = True
	for e in graph[u]:
		residual = e.capacity - e.flow
		if residual > 0 and (not visited[e.target]):
			augment = search(e.target, t, min(smallest, residual), visited, graph)
			if augment > 0:
				e.flow += augment
				e.rev.flow -= augment
				return augment
	return 0

def fulkerson(g, s, t):
	flow = 0
	while True:
		Visited = [False for _ in range(len(g))]
		augment = search(s, t, math.inf, Visited, g)
		flow += augment
		if augment <= 0:
			break
	return flow

def print_graph(graph):
	for (i, edges) in enumerate(graph):
		print('{}: [{}]'.format(i, edges))

def main():
	[n, m] = list(map(int, input('').split()))
	have = list(map(int, input('').split()))
	need = list(map(int, input('').split()))
	graph = [[] for _ in range(2 * n + 2)]
	for (i, soldiers) in enumerate(have):
		graph[0].append(Edge(soldiers, 0, i + 1))
	for (i, soldiers) in enumerate(need):
		graph[n + i + 1].append(Edge(soldiers, 0, 2 * n + 1))
	for _ in range(m):
		[s, t] = list(map(int, input('').split()))
		graph[t].append(Edge(1000, 0, n + s))
		graph[s].append(Edge(1000, 0, n + t))
	for i in range(n):
		i = i + 1
		graph[i].append(Edge(have[i - 1], 0, n + i))
	residualGraph = [[] for _ in range(len(graph))]
	for (u, edges) in enumerate(graph):
		for e in edges:
			target = e.target
			reverse = Edge(0, 0, u, e)
			e.rev = reverse
			residualGraph[u].append(e)
			residualGraph[target].append(reverse)
	flow = fulkerson(residualGraph, 0, 2 * n + 1)
	if sum(need) != flow or sum(have) != sum(need):
		print('NO')
	else:
		print('YES')
		adjmatrix = [[0 for _ in range(n)] for _ in range(n)]
		for (u, edges) in enumerate(residualGraph[1:2 * n + 1]):
			u = u + 1
			for e in edges:
				if e.capacity == 1000 or (u + n == e.target and e.target != 2 * n + 1):
					adjmatrix[u - 1][e.target - n - 1] = e.flow
		for row in adjmatrix:
			print(' '.join(map(str, row)))

def __starting_point():
	main()
__starting_point()


from sys import stdin, stdout, stderr
from collections import deque
(n, m) = map(int, stdin.readline().split())
ai = [int(x) for x in stdin.readline().split()]
bi = [int(x) for x in stdin.readline().split()]
N = 2 * n + 2
M = 4 * m + 6 * n
cap = [None for i in range(M)]
flow = [0 for i in range(M)]
adj = [[] for i in range(N)]
L = []
cure = []
s = 0
t = 2 * n + 1
INF = 1061109567

def bfs():
	global L, cure
	L = [INF for i in range(N)]
	cure = [0 for i in range(N)]
	q = deque()
	q.append(s)
	L[s] = 0
	while q:
		u = q.pop()
		for (v, e) in adj[u]:
			if flow[e] < cap[e] and L[v] == INF:
				q.append(v)
				L[v] = L[u] + 1
	return L[t] < INF

def dfs(u, f):
	if u == t:
		return f
	pushed = 0
	lim = len(adj[u])
	while cure[u] < lim:
		(v, e) = adj[u][cure[u]]
		if flow[e] < cap[e] and L[v] == L[u] + 1:
			cur = dfs(v, min(cap[e] - flow[e], f - pushed))
			flow[e] += cur
			flow[e ^ 1] -= cur
			pushed += cur
		if pushed == f:
			break
		cure[u] += 1
	return pushed
eid = 0

def add_edge(a, b, c):
	global eid, adj, cap
	adj[a].append((b, eid))
	cap[eid] = c
	eid += 1
for i in range(m):
	(a, b) = map(int, stdin.readline().split())
	add_edge(a, n + b, INF)
	add_edge(n + b, a, 0)
	add_edge(b, n + a, INF)
	add_edge(n + a, b, 0)
for i in range(n):
	add_edge(s, i + 1, ai[i])
	add_edge(i + 1, s, 0)
	add_edge(n + i + 1, t, bi[i])
	add_edge(t, n + i + 1, 0)
	add_edge(i + 1, n + i + 1, INF)
	add_edge(n + i + 1, i + 1, 0)
ans = 0
while bfs():
	ans += dfs(s, INF)
if ans != sum(ai) or ans != sum(bi):
	stdout.write('NO\n')
else:
	stdout.write('YES\n')
	grid = [[0 for j in range(n)] for i in range(n)]
	for u in range(1, n + 1):
		for (v, e) in adj[u]:
			if flow[e] > 0 and 1 <= v - n and (v - n <= n):
				grid[u - 1][v - n - 1] += flow[e]
	stdout.write('\n'.join([' '.join([str(x) for x in line]) for line in grid]) + '\n')


import math

class Edge:

	def __init__(self, cap, flow, target, rev=None):
		self.capacity = cap
		self.flow = flow
		self.target = target
		self.rev = rev

	def __repr__(self):
		return '<e: (cap: {}, target: {}, flow: {}>'.format(self.capacity, self.target, self.flow)

def dfs(u, t, bottleneck, visited, graph):
	if u == t:
		return bottleneck
	visited[u] = True
	for e in graph[u]:
		residual = e.capacity - e.flow
		if residual > 0 and (not visited[e.target]):
			augment = dfs(e.target, t, min(bottleneck, residual), visited, graph)
			if augment > 0:
				e.flow += augment
				e.rev.flow -= augment
				return augment
	return 0

def ford_fulkerson(g, s, t):
	flow = 0
	while True:
		Visited = [False for _ in range(len(g))]
		augment = dfs(s, t, math.inf, Visited, g)
		flow += augment
		if augment <= 0:
			break
	return flow

def print_graph(graph):
	for (i, edges) in enumerate(graph):
		print('{}: [{}]'.format(i, edges))
[n, m] = list(map(int, input('').split()))
city_soldiers = list(map(int, input('').split()))
want_soldiers = list(map(int, input('').split()))
graph = [[] for _ in range(2 * n + 2)]
for (i, soldiers) in enumerate(city_soldiers):
	graph[0].append(Edge(soldiers, 0, i + 1))
for (i, soldiers) in enumerate(want_soldiers):
	graph[n + i + 1].append(Edge(soldiers, 0, 2 * n + 1))
for _ in range(m):
	[s, t] = list(map(int, input('').split()))
	graph[t].append(Edge(1000, 0, n + s))
	graph[s].append(Edge(1000, 0, n + t))
for i in range(n):
	i = i + 1
	graph[i].append(Edge(city_soldiers[i - 1], 0, n + i))
residualGraph = [[] for _ in range(len(graph))]
for (u, edges) in enumerate(graph):
	for e in edges:
		target = e.target
		reverse = Edge(0, 0, u, e)
		e.rev = reverse
		residualGraph[u].append(e)
		residualGraph[target].append(reverse)
flow = ford_fulkerson(residualGraph, 0, 2 * n + 1)
if sum(want_soldiers) != flow or sum(city_soldiers) != sum(want_soldiers):
	print('NO')
else:
	print('YES')
	adjmatrix = [[0 for _ in range(n)] for _ in range(n)]
	for (u, edges) in enumerate(residualGraph[1:2 * n + 1]):
		u = u + 1
		for e in edges:
			if e.capacity == 1000 or (u + n == e.target and e.target != 2 * n + 1):
				adjmatrix[u - 1][e.target - n - 1] = e.flow
	for row in adjmatrix:
		print(' '.join(map(str, row)))


from collections import deque
from sys import stdin, stdout
MAX_SOLDIERS = 200000

def solve():
	(n, m) = [int(_) for _ in stdin.readline().rstrip().split()]
	all_lines = stdin.readlines()
	start_vals = [int(_) for _ in all_lines[0].split()]
	end_vals = [int(_) for _ in all_lines[1].split()]
	if sum(start_vals) != sum(end_vals):
		stdout.write('NO\n')
		return
	graph = [[0] * (n * 2 + 2) for _ in range(n * 2 + 2)]
	edges = [(_, _) for _ in range(1, n + 1)]
	for i in range(n):
		graph[0][i + 1] = start_vals[i]
		graph[n + i + 1][n * 2 + 2 - 1] = end_vals[i]
		graph[i + 1][n + i + 1] = start_vals[i]
	for index in range(m):
		(i, j) = [int(_) for _ in all_lines[2 + index].split()]
		graph[i][n + j] = start_vals[i - 1]
		graph[j][n + i] = start_vals[j - 1]
		edges.append((i, j))
	flow = maxflow(graph)
	if flow != sum(start_vals):
		stdout.write('NO\n')
		return
	mat = [[0] * n for _ in range(n)]
	for (i, j) in edges:
		mat[i - 1][j - 1] = start_vals[i - 1] - graph[i][n + j]
		mat[j - 1][i - 1] = start_vals[j - 1] - graph[j][n + i]
	stdout.write('YES\n')
	for i in mat:
		stdout.write(' '.join((str(_) for _ in i)))
		stdout.write('\n')

def bfs(graph, parent):
	num_nodes = len(graph)
	visited = [False] * num_nodes
	queue = deque([])
	queue.append(0)
	visited[0] = True
	while queue:
		curr_node = queue.popleft()
		for i in range(num_nodes):
			if graph[curr_node][i] > 0 and (not visited[i]):
				queue.append(i)
				visited[i] = True
				parent[i] = curr_node
				if i == num_nodes - 1:
					return True
	return visited[num_nodes - 1]

def maxflow(graph):
	num_nodes = len(graph)
	parent = [-1] * num_nodes
	ans = 0
	while bfs(graph, parent):
		curr_flow = MAX_SOLDIERS + 1
		curr_node = num_nodes - 1
		while curr_node != 0:
			curr_flow = min(curr_flow, graph[parent[curr_node]][curr_node])
			curr_node = parent[curr_node]
		ans += curr_flow
		curr_node = num_nodes - 1
		while curr_node != 0:
			par = parent[curr_node]
			graph[par][curr_node] -= curr_flow
			graph[curr_node][par] += curr_flow
			curr_node = par
	return ans
solve()
stdout.close()


class edge:

	def __init__(self, node, capacity, flow, rev):
		self.node = node
		self.capacity = capacity
		self.flow = flow
		self.rev = rev

	def __str__(self):
		return ','.join([str(x) for x in [self.node, self.capacity, self.flow]]) if self.capacity else 'Back Edge'

class flow:

	def __init__(self, n):
		self.n = n
		self.g = [[] for _ in range(n)]

	def adde(self, u, v, w):
		x = edge(v, w, 0, None)
		y = edge(u, 0, 0, x)
		x.rev = y
		self.g[u].append(x)
		self.g[v].append(y)

	def dfs(self, u, t, bottleneck):
		if u == t:
			return bottleneck
		self.visited[u] = True
		for e in self.g[u]:
			v = e.node
			residual = e.capacity - e.flow
			if residual > 0 and (not self.visited[v]):
				augment = self.dfs(v, t, min(bottleneck, residual))
				if augment > 0:
					e.flow += augment
					e.rev.flow -= augment
					return augment
		return 0

	def max_flow(self, s, t):
		flow = 0
		augment = 0
		while True:
			self.visited = [False for _ in range(self.n)]
			augment = self.dfs(s, t, float('inf'))
			flow += augment
			if augment <= 0:
				break
		return flow

	def reprnode(self, u):
		sz = self.n // 2 - 1
		rpr = [0] * sz
		for e in self.g[u]:
			if e.capacity:
				try:
					rpr[e.node - sz - 1] = e.flow
				except:
					pass
		return ' '.join([str(x) for x in rpr])
(n, m) = [int(x) for x in input().split()]
s = 0
t = 2 * n + 1
f = flow(t + 1)
atot = 0
btot = 0
array_a = [int(x) for x in input().split()]
array_b = [int(x) for x in input().split()]
for (i, (a, b)) in enumerate(zip(array_a, array_b), start=1):
	f.adde(s, i, a)
	f.adde(i + n, t, b)
	f.adde(i, i + n, float('inf'))
	atot += a
	btot += b
for _ in range(m):
	(p, q) = [int(x) for x in input().split()]
	f.adde(p, q + n, float('inf'))
	f.adde(q, p + n, float('inf'))
if atot == f.max_flow(s, t) and atot == btot:
	print('YES')
	for i in range(1, n + 1):
		print(f.reprnode(i))
else:
	print('NO')


INF = 10 ** 5

class Graph:

	def __init__(self, vertices):
		self.vertices = vertices
		self.graph = [[0 for i in range(vertices)] for j in range(vertices)]

	def BFS(self, s, t, parent):
		visited = [False for i in range(self.vertices)]
		queue = []
		visited[s] = True
		queue.append(s)
		while len(queue) > 0:
			vertex = queue.pop(0)
			for (i, value) in enumerate(self.graph[vertex]):
				if not visited[i] and value > 0:
					queue.append(i)
					parent[i] = vertex
					visited[i] = True
					if i == t:
						return True
		return False

	def max_flow(self):
		flow = 0
		parent = [i for i in range(self.vertices)]
		while self.BFS(0, self.vertices - 1, parent):
			min_flow = INF
			t = self.vertices - 1
			while t != 0:
				min_flow = min(min_flow, self.graph[parent[t]][t])
				t = parent[t]
			flow += min_flow
			t = self.vertices - 1
			while t != 0:
				self.graph[parent[t]][t] -= min_flow
				self.graph[t][parent[t]] += min_flow
				t = parent[t]
		return flow
(n, m) = map(int, input().split())
a = list(map(int, input().split()))
b = list(map(int, input().split()))
edges = {}
for i in range(m):
	(x, y) = map(int, input().split())
	edges[x, y] = True
g = Graph(2 * n + 2)
for i in range(1, n + 1):
	g.graph[0][i] = a[i - 1]
for (x, y) in edges:
	g.graph[x][y + n] = INF
	g.graph[y][x + n] = INF
for i in range(1, n + 1):
	g.graph[i + n][2 * n + 1] = b[i - 1]
for i in range(1, n + 1):
	g.graph[i][i + n] = a[i - 1]
max_flow = g.max_flow()
if max_flow == sum(a) and sum(a) == sum(b):
	print('YES')
	for i in range(1, n + 1):
		for j in range(1, n + 1):
			if i != j and (edges.get((j, i), False) or edges.get((i, j), False)):
				print(10 ** 5 - g.graph[i][j + n], end=' ')
			elif i != j:
				print(0, end=' ')
			else:
				print(a[i - 1] - g.graph[i][i + n], end=' ')
		print()
else:
	print('NO')


import math

def bfs(graph, size, s, t):
	visited = [False] * size
	queue = []
	parent = {}
	visited[s] = True
	queue.append(s)
	while len(queue) > 0:
		curr = queue.pop(0)
		for (i, val) in enumerate(graph[curr]):
			if not visited[i] and val > 0:
				visited[i] = True
				parent[i] = curr
				if i == t:
					return parent
				queue.append(i)
	return {}

def ff(graph, size, s, t):
	max_flow = 0
	augmenting = bfs(graph, size, s, t)
	while len(augmenting) > 0:
		flow = math.inf
		curr = t
		while curr != s:
			flow = min(flow, graph[augmenting[curr]][curr])
			curr = augmenting[curr]
		max_flow += flow
		curr = t
		while curr != s:
			parent = augmenting[curr]
			graph[parent][curr] -= flow
			graph[curr][parent] += flow
			curr = parent
		augmenting = bfs(graph, size, s, t)
	return max_flow
(n, m) = map(int, input().split(' '))
source_vals = [int(i) for i in input().split(' ')]
sink_vals = [int(i) for i in input().split(' ')]
edges = [(0, 0)] * m
for i in range(m):
	(u, v) = map(int, input().split(' '))
	edges[i] = (u, v)
size = 2 * n + 2
graph = [[0 for j in range(size)] for i in range(size)]
flow_in = 0
flow_out = 0
for (i, val) in enumerate(source_vals):
	node = i + 1
	graph[0][node] = val
	flow_in += val
for (i, val) in enumerate(sink_vals):
	node = i + (n + 1)
	graph[node][2 * n + 1] = val
	flow_out += val
for (u, v) in edges:
	graph[u][v + n] = math.inf
	graph[v][u + n] = math.inf
for i in range(1, n + 1):
	graph[i][i + n] = math.inf
max_flow = ff(graph, size, 0, 2 * n + 1)
if flow_in != flow_out or max_flow < flow_in:
	print('NO')
else:
	print('YES')
	for j in range(1, n + 1):
		for i in range(n + 1, 2 * n + 1):
			print(graph[i][j], end=' ')
		print()


import sys
cap = [[0 for i in range(300)] for j in range(300)]
flow = [[0 for i in range(300)] for j in range(300)]
inf = 99999999
vis = [0] * 300
par = [0] * 300

def pushflow(v, mf, s):
	if v == s:
		return mf
	u = par[v]
	if cap[u][v] <= 0:
		mf = min(mf, flow[v][u])
	else:
		mf = min(mf, cap[u][v] - flow[u][v])
	mf = pushflow(u, mf, s)
	if cap[u][v] <= 0:
		flow[v][u] -= mf
	else:
		flow[u][v] += mf
	return mf

def bfs(n, m, s, t, adj):
	maxflow = 0
	while 1:
		for i in range(2 * n):
			vis[i] = 0
		vis[t] = 0
		q = []
		q.append(s)
		vis[s] = 1
		par[s] = -1
		pushed = False
		while len(q) != 0:
			cur = q.pop()
			for i in range(len(adj[cur])):
				nex = adj[cur][i]
				if vis[nex]:
					continue
				if cap[cur][nex] - flow[cur][nex] <= 0 and flow[nex][cur] <= 0:
					continue
				vis[nex] = 1
				q.append(nex)
				par[nex] = cur
				if nex == t:
					maxflow += pushflow(t, inf, s)
					pushed = True
					break
			if pushed:
				break
		if not pushed:
			break
	return maxflow

def main():
	data = [line.rstrip().split() for line in sys.stdin.readlines()]
	data = [[int(x) for x in row] for row in data]
	n = data[0][0]
	m = data[0][1]
	s = 2 * n
	t = 2 * n + 1
	adj = [[] for i in range(2 * n + 10)]
	summing = 0
	for i in range(n):
		u = data[1][i]
		cap[s][i] = u
		summing += u
		adj[s].append(i)
		adj[i].append(s)
	check = 0
	for i in range(n):
		u = data[2][i]
		cap[i + n][t] = u
		check += u
		adj[i + n].append(t)
		adj[t].append(i + n)
	if summing != check:
		print('NO')
		return
	for i in range(n):
		cap[i][i + n] = inf
		adj[i].append(i + n)
		adj[i + n].append(i)
	for i in range(m):
		u = data[i + 3][0]
		v = data[i + 3][1]
		u -= 1
		v -= 1
		cap[u][v + n] = inf
		cap[v][u + n] = inf
		adj[u].append(v + n)
		adj[v + n].append(u)
		adj[v].append(u + n)
		adj[u + n].append(v)
	check = bfs(n, m, s, t, adj)
	if check == summing:
		print('YES')
		for i in range(n):
			for j in range(n):
				print(flow[i][j + n], end=' ')
			print('\n', end='')
	else:
		print('NO')
main()