Robot Bender decided to make Fray a birthday present. He drove n nails and numbered them from 1 to n in some order. Bender decided to make a picture using metal rods. The picture is a closed polyline, which vertices should be nails (in the given order). The segments of the polyline should be parallel to the coordinate axes. Polyline is allowed to have self-intersections. Bender can take a rod and fold it exactly once in any place to form an angle of 90 degrees. Then he can attach the place of the fold to some unoccupied nail and attach two ends of this rod to adjacent nails. A nail is considered unoccupied if there is no rod attached to it (neither by it's end nor the by the fold place). No rod could be used twice. It is not required to use all the rods.

Help Bender to solve this difficult task.

Input

The first line contains two positive integers n and m (4 ≤ n ≤ 500, 2 ≤ m ≤ 500, n is even) — the amount of nails and the amount of rods. i-th of the following n lines contains a pair of integers, denoting the coordinates of the i-th nail. Nails should be connected in the same order as they are given in the input. The last line contains m integers — the lenghts of the rods. All coordinates do not exceed 104 by absolute value. Lengths of the rods are between 1 and 200 000. No rod can be used twice. It is guaranteed that all segments of the given polyline are parallel to coordinate axes. No three consecutive nails lie on the same line.

Output

If it is impossible to solve Bender's problem, output NO. Otherwise, output YES in the first line, and in the second line output n numbers — i-th of them should be the number of rod, which fold place is attached to the i-th nail, or -1, if there is no such rod.

If there are multiple solutions, print any of them.

Examples

Input

4 2
0 0
0 2
2 2
2 0
4 4


Output

YES
1 -1 2 -1 


Input

6 3
0 0
1 0
1 1
2 1
2 2
0 2
3 2 3


Output

YES
1 -1 2 -1 3 -1 


Input

6 3
0 0
1 0
1 1
2 1
2 2
0 2
2 2 3


Output

NO

Difficulty: MEDIUM_HARD
Tags: Implementation

Starter code:

Solutions:
from collections import defaultdict

def main():
	(n, m) = map(int, input().split())
	tmp = list((tuple(map(int, input().split())) for _ in range(n)))
	nails = [abs(a - c) + abs(b - d) for ((a, b), (c, d)) in zip(tmp, tmp[2:] + tmp[:2])]
	segments = defaultdict(list)
	for (i, s) in enumerate(map(int, input().split()), 1):
		segments[s].append(i)
	for shift in (-1, 0):
		res = [-1] * n
		for nailidx in range(shift, n + shift, 2):
			nail = nails[nailidx]
			if nail in segments and segments[nail]:
				res[(nailidx + 1) % n] = segments[nail].pop()
			else:
				break
		else:
			print('YES')
			print(' '.join(map(str, res)))
			return
	print('NO')
main()


def dist(a, b):
	return abs(a[0] - b[0]) + abs(a[1] - b[1])

def get_sorted_required_pruts(dists):
	res = [dists[i * 2] + dists[i * 2 + 1] for i in range(len(dists) // 2)]
	res = [(i, x) for (i, x) in enumerate(res)]
	return sorted(res, key=lambda x: x[1])

def get_answer(pruts, required_pruts):
	i = 0
	j = 0
	answer = 'YES'
	seq = []
	while i < len(required_pruts):
		if j == len(pruts):
			answer = 'NO'
			return (answer, None)
		if pruts[j][1] > required_pruts[i][1]:
			answer = 'NO'
			return (answer, None)
		if pruts[j][1] < required_pruts[i][1]:
			j += 1
		else:
			seq.append((required_pruts[i][0], pruts[j][0] + 1))
			i += 1
			j += 1
	return (answer, [x[1] for x in sorted(seq)])
(n, m) = map(int, input().split())
gvozdi = [None] * n
for i in range(n):
	gvozdi[i] = list(map(int, input().split()))
pruts = list(map(int, input().split()))
pruts = [(i, p) for (i, p) in enumerate(pruts)]
pruts = sorted(pruts, key=lambda x: x[1])
dists = [dist(gvozdi[i], gvozdi[i + 1]) for i in range(len(gvozdi) - 1)]
dists.append(dist(gvozdi[0], gvozdi[-1]))
even_required_pruts = get_sorted_required_pruts(dists)
odd_required_pruts = get_sorted_required_pruts(dists[-1:] + dists[:-1])
(even_answer, even_seq) = get_answer(pruts, even_required_pruts)
(odd_answer, odd_seq) = get_answer(pruts, odd_required_pruts)
if even_answer == 'NO' and odd_answer == 'NO':
	print('NO')
elif even_answer == 'YES':
	print('YES')
	even_seq = [even_seq[i // 2] if i % 2 == 1 else -1 for i in range(n)]
	print(' '.join(map(str, even_seq)))
else:
	print('YES')
	odd_seq = [odd_seq[i // 2] if i % 2 == 0 else -1 for i in range(n)]
	print(' '.join(map(str, odd_seq)))


from collections import defaultdict
(n, m) = map(int, input().split())
(a, b) = map(int, input().split())
(x, y) = (a, b)
s = [0] * n
for i in range(n - 1):
	(u, v) = map(int, input().split())
	if u == a:
		(s[i], b) = (abs(v - b), v)
	else:
		(s[i], a) = (abs(u - a), u)
s[n - 1] = abs(a - x) + abs(b - y)
(a, b) = (defaultdict(list), defaultdict(list))
for (i, j) in enumerate(map(int, input().split()), 1):
	a[j].append(i)
for j in a:
	b[j] = a[j][:]
q = []
for i in range(0, n, 2):
	j = s[i] + s[i + 1]
	if not a[j]:
		break
	q.append(str(a[j].pop()))
if 2 * len(q) == n:
	print('YES\n-1 ' + ' -1 '.join(q))
else:
	q = []
	for i in range(0, n, 2):
		j = s[i] + s[i - 1]
		if not b[j]:
			break
		q.append(str(b[j].pop()))
	if 2 * len(q) == n:
		print('YES\n' + ' -1 '.join(q) + ' -1')
	else:
		print('NO')


import os
import sys
import math
from io import BytesIO, IOBase
from fractions import Fraction
import collections
from itertools import permutations
from collections import defaultdict
from collections import deque
import threading
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')

class Factorial:

	def __init__(self, MOD):
		self.MOD = MOD
		self.factorials = [1, 1]
		self.invModulos = [0, 1]
		self.invFactorial_ = [1, 1]

	def calc(self, n):
		if n <= -1:
			print('Invalid argument to calculate n!')
			print('n must be non-negative value. But the argument was ' + str(n))
			exit()
		if n < len(self.factorials):
			return self.factorials[n]
		nextArr = [0] * (n + 1 - len(self.factorials))
		initialI = len(self.factorials)
		prev = self.factorials[-1]
		m = self.MOD
		for i in range(initialI, n + 1):
			prev = nextArr[i - initialI] = prev * i % m
		self.factorials += nextArr
		return self.factorials[n]

	def inv(self, n):
		if n <= -1:
			print('Invalid argument to calculate n^(-1)')
			print('n must be non-negative value. But the argument was ' + str(n))
			exit()
		p = self.MOD
		pi = n % p
		if pi < len(self.invModulos):
			return self.invModulos[pi]
		nextArr = [0] * (n + 1 - len(self.invModulos))
		initialI = len(self.invModulos)
		for i in range(initialI, min(p, n + 1)):
			next = -self.invModulos[p % i] * (p // i) % p
			self.invModulos.append(next)
		return self.invModulos[pi]

	def invFactorial(self, n):
		if n <= -1:
			print('Invalid argument to calculate (n^(-1))!')
			print('n must be non-negative value. But the argument was ' + str(n))
			exit()
		if n < len(self.invFactorial_):
			return self.invFactorial_[n]
		self.inv(n)
		nextArr = [0] * (n + 1 - len(self.invFactorial_))
		initialI = len(self.invFactorial_)
		prev = self.invFactorial_[-1]
		p = self.MOD
		for i in range(initialI, n + 1):
			prev = nextArr[i - initialI] = prev * self.invModulos[i % p] % p
		self.invFactorial_ += nextArr
		return self.invFactorial_[n]

class Combination:

	def __init__(self, MOD):
		self.MOD = MOD
		self.factorial = Factorial(MOD)

	def ncr(self, n, k):
		if k < 0 or n < k:
			return 0
		k = min(k, n - k)
		f = self.factorial
		return f.calc(n) * f.invFactorial(max(n - k, k)) * f.invFactorial(min(k, n - k)) % self.MOD

def dist(a, b):
	return abs(a[0] - b[0]) + abs(a[1] - b[1])

def get_sorted_required_pruts(dists):
	res = [dists[i * 2] + dists[i * 2 + 1] for i in range(len(dists) // 2)]
	res = [(i, x) for (i, x) in enumerate(res)]
	return sorted(res, key=lambda x: x[1])

def get_answer(pruts, required_pruts):
	i = 0
	j = 0
	answer = 'YES'
	seq = []
	while i < len(required_pruts):
		if j == len(pruts):
			answer = 'NO'
			return (answer, None)
		if pruts[j][1] > required_pruts[i][1]:
			answer = 'NO'
			return (answer, None)
		if pruts[j][1] < required_pruts[i][1]:
			j += 1
		else:
			seq.append((required_pruts[i][0], pruts[j][0] + 1))
			i += 1
			j += 1
	return (answer, [x[1] for x in sorted(seq)])
(n, m) = map(int, input().split())
gvozdi = [None] * n
for i in range(n):
	gvozdi[i] = list(map(int, input().split()))
pruts = list(map(int, input().split()))
pruts = [(i, p) for (i, p) in enumerate(pruts)]
pruts = sorted(pruts, key=lambda x: x[1])
dists = [dist(gvozdi[i], gvozdi[i + 1]) for i in range(len(gvozdi) - 1)]
dists.append(dist(gvozdi[0], gvozdi[-1]))
even_required_pruts = get_sorted_required_pruts(dists)
odd_required_pruts = get_sorted_required_pruts(dists[-1:] + dists[:-1])
(even_answer, even_seq) = get_answer(pruts, even_required_pruts)
(odd_answer, odd_seq) = get_answer(pruts, odd_required_pruts)
if even_answer == 'NO' and odd_answer == 'NO':
	print('NO')
elif even_answer == 'YES':
	print('YES')
	even_seq = [even_seq[i // 2] if i % 2 == 1 else -1 for i in range(n)]
	print(' '.join(map(str, even_seq)))
else:
	print('YES')
	odd_seq = [odd_seq[i // 2] if i % 2 == 0 else -1 for i in range(n)]
	print(' '.join(map(str, odd_seq)))


(n, m) = map(int, input().split())
s = []
for i in range(n):
	a = map(int, input().split())
	a = list(a)
	s.append(a)
s_chet = []
for i in range(1, n - 1, 2):
	q = abs(s[i][0] - s[i - 1][0] + (s[i][1] - s[i - 1][1])) + abs(s[i][0] - s[i + 1][0] + (s[i][1] - s[i + 1][1]))
	s_chet.append((i + 1, q))
q = abs(s[-1][0] - s[-2][0] + (s[-1][1] - s[-2][1])) + abs(s[-1][0] - s[0][0] + (s[-1][1] - s[0][1]))
s_chet.append((n, q))
s_nechet = []
for i in range(2, n - 1, 2):
	q = abs(s[i][0] - s[i - 1][0] + (s[i][1] - s[i - 1][1])) + abs(s[i][0] - s[i + 1][0] + (s[i][1] - s[i + 1][1]))
	s_nechet.append((i + 1, q))
q = abs(s[-1][0] - s[0][0] + (s[-1][1] - s[0][1])) + abs(s[1][0] - s[0][0] + (s[1][1] - s[0][1]))
s_nechet.append((1, q))
ss = map(int, input().split())
ss = [[i + 1, ss_i] for (i, ss_i) in enumerate(ss)]
s_chet.sort(key=lambda x: x[1])
s_nechet.sort(key=lambda x: x[1])
ss.sort(key=lambda x: x[1])
prut_chet = [-1] * n
chet = True
j = 0
for i in range(len(s_chet)):
	while j < len(ss) and ss[j][1] < s_chet[i][1]:
		j += 1
	if j == len(ss) or ss[j][1] > s_chet[i][1]:
		chet = False
		break
	if s_chet[i][1] == ss[j][1]:
		prut_chet[s_chet[i][0] - 1] = ss[j][0]
		j += 1
		continue
if chet:
	print('YES')
	print(' '.join(map(str, prut_chet)))
else:
	prut_nechet = [-1] * n
	nechet = True
	j = 0
	for i in range(len(s_nechet)):
		while j < len(ss) and ss[j][1] < s_nechet[i][1]:
			j += 1
		if j == len(ss) or ss[j][1] > s_nechet[i][1]:
			nechet = False
			break
		if s_nechet[i][1] == ss[j][1]:
			prut_nechet[s_nechet[i][0] - 1] = ss[j][0]
			j += 1
			continue
	if nechet:
		print('YES')
		print(' '.join(map(str, prut_nechet)))
	else:
		print('NO')


import sys
(n, m) = map(int, input().split())
points = [tuple(map(int, input().split())) for i in range(n)]
points.append(points.pop(0))
segments = []
(x, y) = points[-1]
for (a, b) in points:
	if x == a:
		segments.append(abs(y - b))
	else:
		segments.append(abs(x - a))
	(x, y) = (a, b)
rods = list(map(int, input().split()))
rod_indices = {}
for (index, rod) in enumerate(rods):
	rod_indices.setdefault(rod, []).append(index + 1)
for offset in range(2):
	target_indices = rod_indices.copy()
	assignment = [-1 for i in range(n)]
	for i in range(offset, n, 2):
		target = segments[(i - 1) % n] + segments[i]
		if target not in target_indices or target_indices[target] == []:
			assignment = None
			break
		assignment[i] = target_indices[target].pop()
	if assignment != None:
		print('YES')
		print(' '.join(map(str, assignment)))
		sys.exit()
print('NO')