← Home
package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
)

type Point struct {
	origX, origY int
	x, y         int
	id           int
}

func abs(x int) int {
	if x < 0 {
		return -x
	}
	return x
}

func closest(pts []Point) (int64, Point, Point) {
	if len(pts) <= 3 {
		var bestD int64 = -1
		var p1, p2 Point
		for i := 0; i < len(pts); i++ {
			for j := i + 1; j < len(pts); j++ {
				dx := int64(pts[i].x - pts[j].x)
				dy := int64(pts[i].y - pts[j].y)
				d := dx*dx + dy*dy
				if bestD == -1 || d < bestD {
					bestD = d
					p1 = pts[i]
					p2 = pts[j]
				}
			}
		}
		return bestD, p1, p2
	}

	mid := len(pts) / 2
	midX := pts[mid].x

	d1, p1a, p1b := closest(pts[:mid])
	d2, p2a, p2b := closest(pts[mid:])

	d := d1
	pa, pb := p1a, p1b
	if d2 < d {
		d = d2
		pa, pb = p2a, p2b
	}

	var strip []Point
	for _, p := range pts {
		dx := int64(p.x - midX)
		if dx*dx < d {
			strip = append(strip, p)
		}
	}

	sort.Slice(strip, func(i, j int) bool {
		return strip[i].y < strip[j].y
	})

	for i := 0; i < len(strip); i++ {
		for j := i + 1; j < len(strip); j++ {
			dy := int64(strip[j].y - strip[i].y)
			if dy*dy >= d {
				break
			}
			dx := int64(strip[i].x - strip[j].x)
			dist := dx*dx + dy*dy
			if dist < d {
				d = dist
				pa = strip[i]
				pb = strip[j]
			}
		}
	}

	return d, pa, pb
}

func getK(origX, origY, targetX, targetY int) int {
	sx := 1
	if origX*1 != targetX && origX*-1 == targetX {
		sx = -1
	}
	sy := 1
	if origY*1 != targetY && origY*-1 == targetY {
		sy = -1
	}

	if sx == 1 && sy == 1 {
		return 1
	}
	if sx == -1 && sy == 1 {
		return 2
	}
	if sx == 1 && sy == -1 {
		return 3
	}
	return 4
}

func readInt(scanner *bufio.Scanner) int {
	scanner.Scan()
	s := scanner.Text()
	sign := 1
	if s[0] == '-' {
		sign = -1
		s = s[1:]
	}
	res := 0
	for i := 0; i < len(s); i++ {
		res = res*10 + int(s[i]-'0')
	}
	return res * sign
}

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	scanner.Split(bufio.ScanWords)

	if !scanner.Scan() {
		return
	}
	
	s := scanner.Text()
	n := 0
	for i := 0; i < len(s); i++ {
		n = n*10 + int(s[i]-'0')
	}

	pts := make([]Point, n)
	for i := 0; i < n; i++ {
		x := readInt(scanner)
		y := readInt(scanner)
		pts[i] = Point{
			origX: x,
			origY: y,
			x:     abs(x),
			y:     abs(y),
			id:    i + 1,
		}
	}

	sort.Slice(pts, func(i, j int) bool {
		if pts[i].x == pts[j].x {
			return pts[i].y < pts[j].y
		}
		return pts[i].x < pts[j].x
	})

	_, pa, pb := closest(pts)

	k1 := getK(pa.origX, pa.origY, abs(pa.origX), abs(pa.origY))
	k2 := getK(pb.origX, pb.origY, -abs(pb.origX), -abs(pb.origY))

	fmt.Printf("%d %d %d %d\n", pa.id, k1, pb.id, k2)
}