import sys import itertools #import more_itertools import time import heapq from math import radians, sin, cos, tan, sqrt, comb, pow from math import log, log2, log10, exp #from sortedcontainers import SortedSet, SortedDict, SortedList from collections import deque from operator import mul from functools import reduce, cmp_to_key from random import randint, randrange from bisect import bisect_left, bisect_right def input(): return sys.stdin.readline().replace('\n','') #sys.setrecursionlimit(1000000) md1 = 998244353 md2 = 10 ** 9 + 7 inf = 2 ** 31 + 1 primeset = set() primelist = [] # 入力ツール # 1行の入力を整数のリストとして受け取る def intlist(): return list(map(int, input().split())) # 1行から複数個の整数を受け取る def getints(): return tuple(map(int, input().split())) # n行の入力を文字列のリストとして受け取る def strtable(n): lst = [] for i in range(0, n): lst.append(input()) return lst # n行の入力を整数のリストとして受け取る def inttable(n): return list(map(int, strtable(n))) # 整数のリストをn個受け取る def intlisttable(n): lst = [] for i in range(0, n): lst.append(intlist()) return lst # n個のクエリを先頭だけ整数、他を文字列のリストとして受け取る def getquery(n): lst = [] for i in range(0, n): query = list(input().split()) qr = int(query[0]) lst.append((qr, query[1:])) return lst #========== # 生成ツール # H行W列のリスト生成 def twodimlist(h, w, init): # initの値で初期化 lst1 = [] for i in range(0, h): lst2 = [] for j in range(0, w): lst2.append(init) lst1.append(lst2) return lst1 # # 素数テーブルをsetとして生成 # def genprimeset(n): # n以下の素数を列挙 # global primeset # pt = SortedSet(primeset) # start = 2 # if len(pt) != 0: # start = pt[-1]+1 # for i in range(start, n+1): # pt.add(i) # idx = 0 # while pt[idx] ** 2 <= pt[-1]: # now = pt[idx] * 2 # while now <= pt[-1]: # pt.discard(now) # now += pt[idx] # idx += 1 # return set(pt) #========== # 数え上げ # 1次元数え上げ def cntx(itr, x): cnt = 0 for i in range(0, len(itr)): if itr[i] == x: cnt += 1 return cnt # 2次元数え上げ def twodimcntx(itr, x): sm = 0 for i in range(0, len(itr)): sm += cntx(itr[i], x) return sm # 全要素数え上げ def allcnt(itr): dct = {} for i in range(0, len(itr)): if itr[i] not in dct: dct[itr[i]] = 0 dct[itr[i]] += 1 return dct # 2次元全要素数え上げ def twodimallcnt(itr, x): dct = {} for i in range(0, len(itr)): for j in range(0, len(itr[i])): if itr[i][j] not in dct: dct[itr[i][j]] = 0 dct[itr[i][j]] += 1 return dct #========== # 計算ツール # 最大公約数 def gcd(x, y): if x < y: return gcd(y, x) if x % y == 0: return y return gcd(y, x%y) # 最小公倍数 def lcm(x, y): g = gcd(x, y) return (x*y) // g # フィボナッチ数列(0-indexで、a_0 = 0, a_1 = 1, 第n項まで生成) def genfib(n, m): # m == 0ならmodなし、m == 1ならmd1でmod, m == 2ならmd2でmod lst = [0, 1] if m == 0: for i in range(1, n): lst.append(lst[-2]+lst[-1]) else: md = md1 if m == 2: md = md2 for i in range(1, n): lst.append((lst[-2]+lst[-1])%md) return lst # 素数一覧の初期化 def primeinit(x): global primeset, primelist primeset = genprimeset(x) primelist = list(primeset) return # 素数判定 def isitprime(x): if x < 2: return False global primeset, primelist if len(primeset) == 0: primeinit(int(sqrt(x))+10) elif primelist[-1] ** 2 < x: primeinit(int(sqrt(x))+10) if x in primeset: return True for i in range(0, len(primelist)): if x % primelist[i] == 0: return False return True # 素因数分解 def factorize(x): global primeset, primelist if len(primeset) == 0: primeinit(int(sqrt(x))+10) elif primelist[-1] ** 2 < x: primeinit(int(sqrt(x))+10) dct = {} now = x for i in range(0, len(primelist)): if x < primelist[i] ** 2: break while now % primelist[i] == 0: if primelist[i] not in dct: dct[primelist[i]] = 0 dct[primelist[i]] += 1 now //= primelist[i] if now != 1: dct[now] = 1 return dct # Coprime判定 def coprime(x, y): return gcd(x, y) == 1 # 約数列挙 def divisor(x): s = set() for i in range(1, x+1): if x < i ** 2: break if x % i == 0: s.add(i) s.add(x//i) lst = sorted(list(s)) return lst # 約数数え上げ def countdivisor(x): fact = factorize(x) key = list(fact.keys()) cnt = 1 for i in range(0, len(key)): cnt *= fact[key[i]] + 1 return cnt # 大文字->小文字変換 def uppertolower(c): if 'A' <= c and c <= 'Z': return chr(ord(c)+32) return c # 小文字->大文字変換 def lowertoupper(c): if 'a' <= c and c <= 'z': return chr(ord(c)-32) return c # 大文字小文字相互変換 def upperlower(c): newc = uppertolower(c) if c == newc: newc = lowertoupper(c) return newc # 文字列の大->小変換 def uppertolowerstr(s): lst = [] for i in range(0, len(s)): lst.append(uppertolower(s[i])) return ''.join(lst) # 文字列の大->小変換 def lowertoupperstr(s): lst = [] for i in range(0, len(s)): lst.append(lowertoupper(s[i])) return ''.join(lst) # 文字列の大小相互変換 def upperlowerstr(s): lst = [] for i in range(0, len(s)): lst.append(upperlower(s[i])) return ''.join(lst) # x以上の要素の個数 def xormore(lst, x): # lstはソート済みにすること return len(lst) - bisect_left(lst, x) # xより大きい要素の個数 def morethanx(lst, x): # lstはソート済みにすること return len(lst) - bisect_right(lst, x) # x以下の要素の個数 def xorless(lst, x): # lstはソート済みにすること return bisect_right(lst, x) # x未満の要素の個数 def lessthanx(lst, x): # lstはソート済みにすること return bisect_left(lst, x) # 各桁の総和 def digitsum(x): nm = str(x) sm = 0 for i in range(0, len(nm)): sm += int(nm[i]) return sm # bitカウント(64bitまで) def popcount(x): now = x now = now - ((now >> 1) & 0x5555555555555555) now = (now & 0x3333333333333333) + ((now >> 2) & 0x3333333333333333) now = (now + (now >> 4)) & 0x0f0f0f0f0f0f0f0f n = 8 for i in range(0, 3): now += (now >> n) n *= 2 return now & 0x0000007f # xの累乗リスト(0乗からn乗まで) def powtable(x, n, m): # modなしの場合はm = 0に設定する md = m if m == 1: # m == 1ならmd1でmod md = md1 elif m == 2: # m == 2ならmd2でmod md = md2 lst = [1] for i in range(0, n): if md == 0: lst.append(lst[-1]*x) else: lst.append((lst[-1]*x)%md) return lst # 繰り返し2乗法 powdct = {} def initpow(): global powdct powdct = {} powdct[0] = 1 return def repeatpow(x, y, m): global powdct md = m if m == 1: md = md1 elif m == 2: md = md2 if y in powdct: return powdct[y] a = 1 if y % 2 == 1: a = x if m == 0: a = a*(repeatpow(x, y//2, m)**2) else: a = (a*(repeatpow(x, y//2, m)**2)) % md powdct[y] = a return a def powit(x, y, m): global powdct initpow() if x == 0: return 0 return repeatpow(x, y, m) # ========== # リスト操作 # 値の交換 def swap(lst, x, y): lst[x], lst[y] = lst[y], lst[x] # 累積和(先頭を0にする) def accum(itr): lst = [0] for i in range(0, len(itr)): lst.append(lst[-1]+itr[i]) return lst # itrをとりあえずリストに def itrtolist(itr): lst = [] for i in range(0, len(itr)): lst.append(itr[i]) return lst # 全ての順列 def permall(itr): lst = itrtolist(itr) return list(itertools.permutations(lst)) # itrの中身からn個を取り出す順列 def perm(itr, n): if len(itr) < n: return [] lst = itrtolist(itr) return list(itertools.permutations(lst, n)) # itrの中身からn個を取り出す組合せ def combi(itr, n): if len(itr) < n: return [] lst = itrtolist(itr) return list(itertools.combinations(lst, n)) # 0-indexのリストを1-indexのdictに書き換え def listtodict(lst): dct = {} for i in range(0, len(lst)): dct[i+1] = lst[i] return dct # ========== # グラフツール # グラフの初期化 def defgraph(vlist): graph = {} for i in range(0, len(vlist)): graph[vlist[i]] = set() return graph # 重み付きグラフの初期化 def defgraphw(vlist): graph = {} for i in range(0, len(vlist)): graph[vlist[i]] = {} return graph # 無向グラフ生成 def undirgraph(vlist, elist): # 辺の形式は(u, v) graph = defgraph(vlist) for i in range(0, len(elist)): u = elist[i][0] v = elist[i][1] graph[u].add(v) graph[v].add(u) return graph # 重み付き無向グラフ生成 def undirgraphw(vlist, elist, wdict): graph = defgraphw(vlist) for i in range(0, len(elist)): u = elist[i][0] v = elist[i][1] graph[u][v] = wdict[elist[i]] graph[v][u] = wdict[elist[i]] return graph # 有向グラフ生成 def dirgraph(vlist, elist): # 辺の形式は(u, v)で、向きはu -> v graph = defgraph(vlist) for i in range(0, len(elist)): u = elist[i][0] v = elist[i][1] graph[u].add(v) return graph # 重み付き有向グラフ生成 def dirgraphw(vlist, elist, wdict): graph = defgraphw(vlist) for i in range(0, len(elist)): u = elist[i][0] v = elist[i][1] graph[u][v] = wdict[elist[i]] return graph # 重み無し最短ステップ def shortest(vlist, elist, graph, st, gl): if st not in graph or gl not in graph: return -1 yet = set(vlist) q = deque() q.append((st, 0)) yet.discard(st) while len(q) != 0: now = q.popleft() v = now[0] s = now[1] if v == gl: return s lst = list(graph[v]) for i in range(0, len(lst)): nxtv = lst[i] if nxtv in yet: yet.discard(nxtv) q.append((nxtv, s+1)) return -1 # ダイクストラ def dijkstra(vlist, elist, graph, st): cur = {} for i in range(0, len(vlist)): cur[vlist[i]] = inf cur[st] = 0 dist = {} h = [] heapq.heapify(h) heapq.heappush(h, (0, st)) while len(h) != 0: now = heapq.heappop(h) d = now[0] v = now[1] if v in dist: continue dist[v] = d lst = list(graph[v].keys()) for i in range(0, len(lst)): nxt = lst[i] if nxt not in dist: nxtd = dist[v] + graph[v][nxt] cur[nxt] = min(cur[nxt], nxtd) if cur[nxt] == nxtd: heapq.heappush(h, (nxtd, nxt)) return dist # Union-Find生成 def genunionfind(vlist, elist): # 辺の形式は(u, v) graph = defgraph(vlist) root = {} vcnt = {} flag = False for i in range(0, len(vlist)): root[vlist[i]] = vlist[i] vcnt[vlist[i]] = 1 for i in range(0, len(elist)): u = elist[i][0] v = elist[i][1] ur = root[u] vr = root[v] if ur == vr: flag = True else: H = ur L = vr if vcnt[ur] < vcnt[vr]: H = vr L = ur graph[H].add(L) vcnt[H] += vcnt[L] q = deque() q.append(L) while len(q) != 0: now = q.popleft() root[now] = H lst = list(graph[now]) for j in range(0, len(lst)): q.append(lst[j]) return (graph, root, vcnt, flag) # (グラフ, 根, 頂点の数, ループ検出)の形式で返す # ========== # fenwick木 fenwick = [] # fenwickを初期化 def initfenwick(n, init): global fenwick fenwick = [] for i in range(0, n+1): fenwick.append(init) return # idx番目までの和を求める def fwsum(idx): sm = 0 now = idx while now > 0: sm += fenwick[now] now -= -now & now return sm # idx番目の値にxを足す def fwadd(idx, x): global fenwick now = idx while now < len(fenwick): fenwick[now] += x now += -now & now return # 転倒数 def inversion(A): global fenwick initfenwick(len(A), 0) sm = 0 for i in range(0, len(A)): sm += i - fwsum(A[i]) fwadd(A[i], 1) return sm # ========== # ハッシュ Mset = set() Mlist = [] # Mの候補の素数を生成 def initM(): global Mset, Mlist a = 10 ** 9 for i in range(-10000, 10001): if isitprime(a+i): Mset.add(a+i) Mlist = list(Mset) return # Bの累乗を生成 def genB(b, m, n): lst = [1] for i in range(0, n): lst.append((lst[-1]*b)%m) return lst # ハッシュテーブル生成 def genH(b, m, s): lst = [0] for i in range(0, len(s)): a = ord(s[i]) - ord('a') + 1 lst.append((b*lst[-1]+a)%m) return lst # 部分文字列のハッシュ値を求める def Hval(Hlist, Blist, M, L, R): return (Hlist[R] - Blist[R-L+1]*Hlist[L-1]) % M # ハッシュを複数生成 def multihash(s): global Mset, Mlist if len(Mlist) == 0: initM() bm = {} for i in range(0, 5): b = randint(9900, 11000) m = Mlist[randrange(0, len(Mlist))] while (b, m) in bm: b = randint(9900, 11000) m = Mlist[randrange(0, len(Mlist))] Blist = genB(b, m, len(s)) Hlist = genH(b, m, s) bm[(b, m)] = (Blist, Hlist) return bm # 指定したb, mでハッシュ生成 def multihashconst(s, bmkey): h = {} for i in range(0, 5): b = bmkey[i][0] m = bmkey[i][1] Blist = genB(b, m, len(s)) Hlist = genH(b, m, s) h[(b, m)] = (Blist, Hlist) return h # ========== # 【問題要約】 # # ========== # コードはここから書く N, M = getints() vlist = list(range(1, N+1)) A = intlist() elist = [] for i in range(0, M): U, V = getints() elist.append((U, V)) graph = undirgraph(vlist, elist) ans = [] for i in range(0, 2**N): mineexists = [] now = i for j in range(0, N): mineexists.append(now % 2) now //= 2 minecount = [] for j in range(0, N): minecount.append(0) for j in range(0, N): v = vlist[j] lst = list(graph[v]) for k in range(0, len(lst)): minecount[j] += mineexists[lst[k]-1] subflag = True for j in range(0, N): if minecount[j] != A[j]: subflag = False if subflag: ans.append(mineexists) if len(ans) == 0: print('No') else: print('Yes') chosen = randrange(0, len(ans)) print(' '.join(map(str, ans[chosen])))