#include <bits/stdc++.h>
#pragma GCC optimize("Ofast")
#define ll long long int
#define ull unsigned long long int
#define ld long double
#define ascpqi priority_queue<int, vector<int>, greater<int> >
#define ascpql priority_queue<long long int, vector<long long int>, greater<long long int> >
#define ascpqpi priority_queue<pair<int, int>, vector<pair<int, int> greater<pair<int, int> > >
#define descpqi priority_queue<int>
#define descpql priority_queue<long long int>
#define descpqpi priority_queue<pair<int, int> >
#define pii pair<int, int>
#define pll pair<long long int, long long int>
#define puu pair<unsigned long long int, unsigned long long int>
#define pcc pair<char, char>
#define pss pair<string, string>
#define pi acos(-1)
#define vi vector<int>
#define vl vector<long long int>
#define vu vector<unsigned long long int>
#define vd vector<double>
#define vc vector<char>
#define vs vector<string>
#define sortv(x) sort(x.begin(), x.end())
#define vpi vector<pair<int, int> >
#define vpl vector<pair<long long int, long long int> >
#define vpd vector<pair<double, double> >
#define vpc vector<pair<char, char> >
#define vps vector<pair<string, string> >
#define debug1(a) cout << a << endl;
#define debug2(a, b) cout << a << ' ' << b << endl
#define debug3(a, b, c) cout << a << ' ' << b << ' ' << c << endl
#define debugarr(arr, n) for(int i=0; i<n; i++) {cout << arr[i] << ' ';} cout << endl
#define imax pow(2, 31)-1
#define imin -(pow(2, 31)-1)
#define llmax pow(2, 63)-1
#define llmin -(pow(2, 63)-1)
#define ullmax pow((ull) 2, (ull) 64)-1
#define ullmin 0
#define uimin 0
#define uimax pow(2, 32)-1
#define outround(x) cout << fixed << setprecision(x)
#define multitest int t; cin >> t; while(t--) solve();
using namespace std;
 
ull bigMod(ull b, ull p, ull m) { // (b^p)%m
    b=b%m;
    if(p==0) return 1;
    else if(p%2==0) return ((ull) pow(bigMod(b, p/2, m), 2))%m;
    else return ((ull) pow(bigMod(b, (p-1)/2, m), 2)*b)%m;
}
 
ull nCr(ull n, ull r) {
    ull ans=1;
    if(r>=n-r) {
        for(ull i=r+1;i<=n;i++) {
            ans=ans*i;
        }
        for(ull i=1;i<=n-r;i++) {
            ans=ans/i;
        }
    }
    else {
        for(ull i=n-r+1;i<=n;i++) {
            ans=ans*i;
        }
        for(ull i=1;i<=r;i++) { 
            ans=ans/i;
        }
    }
    return ans;
}
 
ull fib(ull a) {
    const long double root5=sqrt(5);
    const long double root5plus1div2=(root5+1)/2;
    return round(pow(root5plus1div2, a)/root5);
}
 
ull gcd(ull a, ull b) {
    if(b==0) return a;
    else return gcd(b, a%b);
}
 
ull lcm(ull a, ull b) {
    return ((a*b)/gcd(a, b));
}
 
bool isPrime(ull a) {
    if(a%2==0) return false;
    for(int i=3; i<=sqrt(a); i+=2) {
        if(a%i==0) return false;
    }
    return true;
}
 
bool isComposite(ull a) {
    if(isPrime(a)) return false;
    else return true;
}
 
bool coPrime(ull a, ull b) {
    if(gcd(a, b)==1) return true;
    else return false;
}
 
ld toRadian(ld deg) {
    return (deg*pi/180);
}
 
ull strToInt(string a) {
    int len=a.length();
    int power=0;
    ull tot=0;
    for(int i=len-1; i>=0; i--) {
        tot=tot+pow(10, power)*(a[i]-'0');
        power++;
    }
    return tot;
}
 
bool desc(int a, int b) {
    return a>b;
}
 
