struct L{
int x,y;
}a[103];
int f[103],b[103];
int find(int x){
return f[x]==x?x:f[x]=find(f[x]);
}
void merge(int x,int y){
f[find(x)]=find(y);
}
int main(){
int n;
read(n);
for(int i=1;i<=n;++i){
read(a[i].x);read(a[i].y);
//a[i].k =i;
f[i]=i;
}
for(int i=1;i<n;++i){
for(int j=i+1;j<=n;++j){
if(a[i].x ==a[j].x ||a[i].y ==a[j].y ){
merge(i,j);
}
}
}
int cnt=0;
for(int i=1;i<=n;++i){
if(find(i)==i) cnt++; //每个集合都有一个统领,统领的父亲是自己,找到每个集合的统领并计算个数,即集合个数
}
cout << cnt-1 << endl;
return 0;
}