COUNTER_CLOCKWISE = 1
CLOCKWISE = -1
ONLINE_BACK = 2
ONLINE_FRONT = -2
ON_SEGMENT = 0
#occw = {"COUNTER_CLOCKWISE":1, "CLOCKWISE":-1, "ONLINE_BACK":2, "ONLINE_FRONT":-2, "ON_SEGMENT":0}
def ccw(p0, p1, p2):
a = np.array(p1)-np.array(p0)
b = np.array(p2)-np.array(p0)
#print("==p0,p1,p2,a,b==")
#print(p0,p1,p2,a,b)
#print("==corss,dot==")
#print(np.cross(a,b),np.dot(a,b))
if (np.cross(a,b) > np.finfo(np.float).eps):
return COUNTER_CLOCKWISE
if (np.cross(a,b) < - np.finfo(np.float).eps):
return CLOCKWISE
if (np.dot(a,b) < - np.finfo(np.float).eps):
return ONLINE_BACK
if (np.linalg.norm(a)**2 < np.linalg.norm(b)**2):
return ONLINE_FRONT
return ON_SEGMENT
def andrewScan(s):
u = []
l = []
if (len(s) < 3):
return s
#print(s)
#s = np.sort([s])
s = sorted(s)
#print(s,len(s))
u.append(s[0])
u.append(s[1])
l.append(s[len(s)-1])
l.append(s[len(s)-2])
for i in range(2,len(s)):
for n in range(len(u),2-1,-1):
if (ccw(u[n-2], u[n-1], s[i]) in [ONLINE_FRONT,CLOCKWISE]):
break
u.pop()
u.append(s[i])
#print(u)
for i in range(len(s)-3,-1,-1):
for n in range(len(l),2-1,-1):
ret = ccw(l[n-2],l[n-1],s[i])
if (ret in [CLOCKWISE,ONLINE_FRONT]):
break
l.pop()
l.append(s[i])
l = l[::-1]
for i in range(len(u)-2,0,-1):
l.append(u[i])
return l
s = []
n = input()
for i in range(n):
a = []
a.append(map(int, raw_input().split()))
for aa in a:
x = aa[0]
y = aa[1]
s.append([x,y])
ret = andrewScan(s)
print(str(len(ret)))
out = ""
for x in ret:
if (out):
out = out + "\n"
_out = ""
for xx in x:
if (_out):
_out = _out + " "
_out = _out + str(xx)
out = out + _out
print(out)