import java.io.BufferedReader
import java.io.InputStreamReader
import java.io.PrintWriter
import java.util.*

fun main(args: Array<String>) {

    // IO Templates
    val br = BufferedReader(InputStreamReader(System.`in`))
    val out = PrintWriter(System.out)

    val (n, m) = br.readLine()!!.split(' ').map { it.toInt() }

    val g = Array(n) { mutableListOf<Int>() }

    for (i in 1..m) {
        var (a, b) = br.readLine()!!.split(' ').map { it.toInt() }
        a--
        b--
        g[a].add(b)
        g[b].add(a)
    }

    var clusterSize = 0
    val seen = BooleanArray(n) { false }

    for (i in 0 until n) {
        if (seen[i]) continue

        clusterSize++
        val que: Queue<Int> = LinkedList()
        que.add(i)
        seen[i] = true

        while (que.isNotEmpty()) {
            val now = que.poll()
            for (next in g[now]) {
                if (seen[next]) continue
                seen[next] = true
                que.add(next)
            }
        }
    }

    out.println(clusterSize - 1)

    out.flush()
}