let readIntArray _ =
    stdin.ReadLine().Split(" ") |> Array.map int

()
|> readIntArray
|> fun [| n; m |] ->
    seq { 1 .. m }
    |> Seq.map readIntArray
    |> Seq.fold (fun (map: Map<int, int>) [| f; t |] ->
        match (map.TryFind f, map.TryFind t) with
        | (None, None) ->
            let v = min f t
            map.Add(t, v).Add(f, v)
        | (None, Some a) -> map.Add(f, a)
        | (Some a, None) -> map.Add(t, a)
        | (Some a, Some b) ->
            let v = min a b
            let newMap = map.Add(t, v).Add(f, v)
            map
            |> Map.filter (fun _ v -> v = a || v = b)
            |> Map.fold (fun m k _ -> m.Add(k, v)) newMap) Map.empty
    |> fun map ->
        let x =
            map
            |> Map.toSeq
            |> Seq.groupBy snd
            |> Seq.length
            |> (-)
            <| 1

        seq { 1 .. n }
        |> Seq.filter (fun z -> z |> map.ContainsKey |> not)
        |> Seq.length
        |> (+) x
|> printfn "%d"
