class UnionFind
  attr :parent, :rank
  def initialize
    @parent = Hash.new
    @rank = Hash.new
  end
  def make(x)
    @parent[x] = x
    @rank[x] = 0
  end
  def union(a, b)
    x, y = find(a), find(b)
    x, y = y, x if @rank[x] < @rank[y]
    @parent[y] = x
    @rank[x] += 1 if @rank[x] == @rank[y]
  end
  def find(x)
    @parent[x] == x ? x : @parent[x] = find(@parent[x])
  end
  def size
    @parent.keys.map{|k| find(k)}.sort.uniq.size
  end
end

# P=gets.to_i.times.map{|i| [i] + gets.split.map(&:to_i)}
P = gets.to_i.times.map{|i| gets.split.map &:to_i}
N = 10**6

uf = UnionFind.new
P.size.times do |i|
  n, x, y = N+i, P[i][0], -P[i][1]
  uf.make(n)
  uf.make(x)
  uf.make(y)
end
P.size.times do |i|
  n, x, y = N+i, P[i][0], -P[i][1]
  uf.union(n, x)
  uf.union(n, y)
  uf.union(x, y)
end

X = Hash.new{|h, k| h[k] = Array.new}
Y = Hash.new{|h, k| h[k] = Array.new}
G = Array.new
P.size.times do |i|
  g, x, y = uf.find(N+i), P[i][0], -P[i][1]
  G << g
  X[g] << x
  Y[g] << y
end
p G.uniq.map{|g| (X[g].uniq.size-1) * (Y[g].uniq.size-1)}.inject(:+)
