n = int(input())
a = []
visited = [False] * n
adj = [[] for i in range(n)]
for i in range(n):
x, y = map(int, input().split())
a.append([x, y])
for i in range(n):
for j in range(i + 1, n):
if a[i][0] == a[j][0] or a[i][1] == a[j][1]:
adj[i].append(j)
adj[j].append(i)
def dfs(v):
visited[v] = True
for u in adj[v]:
if not visited[u]:
dfs(u)
ans = 0
for i in range(n):
if not visited[i]:
ans += 1
dfs(i)
print(ans - 1)
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef pair<ll, ll> pi;
#define lll __int128_t
#define mp make_pair
#define pb push_back
#define F first
#define S second
#define SetBit(x, k) (x |= (1LL << k))
#define ClearBit(x, k) (x &= ~(1LL << k))
#define CheckBit(x, k) (x & (1LL << k))
#define debug(x) { cerr << #x << " = " << x << endl; }
const ll inf = 1LL<<60; //1.15e18
const ll md = 1000000007;
ll dx[]={0,1,0,-1};
ll dy[]={1,0,-1,0};
ll dxx[]={0,1,0,-1,1,1,-1,-1};
ll dyy[]={1,0,-1,0,1,-1,1,-1};
ll vis[1005];
void dfs(ll i, vector<vector<ll>>&g)
{
vis[i]=1;
for(auto x: g[i])
{
if(!vis[x])dfs(x,g);
}
}
void solve()
{
ll n; cin >> n;
vector<ll>x[1005],y[1005];
vector<vector<ll>>g(n+1);
for(ll i=1;i<=n;i++)
{
ll a, b; cin >> a >> b;
x[a].push_back(i);
y[b].push_back(i);
}
for(ll i=1;i<=1000;i++){
for(auto j: x[i])
{
for(auto k: x[i])
{
if(k==j)continue;
g[j].push_back(k);
g[k].push_back(j);
}
}
}
for(ll i=1;i<=1000;i++){
for(auto j: y[i])
{
for(auto k: y[i])
{
if(k==j)continue;
g[j].push_back(k);
g[k].push_back(j);
}
}
}
ll ans=-1;
for(ll i=1;i<=n;i++)
{
if(!vis[i])
{
ans++;
dfs(i,g);
}
}
cout<<ans;
}
int main()
{
//freopen("input.txt", "r", stdin);
//freopen("output.txt", "w", stdout);
ios_base::sync_with_stdio(false);
cin.tie(NULL);cout.tie(NULL);
ll T; T=1;
//cin >> T;
while(T--)
{
solve();
}
}
1486B - Eastern Exhibition | 1363A - Odd Selection |
131B - Opposites Attract | 490C - Hacking Cypher |
158B - Taxi | 41C - Email address |
1373D - Maximum Sum on Even Positions | 1574C - Slay the Dragon |
621A - Wet Shark and Odd and Even | 1395A - Boboniu Likes to Color Balls |
1637C - Andrew and Stones | 1334B - Middle Class |
260C - Balls and Boxes | 1554A - Cherry |
11B - Jumping Jack | 716A - Crazy Computer |
644A - Parliament of Berland | 1657C - Bracket Sequence Deletion |
1657B - XY Sequence | 1009A - Game Shopping |
1657A - Integer Moves | 230B - T-primes |
630A - Again Twenty Five | 1234D - Distinct Characters Queries |
1183A - Nearest Interesting Number | 1009E - Intercity Travelling |
1637B - MEX and Array | 224A - Parallelepiped |
964A - Splits | 1615A - Closing The Gap |