You are given set of n points in 5-dimensional space. The points are labeled from 1 to n. No two points coincide.

We will call point a bad if there are different points b and c, not equal to a, from the given set such that angle between vectors $\vec{ab}$ and $\vec{ac}$ is acute (i.e. strictly less than $90^{\circ}$). Otherwise, the point is called good.

The angle between vectors $\vec{x}$ and $\vec{y}$ in 5-dimensional space is defined as $\operatorname{arccos}(\frac{\vec{x} \cdot \vec{y}}{|\vec{x}||\vec{y}|})$, where $\vec{x} \cdot \vec{y} = x_{1} y_{1} + x_{2} y_{2} + x_{3} y_{3} + x_{4} y_{4} + x_{5} y_{5}$ is the scalar product and $|\vec{x}|= \sqrt{\vec{x} \cdot \vec{x}}$ is length of $\vec{x}$.

Given the list of points, print the indices of the good points in ascending order.


-----Input-----

The first line of input contains a single integer n (1 ≤ n ≤ 10^3) — the number of points.

The next n lines of input contain five integers a_{i}, b_{i}, c_{i}, d_{i}, e_{i} (|a_{i}|, |b_{i}|, |c_{i}|, |d_{i}|, |e_{i}| ≤ 10^3)  — the coordinates of the i-th point. All points are distinct.


-----Output-----

First, print a single integer k — the number of good points.

Then, print k integers, each on their own line — the indices of the good points in ascending order.


-----Examples-----
Input
6
0 0 0 0 0
1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
0 0 0 1 0
0 0 0 0 1

Output
1
1

Input
3
0 0 1 2 0
0 0 9 2 0
0 0 5 9 0

Output
0



-----Note-----

In the first sample, the first point forms exactly a $90^{\circ}$ angle with all other pairs of points, so it is good.

In the second sample, along the cd plane, we can see the points look as follows:

[Image]

We can see that all angles here are acute, so no points are good.

Source: codeforces | Difficulty: MEDIUM_HARD
Tags: Geometry

Mathematics

Complete search


Solutions:
n = int(input())
points = []
for i in range(n):
	pt = list(map(int, input().split()))
	points.append(pt)
flag = [1] * n
for i in range(n):
	a = points[i]
	ok = False
	for j in range(n):
		if ok:
			break
		if j == i:
			continue
		b = points[j]
		for k in range(n):
			if k == i or k == j:
				continue
			c = points[k]
			summ = 0
			for z in range(5):
				u = b[z] - a[z]
				v = c[z] - a[z]
				summ += u * v
			if summ > 0:
				flag[i] = 0
				ok = True
				break
res = []
for i in range(n):
	if flag[i]:
		res.append(i + 1)
print(len(res))
for i in range(len(res)):
	print(res[i])


import os
import sys
from io import BytesIO, IOBase
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')
from math import gcd, ceil

def prod(a, mod=10 ** 9 + 7):
	ans = 1
	for each in a:
		ans = ans * each % mod
	return ans

def lcm(a, b):
	return a * b // gcd(a, b)

def binary(x, length=16):
	y = bin(x)[2:]
	return y if len(y) >= length else '0' * (length - len(y)) + y
for _ in range(int(input()) if not True else 1):
	n = int(input())
	from math import acos, pi, sqrt
	points = []
	for i in range(n):
		points += [list(map(int, input().split()))]
	if n <= 69:
		ans = []
		for i in range(n):
			pos = True
			for j in range(n):
				for k in range(n):
					if j == i or k == i or j == k:
						continue
					ab = [points[i][x] - points[j][x] for x in range(5)]
					ac = [points[i][x] - points[k][x] for x in range(5)]
					xy = sum([ab[x] * ac[x] for x in range(5)])
					m = sqrt(sum((x ** 2 for x in ab))) * sqrt(sum((x ** 2 for x in ac)))
					angle = acos(xy / m) * 180 / pi
					if angle < 90:
						pos = False
						break
				if not pos:
					break
			if pos:
				ans += [i + 1]
		print(len(ans))
		print(*ans)
	else:
		print(0)


from math import acos, sqrt, degrees

class BadPoint(Exception):
	pass

def vect(point1, point2):
	return [p2 - p1 for (p1, p2) in zip(point1, point2)]

def product(vect1, vect2):
	return sum([v1 * v2 for (v1, v2) in zip(vect1, vect2)])

def angle(vect1, vect2):
	return degrees(acos(product(vect1, vect2) / (sqrt(product(vect1, vect1)) * sqrt(product(vect2, vect2)))))
n = int(input())
points = []
for _ in range(n):
	points.append(list(map(int, input().split())))
if n > 15:
	print(0)
	exit(0)
cnt = []
for i in range(n):
	vectors = []
	for j in range(n):
		if i != j:
			vectors.append(vect(points[i], points[j]))
	try:
		for ii in range(len(vectors)):
			for jj in range(len(vectors)):
				if ii != jj:
					if angle(vectors[ii], vectors[jj]) < 90:
						raise BadPoint()
	except BadPoint:
		pass
	else:
		cnt.append(i)
print(len(cnt))
print(*sorted(map(lambda x: x + 1, cnt)), sep='\n')


