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: Accepted)

fn read_stdin() -> String {
    use std::io::Read;
    let mut input = String::new();
    std::io::stdin().read_to_string(&mut input).unwrap();
    input
}

fn scan<'a, I: Iterator<Item = &'a str>, T: std::str::FromStr>(tokens: &mut I) -> T {
    tokens.next().unwrap().parse().ok().unwrap()
}

fn vec<T, F: FnMut(usize) -> T>(n: usize, mut f: F) -> Vec<T> {
    (0..n).map(|i| f(i)).collect()
}

fn main() {
    use std::collections::{HashMap, HashSet};
    let input = read_stdin();
    let tokens = &mut input.split_whitespace();
    let n: usize = scan(tokens);
    let xy: Vec<(usize, usize)> = vec(n, |_| (scan(tokens), scan(tokens)));
    let xs: HashSet<usize> = xy.iter().map(|&(x, _)| x).collect();
    let ys: HashSet<usize> = xy.iter().map(|&(_, y)| y).collect();
    let x2i: HashMap<usize, usize> = xs.into_iter().enumerate().map(|(i, x)| (x, i)).collect();
    let y2j: HashMap<usize, usize> = ys.into_iter().enumerate().map(|(j, y)| (y, j)).collect();
    let nx: usize = x2i.len();
    let ny: usize = y2j.len();
    let mut i2j = vec![Vec::new(); nx];
    let mut j2i = vec![Vec::new(); ny];
    for &(x, y) in &xy {
        let i: usize = x2i[&x];
        let j: usize = y2j[&y];
        i2j[i].push(j);
        j2i[j].push(i);
    }
    let mut ci = vec![0; nx];
    let mut cj = vec![0; ny];
    let mut k = 0;
    for i in 0..nx {
        if ci[i] == 0 {
            k += 1;
            dfs_i(i, k, &mut ci, &mut cj, &i2j, &j2i);
        }
    }
    let mut kc: Vec<usize> = vec![0; k + 1];
    for &c in &ci {
        kc[c] += 1;
    }
    let mut lc: Vec<usize> = vec![0; k + 1];
    for &c in &cj {
        lc[c] += 1;
    }
    let mut ans = 0;
    for c in 1..k + 1 {
        ans += kc[c] * lc[c];
    }
    ans -= n;
    println!("{}", ans);
}

fn dfs_i(
    i: usize,
    c: usize,
    ci: &mut Vec<usize>,
    cj: &mut Vec<usize>,
    i2j: &Vec<Vec<usize>>,
    j2i: &Vec<Vec<usize>>,
) {
    if ci[i] != 0 {
        return;
    }
    ci[i] = c;
    for &j in &i2j[i] {
        dfs_j(j, c, ci, cj, i2j, j2i);
    }
}

fn dfs_j(
    j: usize,
    c: usize,
    ci: &mut Vec<usize>,
    cj: &mut Vec<usize>,
    i2j: &Vec<Vec<usize>>,
    j2i: &Vec<Vec<usize>>,
) {
    if cj[j] != 0 {
        return;
    }
    cj[j] = c;
    for &i in &j2i[j] {
        dfs_i(i, c, ci, cj, i2j, j2i);
    }
}