Problem:
Score : 300 points

Problem Statement

There are N cities numbered 1 through N, and M bidirectional roads numbered 1 through M.
Road i connects City A_i and City B_i.

Snuke can perform the following operation zero or more times:

Choose two distinct cities that are not directly connected by a road, and build a new road between the two cities.

After he finishes the operations, it must be possible to travel from any city to any other cities by following roads (possibly multiple times).

What is the minimum number of roads he must build to achieve the goal?

Constraints

2 \leq N \leq 100,000

1 \leq M \leq 100,000

1 \leq A_i < B_i \leq N

No two roads connect the same pair of cities.

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N M
A_1 B_1
:
A_M B_M

Output

Print the answer.

Sample Input 1

3 1
1 2

Sample Output 1

1

Initially, there are three cities, and there is a road between City 1 and City 2.

Snuke can achieve the goal by building one new road, for example, between City 1 and City 3.
After that,

We can travel between 1 and 2 directly.

We can travel between 1 and 3 directly.

We can travel between 2 and 3 by following both roads (2 - 1 - 3).

Solution in C# (Mono-csc 3.5.0) (judge verdict: Wrong Answer)

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Text.RegularExpressions;
using System.Numerics;using static System.Math;
namespace _NS
{
    class _PR
    {
        static void Main()
        {
            var NM = CinTAr;
            List<int> gps = new List<int>() { 0 };
            int[] inf = new int[NM[0]];

            AFOR(NM[1], _ =>
            {
                var ab = CinTAr;
                int a = ab[0] - 1;
                int b = ab[1] - 1;
                if (inf[a] == inf[b])
                {
                    if (inf[a] == 0)
                    {//new
                        inf[a] = inf[b] = gps.Count;
                        gps.Add(inf[a]);
                    }
                }
                else if (inf[a] != inf[b])
                {
                    if (inf[a] == 0)
                    {
                        inf[a] = inf[b];
                    }
                    else if (inf[b] == 0)
                    {
                        inf[b] = inf[a];
                    }
                    else
                    {//double pair
                        if (inf[b] != gps[inf[b]])
                        {
                            gps[inf[a]] = gps[inf[b]];
                            inf[a] = inf[b];
                        }
                        else
                        {
                            gps[inf[b]] = gps[inf[a]];
                            inf[b] = inf[a];
                        }


                    }
                }

            });
            int r = -1;
            for (int i = 1; i < gps.Count; i++)
            {
                if (gps[i] == i) { r++; }
            }
            Cout = r + inf.Where(x => x == 0).Count();


            Wait();
        } //main
        #region LIBRARY
        static int MOD10_9_7 = 1000000000 + 7;
        static string Yes = "Yes", No = "No", Good = "Good", Bad = "Bad";
        static int GrARXY(int x, int y, int wid) { return y * wid + x; }
        static int[] GrXY(int arxy, int wid) { return new int[] { arxy % wid , arxy / wid}; }
        static int GetDigits(long n) { return (int)Floor(Log10(n)) + 1; }
        static int GetNumByDigit(long n, int d) { return (int)((n / ((int)Pow(10, d - 1))) % 10); }
        static long Loop(long n, long max){ if (n > max) { return n % (max + 1); } else if (n < 0) { return max - (-n - 1) % (max + 1); } else { return n; }}
        static int Loop(int n, int max) { return (int)Loop((long)n, max); }
        static long PW10(int n) { return (long)Pow(10, n); }
        static long GCD(long a, long b) { if (a < b) { return GCD(b, a); } if (a % b == 0) { return b; } else { return GCD(b, a % b); } }
        static long LCM(long a, long b) { return a * b / GCD(a, b); }
        static void Swap<T>(ref T a, ref T b) { T t = a; a = b; b = t; }
        static void SwapArE<T>(T[] a, int i, int j) { T t = a[i]; a[i] = a[j]; a[j] = t; }
        static void SwapLiE<T>(List<T> a, int i, int j) { T t = a[i]; a[i] = a[j]; a[j] = t; }
        static bool IsInt(double d) { return (long)d == d; }
        static string Wait() { return Console.ReadLine(); }
        static string Cin { get { return Wait(); } }
        static string[] CinAr { get { return Cin.Split(' ').Where(x => x != "").ToArray(); } }
        static int CinT { get { return S2I(Cin); } }
        static int[] CinTAr { get { return CinAr.Select(x => S2I(x)).ToArray(); } }
        static long CinL { get { return S2L(Cin); } }
        static long[] CinLAr { get { return CinAr.Select(x => S2L(x)).ToArray(); } }
        static double CinD { get { return S2D(Cin); } }
        static double[] CinDAr { get { return CinAr.Select(x => S2D(x)).ToArray(); } }
        static int S2I(string s) { return int.Parse(s); }
        static long S2L(string s) { return long.Parse(s); }
        static double S2D(string s) { return double.Parse(s); }
        static object Cout { set { Console.WriteLine(value); } }
        static object WCout { set { Console.Write(value); } }
        static string RevStr(string s) { return new string(s.Reverse().ToArray()); }
        static void AFOR(int m, Action<int> ActI) { for (int i = 0; i < m; i++) { ActI(i); } }
        static void AFOR(long m, Action<long> ActI) { for (long i = 0; i < m; i++) { ActI(i); } }
        static void AFOR(long m, Action Act) { AFOR(m, i => Act()); }
        static long[] Divisor(long n)
        {
            if (n == 1) { return new long[] { 1 }; } List<long> r = new List<long>() { 1, n };
            for (long i = 2; i <= Sqrt(n); i++) { if (n % i == 0) { r.Add(i); long f = n / i; if (f != i) { r.Add(f); } } } return r.ToArray();
        }
        static IEnumerable<decimal> PrimeFactors(decimal n)
        {
            decimal i = 2, t = n; while (i * i <= n) { if (t % i == 0) { t /= i; yield return i; } else { i++; } } if (t != 1) { yield return t; }
        }
        static bool IsPrime(long n){ if (n == 1) { return false; } for (long i = 2; i <= Sqrt(n) + 1; i++) { if (n % i == 0) { return false; } } return true;  }
        static void CoutPaAr<Type>(IEnumerable<Pair<Type>> p) { CoutAr(p.Select(x => $"({x.a}, {x.b}, {x.c})")); }
        static void CoutAr<Type>(IEnumerable<Type> t) { Cout = string.Join(" ", t); }
        static long nCr(int n, int r) { return nPr(n, r) / Factorial(r); }
        static long nPr(int n, int r) { return FactorDiv(n, n - r); }
        static long FactorDiv(int t, int d) { long r = 1; for (int i = t; i > d; i--) { r *= i; } return r; }
        static long Factorial(int i) { if (i <= 1) { return 1; } return i * Factorial(i - 1); }
        #endregion
    }
    struct Pair<T>
    {
        public T a, b, c;
        public Pair(T _a, T _b, T _c = default(T)) { a = _a; b = _b; c = _c; }
    }
}