d = lambda i, j, k: sum(((a - c) * (b - c) for (a, b, c) in zip(p[i], p[j], p[k]))) * (i != j)
n = int(input())
r = range(n)
p = [list(map(int, input().split())) for i in r]
t = [k + 1 for k in r if all((d(i, j, k) <= 0 for i in r for j in r))] if n < 12 else []
for q in [len(t)] + t:
	print(q)


n = int(input())
p = [tuple(map(int, input().split())) for i in range(n)]

def d(a, b):
	return tuple((x - y for (x, y) in zip(a, b)))

def m(a, b):
	return sum((x * y for (x, y) in zip(a, b)))
good_points = []
for i in range(n):
	good = True
	for j in range(n):
		if j == i:
			continue
		ab = d(p[j], p[i])
		for k in range(j + 1, n):
			if k == i:
				continue
			ac = d(p[k], p[i])
			if m(ab, ac) > 0:
				good = False
				break
		if not good:
			break
	if good:
		good_points.append(i)
print(len(good_points))
for i in good_points:
	print(i + 1)


n = int(input())
p = []
answer = []
for j in range(n):
	p.append(list(map(int, input().split())))

def g(i):
	for j in range(n):
		for k in range(j + 1, n):
			if i == j or i == k:
				continue
			if sum(((p[j][l] - p[i][l]) * (p[k][l] - p[i][l]) for l in range(5))) > 0:
				return
	answer.append(i + 1)
for i in range(n):
	g(i)
print(len(answer))
print(*answer)


n = int(input())
a = []
used = [0 for i in range(n)]

def judge(s1, s2, s3):
	sum = 0
	for i in range(5):
		sum += (a[s1][i] - a[s3][i]) * (a[s2][i] - a[s3][i])
	if sum <= 0:
		return 1
	else:
		return 0
for i in range(n):
	b = [int(x) for x in input().split(' ')]
	a.append(b)
if n <= 100:
	num = 0
	flag = 0
	for i in range(n):
		flag = 0
		for j in range(n):
			if i == j:
				continue
			for k in range(j + 1, n):
				if judge(k, j, i) == 0:
					flag = 1
		if flag == 0:
			used[i] = 1
			num += 1
	print(num, '\n')
	for i in range(n):
		if used[i] == 1:
			print(i + 1, ' ')
else:
	print('0')


n = int(input())
if n > 20:
	print(0)
else:
	s = []
	for i in range(n):
		s.append([int(i) for i in input().split()])
	p = []
	for i in range(n):
		p.append(0)
		for j in range(n):
			for l in range(j):
				b = 0
				for k in range(5):
					b += (s[i][k] - s[j][k]) * (s[i][k] - s[l][k])
				if b > 0:
					p[-1] += 1
	u = 0
	ans = []
	for i in range(n):
		if p[i] == 0:
			u += 1
			ans.append(i + 1)
	print(u)
	for i in ans:
		print(i)


n = int(input())
A = []
js = 0
B = []
for i in range(n):
	A.append(list(map(int, input().split())))

def product(a, b, c):
	pr = 0
	for m in range(5):
		pr = pr + (A[b][m] - A[a][m]) * (A[c][m] - A[a][m])
	return pr
if n > 11:
	print(0)
else:
	for j in range(n):
		k = 0
		l = 0
		flag = 0
		while k < n:
			l = k + 1
			while l < n:
				pro = product(j, k, l)
				if l != j and k != j and (pro > 0):
					flag = 1
					break
				else:
					l = l + 1
			if flag == 1:
				break
			else:
				k = k + 1
		if k == n:
			js = js + 1
			B.append(j + 1)
	print(js)
	for f in range(js):
		print(B[f])


import math

def check(i, j, k):
	a = []
	b = []
	for ii in range(len(i)):
		a.append(j[ii] - i[ii])
		b.append(k[ii] - i[ii])
	la = 0
	lb = 0
	scal = 0
	for ii in range(len(i)):
		la += a[ii] * a[ii]
		lb += b[ii] * b[ii]
		scal += a[ii] * b[ii]
	return scal / (la * lb) <= 0

def count(w):
	ans = []
	for i in range(len(w)):
		f = 1
		for j in w:
			if w[i] == j:
				continue
			for k in w:
				if w[i] == k or j == k:
					continue
				f &= check(w[i], j, k)
		ans += [i + 1] if f else []
	return [len(ans)] + ans
n = int(input())
w = []
for i in range(n):
	w.append(list(map(int, input().split())))
if n < 20:
	print(*count(w), end='\n')
else:
	print(0)


from math import *
n = int(input())
arr = [list(map(int, input().split())) for i in range(n)]
ans = [True] * n
for a in range(n):
	for b in range(n):
		bad = False
		for c in range(n):
			if arr[b] != arr[a] and arr[c] != arr[a] and (arr[b] != arr[c]):
				ab = [arr[b][i] - arr[a][i] for i in range(5)]
				ac = [arr[c][i] - arr[a][i] for i in range(5)]
				sc = sum([ab[i] * ac[i] for i in range(5)])
				lab = sum([ab[i] ** 2 for i in range(5)]) ** 0.5
				lac = sum([ac[i] ** 2 for i in range(5)]) ** 0.5
				try:
					if degrees(acos(sc / (lab * lac))) < 90:
						ans[a] = False
						bad = True
						break
				except:
					pass
		if bad:
			break
