# util functions
class UnionFind
  def initialize(n) # n: number of elements in the forest
    @grps = n
    @par  = []
    @rank = []
    @vs   = []  
    n.times do |i|
      @par[i] = i
      @rank[i] = 0
      @vs[i] = 1
    end
  end
  attr_accessor :par, :rank, :vs, :grps

  def find(x)
    raise "x = #{x} is out of range 0..#{@par.size - 1}" unless @par[x]
    if @par[x] == x
      return x
    else
      return find( @par[x] )
    end
  end

  def unite( x, y )
    xrt = find(x)
    yrt = find(y)
    return if xrt == yrt

    @grps -= 1
    
    if @rank[xrt] > @rank[yrt]
      @par[yrt] = xrt
      @vs[xrt] += @vs[yrt]
    else
      @par[xrt] = yrt
      @vs[yrt] += @vs[xrt]
      @rank[yrt] += 1 if @rank[xrt] == @rank[yrt]
    end
  end

  def same( x, y ) # returns true/false
    return find( x ) == find( y )
  end

end # UnionFind


# debug
$debugFlag = ( ARGV[0] != nil )
p "==== DEBUG MODE ====" if $debugFlag

def pd(str)
  p str if $debugFlag
end

# input
inputs = []
lc = 0
while l = $stdin.gets do
  if false
    inputs << l.chomp.split(" ").map(&:to_s)
  else
    inputs << l.chomp.split(" ").map(&:to_i)
  end
  lc += 1
end

# input check
if $debugFlag
  p "--- INPUT (begin) ---"
  inputs.each do |l_i|
    p l_i
  end
  p "--- INPUT (end) ---"
  print "\n"
end

nn = inputs[0][0]
mm = inputs[0][1]

# body
if $debugFlag
  p nn
  p mm
end

uf = UnionFind.new(nn)

for i in 0..mm-1
  uf.unite(inputs[i+1][0]-1, inputs[i+1][1]-1)
end

# pd uf.par
# pd uf.rank
# pd uf.vs
puts uf.grps
