← Home
Looking at this problem, I need to find pairs of persons (A, B) who will make eye contact at least once during a full 360° rotation.

**Key Insight:** Both persons rotate clockwise at the same angular speed. Person A looks in direction θ_A(t) = θ_A(0) - ωt, and person B looks in direction θ_B(t) = θ_B(0) - ωt.

For A and B to make eye contact:
- A must look toward B: the direction from A to B equals θ_A(t)
- B must look toward A: the direction from B to A equals θ_B(t)

The direction from A to B and from B to A differ by exactly π.

So we need: θ_A(t) = angle(B - A) and θ_B(t) = angle(A - B) = angle(B - A) + π

Since θ_A(t) = θ_A(0) - ωt and θ_B(t) = θ_B(0) - ωt:

From first equation: ωt = θ_A(0) - angle(B - A)
From second equation: ωt = θ_B(0) - angle(B - A) - π

So: θ_A(0) - angle(B - A) = θ_B(0) - angle(B - A) - π (mod 2π)

This simplifies to: θ_A(0) - θ_B(0) ≡ -π (mod 2π), or equivalently θ_A(0) - θ_B(0) ≡ π (mod 2π).

Wait, let me recheck. θ_A(0) = θ_B(0) - π (mod 2π), meaning θ_A(0) + π ≡ θ_B(0) (mod 2π).

So the initial direction of A's gaze and the initial direction of B's gaze must differ by exactly π. In other words, they must initially look in **opposite** directions.

The initial direction for person i is the direction from (x_i, y_i) to (u_i, v_i), which is atan2(v_i - y_i, u_i - x_i).

Two persons make eye contact iff their initial looking directions differ by exactly π. The opposite of direction (dx, dy) is (-dx, -dy). We can normalize directions by reducing (dx, dy) to their coprime form with a canonical sign.

For each person, compute (dx, dy) = (u_i - x_i, v_i - y_i), reduce to coprime form with canonical sign. Two persons pair up if one has direction (a, b) and the other has (-a, -b) in canonical form. We can group by canonical direction and count pairs between opposite groups.

```go
package main

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

func gcd(a, b int64) int64 {
	for b != 0 {
		a, b = b, a%b
	}
	return a
}

func abs64(x int64) int64 {
	if x < 0 {
		return -x
	}
	return x
}

func normalize(dx, dy int64) (int64, int64) {
	g := gcd(abs64(dx), abs64(dy))
	dx /= g
	dy /= g
	// canonical: first nonzero component positive
	if dx < 0 || (dx == 0 && dy < 0) {
		dx = -dx
		dy = -dy
	}
	return dx, dy
}

type pair struct {
	x, y int64
}

func main() {
	reader := bufio.NewReader(os.Stdin)
	writer := bufio.NewWriter(os.Stdout)
	defer writer.Flush()

	var t int
	fmt.Fscan(reader, &t)
	for ; t > 0; t-- {
		var n int
		fmt.Fscan(reader, &n)

		// For each person, compute canonical direction and whether it was flipped
		counts := make(map[pair]int64)
		type entry struct {
			norm    pair
			flipped bool
		}
		for i := 0; i < n; i++ {
			var x, y, u, v int64
			fmt.Fscan(reader, &x, &y, &u, &v)
			dx := u - x
			dy := v - y
			ndx, ndy := normalize(dx, dy)
			// Check if we flipped sign
			// Original reduced: dx/g, dy/g. If normalize flipped, then direction is opposite
			g := gcd(abs64(dx), abs64(dy))
			rdx, rdy := dx/g, dy/g
			flipped := (rdx != ndx || rdy != ndy)
			_ = flipped
			// Store as (canonical_dir, sign): sign=0 means original, sign=1 means flipped
			if rdx == ndx && rdy == ndy {
				counts[pair{ndx*2, ndy*2}]++
			} else {
				counts[pair{ndx*2 + 1, ndy*2 + 1}]++
			}
		}
		// Pairs: same canonical direction, different sign
		// Regroup
		canon := make(map[pair][2]int64)
		for k, v := range counts {
			cx, cy := k.x/2, k.y/2
			sign := k.x % 2
			key := pair{cx, cy}
			arr := canon[key]
			arr[sign] += v
			canon[key] = arr
		}
		var ans int64
		for _, arr := range canon {
			ans += arr[0] * arr[1]
		}
		fmt.Fprintln(writer, ans)
	}
}
```