import java.math.*
import java.util.*
import java.util.function.*
import java.util.stream.*
import kotlin.math.min

fun main(args: Array<String>) {
  val sc = Scanner(System.`in`)
  val n = sc.nextInt()
  val m = sc.nextInt()
  val list = (0 until n).map {
    UnionFind(it)
  }
  (0 until m).forEach {
    val a = sc.nextInt() - 1
    val b = sc.nextInt() - 1
    UnionFind.union(list[a], list[b], ::min)
  }
  println(list.map(UnionFind<Int>::getGroupValue).toSet().size - 1);
}

/**
 * Union Find
 * @param <T> 値の型
</T> */
internal class UnionFind<T>(
  /** 値  */
  val value: T
) {
  /** 親 (なければnull)  */
  private var parent: UnionFind<T>? = null
  /**
   * この要素の値を返す。
   * @return 値
   */

  /** 所属するグループの合算した値 (root要素以外のgroupValueは正しいとは限らない)  */
  private var groupValue: T
  override fun equals(o: Any?): Boolean {
    return this === o
  }

  /**
   * root要素を返す。
   * @return root要素
   */
  private val root: UnionFind<T>
    private get() {
      if (parent == null) {
        return this
      }
      val root = parent!!.root
      parent = root
      return root
    }

  /**
   * この要素が属するグループの値を返す。
   * @return グループの値
   */
  fun getGroupValue(): T {
    return root.groupValue
  }

  companion object {
    /**
     * 同じグループに属するかどうか
     * @param a a
     * @param b b
     * @param <S> 値の型
     * @return 同じグループに属するならtrue
    </S> */
    fun <S> sameGroup(a: UnionFind<S>, b: UnionFind<S>): Boolean {
      return a.root == b.root
    }

    /**
     * 同じ木に所属させる
     * @param a a
     * @param b b
     * @param <S> 値の型
    </S> */
    fun <S> union(a: UnionFind<S>, b: UnionFind<S>) {
      union(a, b, { _1, _ -> _1 })
    }

    /**
     * 同じ木に所属させる。また、値の計算もする
     * @param a a
     * @param b b
     * @param groupValueFunction aとbが異なるグループに属するとき、その2つのグループの値を合算する関数。
     * @param <S> 値の型
    </S> */
    fun <S> union(a: UnionFind<S>, b: UnionFind<S>, groupValueFunction: (S, S) -> S) {
      val aRoot = a.root
      val bRoot = b.root
      if (aRoot != bRoot) {
        bRoot.parent = aRoot
        aRoot.groupValue = groupValueFunction(aRoot.groupValue, bRoot.groupValue)
      }
    }
  }

  /**
   * Union Find
   * @param value 値
   */
  init {
    groupValue = value
  }
}
