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 C (GCC 5.4.1) (judge verdict: Time Limit Exceeded)

#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>
#include<stdbool.h>
typedef long long ll;
typedef long double ld;
#define rep(i,l,r)for(ll i=(l);i<(r);i++)
#define repp(i,l,r,k)for(ll i=(l);i<(r);i+=(k))
#define rrep(i,l,r)for(ll i=(l);i>=(r);i--)
#define INF (1LL<<60)
#define MOD1 1000000007
#define MOD2 998244353
#define MAX_N (1 << 17)
#define YES printf("Yes\n")
#define NO printf("No\n")
#define PN printf("\n")

void swap(ll *a, ll *b){ll c;c=*b;*b=*a;*a=c;}
ll max2(ll a,ll b){return a>=b?a:b;}
ll min2(ll a,ll b){return a>=b?b:a;}
ll min3(ll a, ll b, ll c){return (a<=b && a<=c) ? a : b<=c ? b : c;}
ll max3(ll a, ll b, ll c){return (a>=b && a>=c) ? a : b>=c ? b : c;}
ll minn(ll n, ll a[n]){ll b=INF;rep(i,0,n) b=min2(b,a[i]);return b;}
ll maxn(ll n, ll a[n]){ll b=-INF;rep(i,0,n) b=max2(b,a[i]);return b;}
ll ABS(ll a){return a>=0?a:(-a);}
ll POW(ll a, ll b){ll c=1;rep(i,0,b) c*=a;return c;}
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
ll mod(ll n){return n%=MOD1;}
int upll(const void*a, const void*b){return*(ll*)a<*(ll*)b?-1:*(ll*)a>*(ll*)b?1:0;}
int downll(const void*a, const void*b){return*(ll*)a<*(ll*)b?1:*(ll*)a>*(ll*)b?-1:0;}
void sortup(ll*a,int n){qsort(a,n,sizeof(ll),upll);}
void sortdown(ll*a,int n){qsort(a,n,sizeof(ll),downll);}


/*ai<=xとなる最大のi*/
ll lower_bound4(ll n, ll a[n][2], ll l, ll r, ll x){
    while(r-l>1){
        ll p=(l+r)/2;
        if(a[p][0]<=x) l=p;
        else r=p;
    }
    return a[r][0]<=x?r:a[l][0]<=x?l:-1;
}

/*ai<xとなる最大のi*/
ll lower_bound(ll n, ll a[n], ll l, ll r, ll x){
    while(r-l>1){
        ll p=(l+r)/2;
        if(a[p]<x) l=p;
        else r=p;
    }
    return a[r]<x?r:a[l]<x?l:-1;
}

/*ai>xとなる最小のi*/
ll upper_bound(ll n, ll a[n], ll l, ll r, ll x){
    while(r-l>1){
        ll p=(l+r)/2;
        if(a[p]<=x) l=p;
        else r=p;
    }
    return a[l]>x?l:a[r]>x?r:n;
}

ll trans=1000000;
ll xkind,ykind,pkind;
ll xused[100000]={},yused[100000]={},reached[100000][2]={};

void dfs(ll n, ll xbase[n], ll ybase[n], ll x, ll y){
    if(xused[x-1]==0) xkind++;
    if(yused[y-1]==0) ykind++;
    ll zzz=lower_bound4(n,reached,0,n-1,x*trans+y);
    reached[zzz][1]=1;
    pkind++;
    // xkind++; ykind++;
    xused[x-1]=1; yused[y-1]=1;

    ll l=upper_bound(n,xbase,0,n-1,x*trans-1) ,r=lower_bound(n,xbase,0,n-1,(x+1)*trans) ,
    d=upper_bound(n,ybase,0,n-1,y*trans-1) ,u=lower_bound(n,ybase,0,n-1,(y+1)*trans);

    // printf("x;%lld y;%lld %lld %lld\n",x,y,l,r);
    ll piv=lower_bound4(n,reached,0,n-1,x*trans+ xbase[l]%trans );
    rep(i,l,r+1){
        ll Y=xbase[i]%trans;
        if(Y==y) continue;
        if( reached[ piv+ (i-l) ][1] == 0 ){
            dfs(n,xbase,ybase,x,Y);
        }
    }
    rep(i,d,u+1){
        ll X=ybase[i]%trans;
        if(X==x) continue;
        if( reached[ lower_bound4(n,reached,0,n-1,X*trans+y) ][1] == 0 ){
            dfs(n,xbase,ybase,X,y);
        }
    }
}

int main(void){
    ll n,ans=0;
    scanf("%lld",&n);
    ll xbase[n],ybase[n];
    rep(i,0,n){
        ll x,y;
        scanf("%lld%lld",&x,&y);
        xbase[i]=x*trans+y;
        ybase[i]=y*trans+x;
    }
    sortup(xbase,n);
    sortup(ybase,n);
    rep(i,0,n) reached[i][0]=xbase[i];

    rep(i,0,n){
        // printf("%lld\n",ybase[i]);
        if( xused[ybase[i]%trans-1] ) continue;
        xkind=0; ykind=0; pkind=0;
        dfs(n,xbase,ybase, ybase[i]%trans , ybase[i]/trans );
        if(xkind<2 || ykind<2) continue;
        else ans+= xkind * ykind - pkind;
        // printf("%lld %lld %lld\n",xkind,ykind,pkind);
        // printf("%lld\n",ans);
    }
    
    printf("%lld\n",ans);
    return 0;
}