Problem:
Score : 600 points

Problem Statement

There are N dots in a two-dimensional plane. The coordinates of the i-th dot are (x_i, y_i).

We will repeat the following operation as long as possible:

Choose four integers a, b, c, d (a \neq c, b \neq d) such that there are dots at exactly three of the positions (a, b), (a, d), (c, b) and (c, d), and add a dot at the remaining position.

We can prove that we can only do this operation a finite number of times. Find the maximum number of times we can do the operation.

Constraints

1 \leq N \leq 10^5

1 \leq x_i, y_i \leq 10^5

If i \neq j, x_i \neq x_j or y_i \neq y_j.

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N
x_1 y_1
:
x_N y_N

Output

Print the maximum number of times we can do the operation.

Sample Input 1

3
1 1
5 1
5 5

Sample Output 1

1

By choosing a = 1, b = 1, c = 5, d = 5, we can add a dot at (1, 5). We cannot do the operation any more, so the maximum number of operations is 1.

Sample Input 2

2
10 10
20 20

Sample Output 2

0

There are only two dots, so we cannot do the operation at all.

Sample Input 3

9
1 1
2 1
3 1
4 1
5 1
1 2
1 3
1 4
1 5

Sample Output 3

16

We can do the operation for all choices of the form a = 1, b = 1, c = i, d = j (2 \leq i,j \leq 5), and no more. Thus, the maximum number of operations is 16.

Solution in Rust (1.15.1) (judge verdict: Wrong Answer)

use std::collections::HashSet;
use std::io::prelude::*;

#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
struct Point {
    y: u32,
    x: u32,
}

fn main() {
    let mut input_str = String::new();
    std::io::stdin().read_to_string(&mut input_str).unwrap();

    let input_parts = input_str.split_whitespace().collect::<Vec<_>>();
    let mut input_parts_it = input_parts.iter().cloned();

    let n: usize = input_parts_it.next().unwrap().parse().unwrap();

    let mut points: Vec<_> = (0..n)
        .map(|_| Point {
            x: input_parts_it.next().unwrap().parse().unwrap(),
            y: input_parts_it.next().unwrap().parse().unwrap(),
        })
        .collect();

    let mut x_set = vec![Vec::new(); 100001];
    for p in points.iter() {
        x_set[p.x as usize].push(*p);
    }

    let mut point_set: HashSet<_> = points.iter().cloned().collect();
    points.sort();

    let mut count = 0;

    for (i1, pt1) in points.iter().enumerate() {
        let x1 = pt1.x;
        let y1 = pt1.y;

        for pt2 in x_set[x1 as usize].iter() {
            if pt2.y == y1 {
                continue;
            }

            for pt3 in points[i1 + 1..].iter() {
                if pt3.y != y1 {
                    break;
                }

                let new_pt = Point { x: pt3.x, y: pt2.y };
                if point_set.insert(new_pt) {
                    count += 1;
                }
            }

            for pt3 in points[0..i1].iter().rev() {
                if pt3.y != y1 {
                    break;
                }

                let new_pt = Point { x: pt3.x, y: pt2.y };
                if point_set.insert(new_pt) {
                    count += 1;
                }
            }
        }
    }

    println!("{}", count);
}