print(sum(ans))
for i in range(n):
	if ans[i]:
		print(i + 1)


def vec(c0, a, b):
	an = 0
	for i in range(5):
		an += (a[i] - c0[i]) * (b[i] - c0[i])
	return an
n = int(input())
if n > 80:
	print(0)
	exit(0)
a = [[0] * 5 for i in range(n)]
for i in range(n):
	a[i] = [int(j) for j in input().split()]
ans = []
for i in range(n):
	flag = True
	for j in range(n):
		for k in range(n):
			if i != j and j != k and (k != i) and (vec(a[i], a[j], a[k]) > 0):
				flag = False
	if flag:
		ans.append(i)
print(len(ans))
for i in ans:
	print(i + 1)


def sc(x, y):
	return x[0] * y[0] + x[1] * y[1] + x[2] * y[2] + x[3] * y[3] + x[4] * y[4]

def check(a, b, c):
	if sc([b[0] - a[0], b[1] - a[1], b[2] - a[2], b[3] - a[3], b[4] - a[4]], [c[0] - a[0], c[1] - a[1], c[2] - a[2], c[3] - a[3], c[4] - a[4]]) > 0:
		return True
	return False
n = int(input())
data = []
for i in range(n):
	a = list(map(int, input().split()))
	data.append(a)
an = 0
t = False
ann = []
for i in range(n):
	for j in range(n):
		if i == j:
			continue
		for k in range(n):
			if k == i or k == j:
				continue
			if check(data[i], data[j], data[k]):
				an += 1
				t = True
				break
		if t:
			break
	if not t:
		ann.append(i + 1)
	t = False
print(n - an)
print(*ann)


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
n = int(input())
l = []
for i in range(n):
	l.append(list(map(int, input().split())))
if n >= 50:
	print(0)
	sys.exit(0)
if n <= 2:
	print(n)
	for i in range(n):
		print(i + 1)
	sys.exit(0)
er = set()
for i in range(n):
	f = 0
	for j in range(n):
		for k in range(n):
			if i == j or i == k or j == k:
				continue
			w = 0
			for d in range(5):
				w += (l[i][d] - l[j][d]) * (l[i][d] - l[k][d])
			if w > 0:
				f = 1
				break
		if f == 1:
			break
	if f == 0:
		er.add(i + 1)
print(len(er))
print(*er, sep='\n')


n = int(input())
p = [tuple(map(int, input().split())) for i in range(n)]

def d(a, b):
	return (a[0] - b[0], a[1] - b[1], a[2] - b[2], a[3] - b[3], a[4] - b[4])

def m(a, b):
	t = 0
	for i in range(5):
		t += a[i] * b[i]
	return t
good_points = []
for i in range(n):
	good = True
	for j in range(n):
		if j == i:
			continue
		ab = d(p[j], p[i])
		for k in range(j + 1, n):
			if k == i:
				continue
			ac = d(p[k], p[i])
			if m(ab, ac) > 0:
				good = False
				break
		if not good:
			break
	if good:
		good_points.append(i)
print(len(good_points))
for i in good_points:
	print(i + 1)


def sc(i, j, k):
	xx = 0
	for t in range(5):
		xx += (m[i][t] - m[j][t]) * (m[i][t] - m[k][t])
	return xx
n = int(input())
m = []
mm = n
ans = []
if n > 36:
	print('0')
else:
	for i in range(n):
		ans.append(1)
		(a, b, c, d, e) = map(int, input().split())
		m.append([a, b, c, d, e])
	for i in range(n):
		for j in range(n):
			if i != j:
				for k in range(n):
					if i != k and j != k:
						if sc(i, j, k) > 0:
							ans[i] = -1
	for i in range(n):
		if ans[i] == -1:
			mm += -1
	print(mm)
	for i in range(n):
		if ans[i] == 1:
			print(i + 1)


import math
import collections
import bisect
import heapq
import time
import random
import itertools
N = int(input())
P = []
for i in range(N):
	P.append([int(x) for x in input().split()])

def length(a):
	return math.sqrt(sum([x ** 2 for x in a]))

def angle(a, b):
	c = sum((a[i] * b[i] for i in range(len(a))))
	la = length(a)
	lb = length(b)
	if la and lb:
		return math.acos(c / la / lb)
	return -1

def cos(a, b, c):
	x = [b[i] - a[i] for i in range(len(a))]
	y = [c[i] - a[i] for i in range(len(a))]
	c = sum((x[i] * y[i] for i in range(len(x))))
	return c
ans = []
for i in range(N):
	bad = False
	for j in range(N):
		if bad:
			break
		if i != j:
			for k in range(N):
				if k != i and k != j:
					if cos(P[i], P[j], P[k]) > 0:
						bad = True
						break
	if not bad:
		ans.append(i + 1)
print(len(ans))
if ans:
	print(' '.join(map(str, ans)))


import math
import operator
PI = math.pi

def is_acute(p, q, r):
	pq = list(map(operator.sub, p, q))
	rq = list(map(operator.sub, r, q))
	dot_prod = sum((i[0] * i[1] for i in zip(pq, rq)))
	norm_pq = math.sqrt(sum((i[0] * i[1] for i in zip(pq, pq))))
	norm_rq = math.sqrt(sum((i[0] * i[1] for i in zip(rq, rq))))
	cos_pqr = dot_prod / (norm_rq * norm_pq)
	arccos_pqr = math.acos(cos_pqr)
	if arccos_pqr < PI / 2:
		return True
	else:
		return False
