import sys, math, numpy
def triangleField(pointA, pointB, pointC):
field = math.fabs(
((pointB[0] - pointA[0]) * (pointC[1] - pointA[1]) - (pointB[1] - pointA[1]) * (pointC[0] - pointA[0]))) / 2
return field
data = sys.stdin
testCount = int(data.readline())
for test in range(testCount):
pointsListX = []
pointsCount = int(data.readline())
trianglesPoints = []
for line in range(1, pointsCount + 1):
point = list(map(int, data.readline().split())) # Te można zamienić na tuple.
point.append(line)
pointsListX.append(list(point))
trianglesCount = int(pointsCount / 3)
pointStatus = numpy.full(len(pointsListX), False, dtype=object)
for triangle in range(trianglesCount):
pointsListX.sort(key=lambda x: x[0])
xMax = pointsListX[0]
pointsListX.remove(xMax)
xMin = pointsListX[-1]
pointsListX.remove(xMin)
pointsListX.sort(key=lambda x: x[1])
yMax = pointsListX[0]
candidates = [xMax, xMin, yMax]
try:
yMin = pointsListX[-1]
candidates.append(yMin)
except:
pass
if len(candidates) == 4:
maxField = 0
for pointC in candidates:
if pointStatus[pointC[2] - 1] != True:
field = triangleField(xMax, xMin, pointC)
if field > maxField:
maxField = field
answer3 = pointC
else:
answer3 = candidates[2]
myNumbers = [xMax[2], xMin[2], answer3[2]]
myNumbers.sort()
print(myNumbers[0], myNumbers[1], myNumbers[2])
pointsListX.remove(answer3)
pointStatus[answer3[2] - 1] = True
print()
aW1wb3J0IHN5cywgbWF0aCwgbnVtcHkKCgpkZWYgdHJpYW5nbGVGaWVsZChwb2ludEEsIHBvaW50QiwgcG9pbnRDKToKICAgIGZpZWxkID0gbWF0aC5mYWJzKAogICAgICAgICgocG9pbnRCWzBdIC0gcG9pbnRBWzBdKSAqIChwb2ludENbMV0gLSBwb2ludEFbMV0pIC0gKHBvaW50QlsxXSAtIHBvaW50QVsxXSkgKiAocG9pbnRDWzBdIC0gcG9pbnRBWzBdKSkpIC8gMgogICAgcmV0dXJuIGZpZWxkCgoKZGF0YSA9IHN5cy5zdGRpbgp0ZXN0Q291bnQgPSBpbnQoZGF0YS5yZWFkbGluZSgpKQpmb3IgdGVzdCBpbiByYW5nZSh0ZXN0Q291bnQpOgogICAgcG9pbnRzTGlzdFggPSBbXQogICAgcG9pbnRzQ291bnQgPSBpbnQoZGF0YS5yZWFkbGluZSgpKQogICAgdHJpYW5nbGVzUG9pbnRzID0gW10KCiAgICBmb3IgbGluZSBpbiByYW5nZSgxLCBwb2ludHNDb3VudCArIDEpOgogICAgICAgIHBvaW50ID0gbGlzdChtYXAoaW50LCBkYXRhLnJlYWRsaW5lKCkuc3BsaXQoKSkpICAjIFRlIG1vxbxuYSB6YW1pZW5pxIcgbmEgdHVwbGUuCiAgICAgICAgcG9pbnQuYXBwZW5kKGxpbmUpCiAgICAgICAgcG9pbnRzTGlzdFguYXBwZW5kKGxpc3QocG9pbnQpKQogICAgdHJpYW5nbGVzQ291bnQgPSBpbnQocG9pbnRzQ291bnQgLyAzKQogICAgcG9pbnRTdGF0dXMgPSBudW1weS5mdWxsKGxlbihwb2ludHNMaXN0WCksIEZhbHNlLCBkdHlwZT1vYmplY3QpCgogICAgZm9yIHRyaWFuZ2xlIGluIHJhbmdlKHRyaWFuZ2xlc0NvdW50KToKCiAgICAgICAgcG9pbnRzTGlzdFguc29ydChrZXk9bGFtYmRhIHg6IHhbMF0pCiAgICAgICAgeE1heCA9IHBvaW50c0xpc3RYWzBdCiAgICAgICAgcG9pbnRzTGlzdFgucmVtb3ZlKHhNYXgpCiAgICAgICAgeE1pbiA9IHBvaW50c0xpc3RYWy0xXQogICAgICAgIHBvaW50c0xpc3RYLnJlbW92ZSh4TWluKQoKICAgICAgICBwb2ludHNMaXN0WC5zb3J0KGtleT1sYW1iZGEgeDogeFsxXSkKICAgICAgICB5TWF4ID0gcG9pbnRzTGlzdFhbMF0KCiAgICAgICAgY2FuZGlkYXRlcyA9IFt4TWF4LCB4TWluLCB5TWF4XQogICAgICAgIHRyeToKICAgICAgICAgICAgeU1pbiA9IHBvaW50c0xpc3RYWy0xXQogICAgICAgICAgICBjYW5kaWRhdGVzLmFwcGVuZCh5TWluKQogICAgICAgIGV4Y2VwdDoKICAgICAgICAgICAgcGFzcwoKICAgICAgICBpZiBsZW4oY2FuZGlkYXRlcykgPT0gNDoKICAgICAgICAgICAgbWF4RmllbGQgPSAwCiAgICAgICAgICAgIGZvciBwb2ludEMgaW4gY2FuZGlkYXRlczoKICAgICAgICAgICAgICAgIGlmIHBvaW50U3RhdHVzW3BvaW50Q1syXSAtIDFdICE9IFRydWU6CiAgICAgICAgICAgICAgICAgICAgZmllbGQgPSB0cmlhbmdsZUZpZWxkKHhNYXgsIHhNaW4sIHBvaW50QykKICAgICAgICAgICAgICAgICAgICBpZiBmaWVsZCA+IG1heEZpZWxkOgogICAgICAgICAgICAgICAgICAgICAgICBtYXhGaWVsZCA9IGZpZWxkCiAgICAgICAgICAgICAgICAgICAgICAgIGFuc3dlcjMgPSBwb2ludEMKICAgICAgICBlbHNlOgogICAgICAgICAgICBhbnN3ZXIzID0gY2FuZGlkYXRlc1syXQoKICAgICAgICBteU51bWJlcnMgPSBbeE1heFsyXSwgeE1pblsyXSwgYW5zd2VyM1syXV0KICAgICAgICBteU51bWJlcnMuc29ydCgpCiAgICAgICAgcHJpbnQobXlOdW1iZXJzWzBdLCBteU51bWJlcnNbMV0sIG15TnVtYmVyc1syXSkKICAgICAgICBwb2ludHNMaXN0WC5yZW1vdmUoYW5zd2VyMykKICAgICAgICBwb2ludFN0YXR1c1thbnN3ZXIzWzJdIC0gMV0gPSBUcnVlCiAgICBwcmludCgp
MwozCjAgMAoxIDIKMiAxCjYKLTIgMAoyIDAKMSAxCi0xIDEKMCAzCjAgNAoxNSAKMCA0MAo3IDEwCi0xIDgKMSAxMwoxNCAyCi00IDQKLTMgMTMKLTE0IDIKMCAzNQoxOCAxCi0yMCAwCi01IDE4CjAgMzAKLTE4IDEKMjAgMA==
3
3
0 0
1 2
2 1
6
-2 0
2 0
1 1
-1 1
0 3
0 4
15
0 40
7 10
-1 8
1 13
14 2
-4 4
-3 13
-14 2
0 35
18 1
-20 0
-5 18
0 30
-18 1
20 0