ull mex(int* arr, int n) {
    sort(arr, arr+n);
    int now=-1;
    for(int i=0; i<n; i++) {
        if(arr[i]==now+1) {
            now++;
        }
        else if(arr[i]==now) {
            
        }
        else {
            return now+1;
        }
    }
    return now+1;
}

ll euclid_ext(ll a, ll b, ll *x, ll *y) {
    // cout<<a<<' '<<b<<endl;
    if(a==0) {
        *x=0;
        *y=1;
        return b;
    }
    ll sx,sy;
    ll gcd=euclid_ext(b%a,a,&sx,&sy);
    // cout<<a<<' '<<b<<endl;
    *x=sy-(b/a)*sx;
    *y=sx;
    return gcd;
}
 
ll modInv(ll b, ll m) {
    ll x,y;
    ll gcd=euclid_ext(b,m,&x,&y);
    if(gcd==-1) {
        return -1;
    }
    else {
        return (x%m+m)%m;
    }
}
 
ld slope(ld xdiff, ld ydiff) {
    return (ydiff/xdiff);
}
 
bool binSearch(ll* arr, ll n, ll target) {
    ull l=0, r=n-1;
    while(l<r) {
        int mid=(l+r)/2;
        if(arr[mid]>=target) {
            r=mid;
        }
        else {
            l=mid+1;
        }
    }
    if(arr[l]==target) {
        return true;
    }
    else {
        return false;
    }
}
 
int ascii(char x) {
    return int(x);
}
 
ld sine(ld x) {
    return sin(toRadian(x));
}
 
ld cosine(ld x) {
    return cos(toRadian(x));
}
 
ld tangent(ld x) {
    return tan(toRadian(x));
}
 
ull hammDist(string a, string b, ull len) {
    ull cnt=0;
    for(int i=0; i<len; i++) {
        if(a[i]!=b[i]) cnt++;
    }
    return cnt;
}
 
ull binStrToInt(string a, ull len) {
    ull num=0;
    for(int i=len-1; i>=0; i--) {
        if(a[i]=='1') {
            num=num+pow((ull) 2, len-i-1);
        }
    }
    return num;
}

const ll maxn=1000001;

class fenwick {
    ll arr[maxn]={0};
    ll n;
    public:
        void init(ll);
        void update(int,ll); //update(a,b)=update position a by delta of b
        ll sum(int); //sum(a)=sum of items in the range [1...a]
        int g(int);
        int h(int);
};

int fenwick::g(int a) {
    return (a&(a+1));
}

int fenwick::h(int a) {
    return (a|(a+1));
}

void fenwick::update(int pos, ll ch) {
    for(;pos<n;pos=h(pos)) {
        arr[pos]+=ch;
    }
}

ll fenwick::sum(int pos) {
    ll ans=0;
    while(pos>=0) {
        ans+=arr[pos];
        pos=g(pos)-1;
    }
    return ans;
}

void fenwick::init(ll t) {
    n=t;
}

class dsu {
    int arr[maxn];
    int n;
    public:
        void merge(int,int);
        int get(int);
        void init(int);
};

void dsu::init(int a) {
    n=a;
    for(int i=0; i<n; i++) arr[i]=i;
}

int dsu::get(int u) {
    if(u==arr[u]) return u;
    else return arr[u]=get(arr[u]);
}

void dsu::merge(int u, int v) {
    arr[get(u)]=get(v);
}

void solve() {
    dsu ok;
    int n,m;
    cin>>n>>m;
    ok.init(n+1);
    int u,v;
    for(int i=0; i<m; i++) {
        cin>>u>>v;
        ok.merge(u,v);
    }
    map<int,bool> have;
    have[ok.get(1)]=true;
    int cnt=0;
    for(int i=2; i<=n; i++) {
        if(!have.count(ok.get(i))) {
            cnt++;
            have[ok.get(i)]=1;
        }
    }
    cout<<cnt<<endl;
}

int main() {
    cin.tie(NULL);
    cout.tie(NULL);
    ios::sync_with_stdio(false);
    // multitest
    solve();
}

//TODO: CHANGE VALUE OF "MAXN"












Measured memory_bytes: 7872