n = int(input())
points = []
for i in range(n):
	points.append(list(map(int, input().split())))
bad_points = [False for i in range(n)]
for i in range(n):
	cond = False
	for j in range(n):
		for k in range(n):
			if i == j or j == k or k == i:
				continue
			if bad_points[i]:
				cond = True
				continue
			if is_acute(points[j], points[i], points[k]):
				bad_points[i] = True
				cond = True
				continue
			else:
				bad_points[j] = True
				bad_points[k] = True
			if cond:
				break
		if cond:
			break
print(n - sum(bad_points))
for i in range(n):
	if not bad_points[i]:
		print(i + 1, end=' ')
print('\n')


(n, p, ans) = (int(input()), [], [])
if n > 123:
	(print(0), exit(0))
for _ in range(n):
	p.append(list(map(int, input().split())))
for i in range(0, n):
	good = True
	for j in range(0, n):
		for k in range(j + 1, n):
			good &= sum(((p[j][l] - p[i][l]) * (p[k][l] - p[i][l]) for l in range(5))) <= 0
	if good:
		ans.append(1 + i)
print(len(ans))
print(*ans)


from sys import stdin, stdout
from math import hypot
import random
import itertools
from functools import reduce
import operator
reduce(operator.mul, (3, 4, 5), 1)

def isAcute(x, y):
	return sum([i * j for (i, j) in zip(x, y)])
n = int(stdin.readline().rstrip())
pointList = [(0, 0, 0, 0, 0)] * n
for i in range(n):
	(a, b, c, d, e) = map(int, stdin.readline().rstrip().split())
	pointList[i] = (a, b, c, d, e)
notConsidered = set(range(n))
isGood = set()
while len(notConsidered) > 0:
	i = random.sample(notConsidered, 1)[0]
	x = pointList[i]
	for (j, k) in itertools.combinations(range(n), 2):
		if j == i or k == i:
			continue
		y = pointList[j]
		z = pointList[k]
		xy = [n - m for (n, m) in zip(y, x)]
		yz = [n - m for (n, m) in zip(z, y)]
		xz = [n - m for (n, m) in zip(z, x)]
		if isAcute(yz, xz) > 0:
			notConsidered.discard(k)
		if isAcute(xy, yz) < 0:
			notConsidered.discard(j)
		if isAcute(xy, xz) > 0:
			notConsidered.discard(i)
			break
	if i in notConsidered:
		isGood.add(i)
		notConsidered.discard(i)
isGood = list(sorted(list(isGood)))
print(len(isGood))
for x in isGood:
	print(x + 1)


def ip(x, y):
	return sum([a * b for (a, b) in zip(x, y)])

def dif(a, b):
	return [b - a for (a, b) in zip(a, b)]

def calcAng(a, b, c):
	return ip(dif(a, b), dif(a, c))

def testCase(pts):
	n = len(pts)
	if n > 35:
		return []
	ans = []
	for i in range(n):
		acs = 0
		for j in range(n):
			for k in range(n):
				if i == j or j == k or i == k:
					continue
				if calcAng(pts[i], pts[j], pts[k]) > 0:
					acs += 1
		if acs == 0:
			ans.append(i)
	return ans

def main():
	n = int(input())
	pts = []
	for i in range(n):
		pts.append([int(x) for x in input().split()])
	ans = testCase(pts)
	print(len(ans))
	for x in ans:
		print(x + 1)
main()


import sys
from math import acos, sqrt, pi
n = int(input())
p = []

def get_angle(a, b, c):
	v = [(b[i] - a[i], c[i] - a[i]) for i in range(5)]
	sp = sum([v[i][0] * v[i][1] for i in range(5)])
	sab = sqrt(sum([v[i][0] * v[i][0] for i in range(5)]))
	sac = sqrt(sum([v[i][1] * v[i][1] for i in range(5)]))
	if 2 * acos(sp / (sab * sac)) < pi:
		return True
	else:
		return False
for i in range(n):
	p.append(list(map(int, input().split())))
if n > 38:
	print('0')
	sys.exit()
s = set()
t = [False] * n
for k in range(n):
	if not t[k]:
		for i in range(n):
			if k != i:
				for j in range(n):
					if i != j and k != j:
						if get_angle(p[k], p[i], p[j]):
							s.add(k)
							t[k] = True
						if get_angle(p[i], p[k], p[j]):
							s.add(i)
							t[i] = True
						if get_angle(p[j], p[k], p[i]):
							s.add(j)
							t[j] = True
					if t[k]:
						break
				if t[k]:
					break
		t[k] = True
s = sorted(list(set([i for i in range(n)]) - s))
print(len(s))
[print(i + 1) for i in s]


import math
import random
import heapq, bisect
import sys
from collections import deque, defaultdict
from fractions import Fraction
import sys
import threading
from collections import defaultdict
mod = 10 ** 9 + 7
mod1 = 998244353
import os
import sys
from io import BytesIO, IOBase
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 TreeNode:

	def __init__(self, k, v):
		self.key = k
		self.value = v
		self.left = None
		self.right = None
		self.parent = None
		self.height = 1
		self.num_left = 1
		self.num_total = 1

