module union_find_mod
    use,intrinsic :: iso_fortran_env
    integer(int32), allocatable:: ar(:)
contains
subroutine init(n)
    allocate(ar(n), source=[(i,i=1,n)])
end subroutine

recursive function root(x) result(ret)
    integer(int32):: x,ret
    if(ar(x) == x) then
        ret = x
    else
        ar(x) = root(ar(x))
        ret = ar(x)
    end if
end function

subroutine unite(x,y)
    integer(int32):: x,y
    x = root(x)
    y = root(y)
    if (x==y) return
    ar(x) = ar(y)
end subroutine
end module


program main
    use,intrinsic :: iso_fortran_env
    use union_find_mod
    implicit none
    integer(int32):: n,m,i,a,b,ans
    integer(int32), allocatable:: cnt(:)


    read*, n,m
    allocate(cnt(n),source=0)
    call init(n)

    do i=1,m
        read*, a,b
        call unite(a,b)
    end do

    do i=1,n
        ar(i) = root(i)
    end do
    do i=1,n
        cnt(ar(i)) = cnt(ar(i)) + 1
    end do
    ans=0
    do i=1,n
        if (cnt(i) > 0) ans=ans+1
    end do
    print'(i0)',ans-1
end program main