class AvlTree:

	def __init__(self):
		self._tree = None

	def add(self, k, v):
		if not self._tree:
			self._tree = TreeNode(k, v)
			return
		node = self._add(k, v)
		if node:
			self._rebalance(node)

	def _add(self, k, v):
		node = self._tree
		while node:
			if k < node.key:
				if node.left:
					node = node.left
				else:
					node.left = TreeNode(k, v)
					node.left.parent = node
					return node.left
			elif node.key < k:
				if node.right:
					node = node.right
				else:
					node.right = TreeNode(k, v)
					node.right.parent = node
					return node.right
			else:
				node.value = v
				return

	@staticmethod
	def get_height(x):
		return x.height if x else 0

	@staticmethod
	def get_num_total(x):
		return x.num_total if x else 0

	def _rebalance(self, node):
		n = node
		while n:
			lh = self.get_height(n.left)
			rh = self.get_height(n.right)
			n.height = max(lh, rh) + 1
			balance_factor = lh - rh
			n.num_total = 1 + self.get_num_total(n.left) + self.get_num_total(n.right)
			n.num_left = 1 + self.get_num_total(n.left)
			if balance_factor > 1:
				if self.get_height(n.left.left) < self.get_height(n.left.right):
					self._rotate_left(n.left)
				self._rotate_right(n)
			elif balance_factor < -1:
				if self.get_height(n.right.right) < self.get_height(n.right.left):
					self._rotate_right(n.right)
				self._rotate_left(n)
			else:
				n = n.parent

	def _remove_one(self, node):
		replacement = node.left or node.right
		if node.parent:
			if AvlTree._is_left(node):
				node.parent.left = replacement
			else:
				node.parent.right = replacement
			replacement.parent = node.parent
			node.parent = None
		else:
			self._tree = replacement
			replacement.parent = None
		node.left = None
		node.right = None
		node.parent = None
		self._rebalance(replacement)

	def _remove_leaf(self, node):
		if node.parent:
			if AvlTree._is_left(node):
				node.parent.left = None
			else:
				node.parent.right = None
			self._rebalance(node.parent)
		else:
			self._tree = None
		node.parent = None
		node.left = None
		node.right = None

	def remove(self, k):
		node = self._get_node(k)
		if not node:
			return
		if AvlTree._is_leaf(node):
			self._remove_leaf(node)
			return
		if node.left and node.right:
			nxt = AvlTree._get_next(node)
			node.key = nxt.key
			node.value = nxt.value
			if self._is_leaf(nxt):
				self._remove_leaf(nxt)
			else:
				self._remove_one(nxt)
			self._rebalance(node)
		else:
			self._remove_one(node)

	def get(self, k):
		node = self._get_node(k)
		return node.value if node else -1

	def _get_node(self, k):
		if not self._tree:
			return None
		node = self._tree
		while node:
			if k < node.key:
				node = node.left
			elif node.key < k:
				node = node.right
			else:
				return node
		return None

	def get_at(self, pos):
		x = pos + 1
		node = self._tree
		while node:
			if x < node.num_left:
				node = node.left
			elif node.num_left < x:
				x -= node.num_left
				node = node.right
			else:
				return (node.key, node.value)
		raise IndexError('Out of ranges')

	@staticmethod
	def _is_left(node):
		return node.parent.left and node.parent.left == node

	@staticmethod
	def _is_leaf(node):
		return node.left is None and node.right is None

	def _rotate_right(self, node):
		if not node.parent:
			self._tree = node.left
			node.left.parent = None
		elif AvlTree._is_left(node):
			node.parent.left = node.left
			node.left.parent = node.parent
		else:
			node.parent.right = node.left
			node.left.parent = node.parent
		bk = node.left.right
		node.left.right = node
		node.parent = node.left
		node.left = bk
		if bk:
			bk.parent = node
		node.height = max(self.get_height(node.left), self.get_height(node.right)) + 1
		node.num_total = 1 + self.get_num_total(node.left) + self.get_num_total(node.right)
		node.num_left = 1 + self.get_num_total(node.left)

	def _rotate_left(self, node):
		if not node.parent:
			self._tree = node.right
			node.right.parent = None
		elif AvlTree._is_left(node):
			node.parent.left = node.right
			node.right.parent = node.parent
		else:
			node.parent.right = node.right
			node.right.parent = node.parent
		bk = node.right.left
		node.right.left = node
		node.parent = node.right
		node.right = bk
		if bk:
			bk.parent = node
		node.height = max(self.get_height(node.left), self.get_height(node.right)) + 1
		node.num_total = 1 + self.get_num_total(node.left) + self.get_num_total(node.right)
		node.num_left = 1 + self.get_num_total(node.left)

	@staticmethod
	def _get_next(node):
		if not node.right:
			return node.parent
		n = node.right
		while n.left:
			n = n.left
		return n

class SegmentTree1:

	def __init__(self, data, default=0, func=lambda a, b: max(a, b)):
		self._default = default
		self._func = func
		self._len = len(data)
		self._size = _size = 1 << (self._len - 1).bit_length()
		self.data = [default] * (2 * _size)
		self.data[_size:_size + self._len] = data
		for i in reversed(range(_size)):
			self.data[i] = func(self.data[i + i], self.data[i + i + 1])

	def __delitem__(self, idx):
		self[idx] = self._default

	def __getitem__(self, idx):
		return self.data[idx + self._size]

	def __setitem__(self, idx, value):
		idx += self._size
		self.data[idx] = value
		idx >>= 1
		while idx:
			self.data[idx] = self._func(self.data[2 * idx], self.data[2 * idx + 1])
			idx >>= 1

	def __len__(self):
		return self._len

	def query(self, start, stop):
		if start == stop:
			return self.__getitem__(start)
		stop += 1
		start += self._size
		stop += self._size
		res = self._default
		while start < stop:
			if start & 1:
				res = self._func(res, self.data[start])
				start += 1
			if stop & 1:
				stop -= 1
				res = self._func(res, self.data[stop])
			start >>= 1
			stop >>= 1
		return res

	def __repr__(self):
		return 'SegmentTree({0})'.format(self.data)

class SegmentTree:

	def __init__(self, data, default=0, func=lambda a, b: a + b):
		self._default = default
		self._func = func
		self._len = len(data)
		self._size = _size = 1 << (self._len - 1).bit_length()
		self.data = [default] * (2 * _size)
		self.data[_size:_size + self._len] = data
		for i in reversed(range(_size)):
			self.data[i] = func(self.data[i + i], self.data[i + i + 1])

	def __delitem__(self, idx):
		self[idx] = self._default

	def __getitem__(self, idx):
		return self.data[idx + self._size]

	def __setitem__(self, idx, value):
		idx += self._size
		self.data[idx] = value
		idx >>= 1
		while idx:
			self.data[idx] = self._func(self.data[2 * idx], self.data[2 * idx + 1])
			idx >>= 1

	def __len__(self):
		return self._len

	def query(self, start, stop):
		if start == stop:
			return self.__getitem__(start)
		stop += 1
		start += self._size
		stop += self._size
		res = self._default
		while start < stop:
			if start & 1:
				res = self._func(res, self.data[start])
				start += 1
			if stop & 1:
				stop -= 1
				res = self._func(res, self.data[stop])
			start >>= 1
			stop >>= 1
		return res

	def __repr__(self):
		return 'SegmentTree({0})'.format(self.data)

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 powm(a, n, m):
	if a == 1 or n == 0:
		return 1
	if n % 2 == 0:
		s = powm(a, n // 2, m)
		return s * s % m
	else:
		return a * powm(a, n - 1, m) % m

def sort_list(list1, list2):
	zipped_pairs = zip(list2, list1)
	z = [x for (_, x) in sorted(zipped_pairs)]
	return z

def product(l):
	por = 1
	for i in range(len(l)):
		por *= l[i]
	return por

def binarySearchCount(arr, n, key):
	left = 0
	right = n - 1
	count = 0
	while left <= right:
		mid = int((right + left) / 2)
		if arr[mid] < key:
			count = mid + 1
			left = mid + 1
		else:
			right = mid - 1
	return count

def countdig(n):
	c = 0
	while n > 0:
		n //= 10
		c += 1
	return c

def binary(x, length):
	y = bin(x)[2:]
	return y if len(y) >= length else '0' * (length - len(y)) + y

def countGreater(arr, n, k):
	l = 0
	r = n - 1
	leftGreater = n
	while l <= r:
		m = int(l + (r - l) / 2)
		if arr[m] >= k:
			leftGreater = m
			r = m - 1
		else:
			l = m + 1
	return n - leftGreater
n = int(input())
l = []
for i in range(n):
	l.append(list(map(int, input().split())))
if n >= 50:
	print(0)
	sys.exit(0)
if n <= 2:
	print(n)
	for i in range(n):
		print(i + 1)
	sys.exit(0)
er = set()
for i in range(n):
	f = 0
	for j in range(n):
		for k in range(n):
			if i == j or i == k or j == k:
				continue
			w = 0
			for d in range(5):
				w += (l[i][d] - l[j][d]) * (l[i][d] - l[k][d])
			if w > 0:
				f = 1
				break
		if f == 1:
			break
	if f == 0:
		er.add(i + 1)
print(len(er))
print(*er, sep='\n')


n = int(input())
points = []
for p in range(n):
	points.append(list(map(int, input().split())))

def dot(x, y):
	res = 0
	for (a, b) in zip(x, y):
		res += a * b
	return res

def minus(x, y):
	res = []
	for (a, b) in zip(x, y):
		res.append(a - b)
	return res
indices = set(range(n))
if n <= 50:
	for x in range(n):
		for y in range(n):
			if x != y:
				for z in range(n):
					if z != y and z != x:
						if dot(minus(points[y], points[x]), minus(points[z], points[x])) > 0:
							indices.discard(x)
	print(len(indices))
	for i in sorted(indices):
		print(i + 1)
else:
	print(0)


n = int(input())
p = []
ans = []
for _ in range(n):
	p.append(list(map(int, input().split())))
if n > 100:
	print(0)
	exit(0)
for i in range(0, n):
	good = True
	for j in range(0, n):
		for k in range(j + 1, n):
			if i == j or i == k:
				continue
			dp = 0
			for l in range(5):
				dp += (p[j][l] - p[i][l]) * (p[k][l] - p[i][l])
			if dp > 0:
				good = False
	if good:
		ans.append(i)
print(len(ans))
out = ''
for e in ans:
	out += str(e + 1) + ' '
print(out)


n = int(input())
if n > 11:
	for _ in range(n):
		input()
	print(0)
else:
	L = [tuple(map(int, input().split())) for _ in range(n)]
	good = [True] * n
	from itertools import combinations, chain
	dot = lambda i, j: sum((L[i][k] * L[j][k] for k in range(5)))
	memo = [[dot(i, j) for j in range(n)] for i in range(n)]
	for i in range(n):
		c2 = memo[i][i]
		for (j, k) in combinations(chain(range(i), range(i + 1, n)), r=2):
			if memo[j][k] > memo[j][i] + memo[k][i] - c2:
				good[i] = False
				break
	print(sum(good))
	print(' '.join(map(str, (i + 1 for (i, v) in enumerate(good) if v))))


n = int(input())
points = []
for _ in range(n):
	tmp = list(map(int, input().split()))
	points.append(tmp)
ans = []
for i in range(n):
	point_i = points[i]
	for j in range(n):
		if j == i:
			continue
		point_j = points[j]
		k_break = False
		vector_ij = [point_j[idx] - point_i[idx] for idx in range(5)]
		for k in range(j + 1, n):
			if k == i:
				continue
			point_k = points[k]
			vector_ik = [point_k[idx] - point_i[idx] for idx in range(5)]
			inner_product = 0
			num_i_mo = 0
			num_j_mo = 0
			for idx in range(5):
				inner_product += vector_ij[idx] * vector_ik[idx]
			if inner_product > 0:
				k_break = True
				break
		if k_break:
			break
	else:
		ans.append(point_i)
if len(points) <= 2:
	print(len(points))
	for i in range(len(points)):
		print(i + 1)
else:
	print(len(ans))
	for single in ans:
		print(points.index(single) + 1)


from sys import exit
n = int(input())
P = []
if n >= 38:
	print('0')
	exit()
for i in range(n):
	tmp = input().split()
	tmp = [int(k) for k in tmp]
	P.append(tuple(tmp))
isGood = [True for i in range(n)]
for i in range(n):
	for j in range(n):
		for k in range(j):
			dp = 0
			for d in range(5):
				dp += (P[j][d] - P[i][d]) * (P[k][d] - P[i][d])
			if dp > 0:
				isGood[i] = False
print(isGood.count(True))
for i in range(n):
	if isGood[i]:
		print(i + 1)


n = int(input())
dots = []
for i in range(n):
	dots.append(list(map(int, input().split())))
good_dots = []
for a_index in range(n):
	a_dot = dots[a_index]
	a_is_good = True
	for b_index in range(n):
		for c_index in range(n):
			if a_index != b_index and a_index != c_index and (b_index < c_index):
				b_dot = dots[b_index]
				c_dot = dots[c_index]
				ab_vec = [b_coord - a_coord for (a_coord, b_coord) in zip(a_dot, b_dot)]
				ac_vec = [c_coord - a_coord for (a_coord, c_coord) in zip(a_dot, c_dot)]
				prod = sum([a * b for (a, b) in zip(ab_vec, ac_vec)])
				if prod > 0:
					a_is_good = False
					break
		if not a_is_good:
			break
	if a_is_good:
		good_dots.append(a_index + 1)
print(len(good_dots))
for dot in good_dots:
	print(dot)


from math import acos

def check(i, j, k):
	num = 0
	for l in range(0, 5):
		num += (points[j][l] - points[i][l]) * (points[k][l] - points[i][l])
	return num > 0
n = int(input())
points = [[-1, -1, -1, -1, -1]]
ans = []
for _ in range(0, n):
	pts = [int(i) for i in input().split()]
	points.append(pts)
for i in range(1, n + 1):
	put = True
	for j in range(1, n + 1):
		if j != i and put:
			for k in range(1, n + 1):
				if j != k:
					if check(i, j, k):
						put = False
						break
			if not put:
				break
	if put:
		ans.append(i)
print(len(ans))
print(*ans)


import sys
import math
n = int(input())
if n > 20:
	print(0)
	sys.exit()
points = []
for i in range(n):
	p = list(map(int, input().split()))
	points.append(p)
good = []

class Vector:

	def __init__(self, first, last):
		self.elems = [last[i] - first[i] for i in range(5)]

	def __iter__(self):
		return self.elems.__iter__()

	def l(self):
		return sum((item ** 2 for item in self)) ** 0.5

	def ac(self, other):
		ch = sum((self.elems[i] * other.elems[i] for i in range(5)))
		z = self.l() * other.l()
		return ch / z

def check(index):
	for i in range(n):
		if i == index:
			continue
		for j in range(i + 1, n):
			if j == index:
				continue
			f = Vector(points[index], points[i])
			s = Vector(points[index], points[j])
			tmp = f.ac(s)
			if math.acos(tmp) < math.pi / 2:
				return False
	return True
for i in range(n):
	if check(i):
		good.append(str(i + 1))
print(len(good))
if len(good):
	print(' '.join(good))


def check(a, b, c):
	s = 0
	for i in range(5):
		s += (b[i] - a[i]) * (c[i] - a[i])
	return s <= 0
n = int(input())
a = []
for i in range(n):
	a.append(list(map(int, input().split())))
if n == 1 or n == 2:
	print(n)
	print(1)
	if n == 2:
		print(2)
	exit()
v = -1
i = 0
while i + 1 < n:
	if v == -1:
		if i + 2 < n:
			if check(a[i], a[i + 1], a[i + 2]):
				v = i
			elif check(a[i + 1], a[i], a[i + 2]):
				v = i + 1
			elif check(a[i + 2], a[i], a[i + 1]):
				v = i + 2
		else:
			break
	elif not check(a[v], a[i], a[i + 1]):
		if check(a[i], a[v], a[i + 1]):
			v = i
		elif check(a[i + 1], a[v], a[i]):
			v = i + 1
		else:
			v = -1
	i += 1
if v == -1:
	print(0)
	exit()
for i in range(n):
	if i == v:
		continue
	for j in range(i + 1, n):
		if j == v:
			continue
		if not check(a[v], a[i], a[j]):
			print(0)
			exit()
print(1)
print(v + 1)
exit()


def check(coor1, coor2, coor3):
	v1 = [coor2[i] - coor1[i] for i in range(5)]
	v2 = [coor3[i] - coor1[i] for i in range(5)]
	return scalar_product(v1, v2)

def scalar_product(coor1, coor2):
	(a1, a2, a3, a4, a5) = coor1
	(b1, b2, b3, b4, b5) = coor2
	return a1 * b1 + a2 * b2 + a3 * b3 + a4 * b4 + a5 * b5
n = int(input())
idx___coor = []
for idx in range(n):
	coor = [int(x) for x in input().split()]
	idx___coor.append(coor)
if n > 129:
	print(0)
else:
	good_idxes = []
	for (idx1, coor1) in enumerate(idx___coor):
		is_ok_flag = True
		for (idx2, coor2) in enumerate(idx___coor):
			for (idx3, coor3) in enumerate(idx___coor):
				if idx2 == idx3 or idx1 == idx3 or idx1 == idx2 or (not is_ok_flag):
					continue
				if check(coor1, coor2, coor3) > 0:
					is_ok_flag = False
		if is_ok_flag:
			good_idxes.append(idx1)
	good_idxes = sorted(good_idxes)
	good_idxes = [x + 1 for x in good_idxes]
	print(len(good_idxes))
	print(*good_idxes)


n = int(input())
points = [[-1, -1, -1, -1, -1]]
for _ in range(n):
	pts = list(map(int, input().split()))
	points.append(pts)

def check(i, j, k):
	res = 0
	for t in range(5):
		a = points[j][t] - points[i][t]
		b = points[k][t] - points[i][t]
		res += a * b
	return res > 0
res = []
for i in range(1, n + 1):
	valid = True
	for j in range(1, n + 1):
		if j != i and valid:
			for k in range(1, n + 1):
				if j != k:
					if check(i, j, k):
						valid = False
						break
			if not valid:
				break
	if valid:
		res.append(i)
print(len(res))
print(*res)


from math import acos, sqrt, pi

def norm(x):
	if x == 0:
		return 0
	else:
		return sqrt(scalar(x, x))

def scalar(x, y):
	return sum([x[i] * y[i] for i in range(5)])

def vector(p, q):
	return [q[i] - p[i] for i in range(5)]
number = 0
good_points = []
n = int(input())
liste = []
for _ in range(n):
	x = list(map(int, input().split(' ')))
	liste.append(x)
if n > 11:
	print(0)
else:
	for i in range(n):
		bool = True
		for j in range(n):
			if j != i:
				for k in range(n):
					if k != j and k != i:
						x = vector(liste[i], liste[j])
						y = vector(liste[i], liste[k])
						angle = acos(scalar(x, y) / norm(x) / norm(y))
						if angle < pi / 2:
							bool = False
		if bool:
			good_points.append(i + 1)
			number += 1
	if number > 0:
		answer = str(number) + ' '
		good_points.sort()
		for element in good_points:
			answer += '\n' + str(element)
		print(answer)
	else:
		print(0)


from functools import reduce
from itertools import combinations

def inner_prod(v1, v2):
	assert len(v1) == len(v2)
	return reduce(lambda acc, pair: acc + pair[0] * pair[1], zip(v1, v2), 0)

def vec_diff(v1, v2):
	assert len(v1) == len(v2)
	return list(map(lambda pair: pair[0] - pair[1], zip(v1, v2)))

def is_good_triple(orig, v1, v2):
	return inner_prod(vec_diff(v1, orig), vec_diff(v2, orig)) <= 0

def process(vec_indx, vec_list, bad_set):
	for pair in combinations(range(len(vec_list)), 2):
		if vec_indx in pair:
			continue
		elif not is_good_triple(vec_list[vec_indx], vec_list[pair[0]], vec_list[pair[1]]):
			bad_set.add(vec_indx)
			return
		else:
			bad_set.add(pair[0])
			bad_set.add(pair[1])

def main():
	n = int(input())
	if n < 3:
		print(n)
		list(map(print, range(1, n + 1)))
		return
	vec_list = [None] * n
	for indx in range(n):
		vec_list[indx] = list(map(int, input().split()))
	bad_set = set()
	for indx in range(n):
		if indx in bad_set:
			continue
		process(indx, vec_list, bad_set)
	print(n - len(bad_set))
	for indx in range(n):
		if indx not in bad_set:
			print(indx + 1)
main()