Go: package main

import (
    "fmt"
    "bufio"
    "strconv"
    "os"
    "strings"
    "math"
)

var rdr = bufio.NewReaderSize(os.Stdin, 1000000)

func readLine() string {
    buf := make([]byte, 0, 1000000)
    for {
        l, p, e := rdr.ReadLine()
        if e != nil {
            panic(e)
        }
        buf = append(buf, l...)
        if !p {
            break
        }
    }
    return string(buf)
}

func toInt(str string) int  {
    n, _ := strconv.Atoi(str)
    return n
}

func abs(a int) int {
    return int(math.Abs(float64(a)))
}

func getPar(x int, parent[1000]int) int {
    if parent[x] == x {
        return x
    } else {
        parent[x] = getPar(parent[x], parent)
        return parent[x]
    }
}

func main() {
    nm := strings.Split(readLine(), " ")
    n := toInt(nm[0])
    m := toInt(nm[1])
    var parent [1000]int
    for i := 0;i < n; i++ {
        parent[i] = i
    }


    for i := 0; i < m; i++ {
        ab := strings.Split(readLine(), " ")
        pa := getPar(toInt(ab[0]) - 1, parent)
        pb := getPar(toInt(ab[1]) - 1, parent)
        parent[pb] = pa
    }

    cities := make(map[int]int)
    villageCnt := 0
    for i := 0;i < n; i ++ {
        pi := getPar(i, parent)
        if i != pi {
            cities[pi] = 1
        } else {
            villageCnt ++
        }
    }
    cityCnt := len(cities)
    fmt.Println(abs(cityCnt * 2 - villageCnt))
}

C++: #include <bits/stdc++.h>
using namespace std;

#define int long long
#define pb push_back
#define mp make_pair
#define fr first
#define sc second
#define Rep(i, n) for( int i = 0; i < (n); i++ )
#define Rrep(i, a, n) for( int i = (a); i < (n); i++ )
#define All(v) v.begin(), v.end()

typedef pair<int, int> Pii;
typedef pair<int, Pii> Pip;
const int INF = 1107110711071107;

struct UnionFind{
    vector<int> r, p;
    UnionFind() {}
    UnionFind(int size) { init(size); }
    void init(int size) {
        r.resize(size, 0);
        p.resize(size, 0);
        for ( int i = 0; i < size; i++ ) r[i] = 1,p[i] = i;
    }
    int find(int x) {
        return (x == p[x] ? x : p[x] = find(p[x]));
    }
    bool same(int x, int y) {
        return find(x) == find(y);
    }
    void unite(int x, int y) {
        x = find(x); y = find(y);
        if ( x == y ) return;
        if( r[x] < r[y] ) swap(x, y);
        r[x] += r[y];
        p[y] = x;
    }
};

signed main() {
    int N, M;
    cin >> N >> M;

    UnionFind uf(N);
    Rep(i, M) {
        int a, b;
        cin >> a >> b;
        uf.unite(--a, --b);
    }

    bool used[1001] = {0};
    int v = 0, c = 0;
    Rep(i, N) {
        bool flag = false;
        if ( used[i] ) continue;
        Rep(j, N) {
            if ( i == j ) continue;
            if ( uf.same(i, j) ) {
                if ( !flag ) c++;
                flag = true;
                used[i] = used[j] = true;
            }
        }
    }

    Rep(i, N) if ( !used[i] ) v++;
    //cout << v << " " << c << endl;
    cout << abs(v - c) << endl;

    return 0;
}

C++: #include<bits/stdc++.h>
#define LL long long
#define rep(i,n) for(int i=0;i<n;++i)
#define FOR(i,a,b) for(int i=a;i<=b;++i)
using namespace std;
static const LL INF = 1LL<<61LL;
static const int MAX_N = 10000;
typedef pair<int,int> PII;

int par[MAX_N];
int rank[MAX_N];
int t[MAX_N];
int temp[MAX_N];
int n,m;
int city;

class UF{
    public:
        void init(int n){
            rep(i,n){
                par[i]=i;
                rank[i]=0;
            }
        }

        int find(int x){
            if(par[x]==x)return x;
            return par[x]=find(par[x]);
        }
        void unite(int x,int y){
            x=find(x);
            y=find(y);
            if(x==y)return;
            if(rank[x]<rank[y])par[x]=y;
            else {
                par[y]=x;
                if(rank[x]==rank[y])rank[x]++;
            }
        }

        bool same(int x,int y){
            return (find(x)==find(y));
        }
};

int main(){
    cin>>n>>m;
    UF uf;
    int val=n;
    uf.init(n);
    rep(i,m){
        int a,b;
        cin>>a>>b;
        if(!t[a])val--;
        if(!t[b])val--;
        t[a]=t[b]=1;
        uf.unite(a,b);
    }
    rep(i,n+1){
        if(t[i]){
            int p=uf.find(i);
            if(!temp[p])city++;
            temp[uf.find(i)]=1;
        }
    }
    cout<<abs(val-city)<<endl;
}

C++: #include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <iostream>
#include <set>
#include <map>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;

int N;
int boss[1000],height[1000];
bool is_Integrated[1000];

int get_boss(int id){
	if(boss[id] == id)return id;
	else{
		return boss[id] = get_boss(boss[id]);
	}
}

int is_same(int x,int y){
	return get_boss(x) == get_boss(y);
}

void unite(int x,int y){
	int boss_x = get_boss(x);
	int boss_y = get_boss(y);

	if(boss_x == boss_y)return;

	if(height[x] > height[y]){

		boss[boss_y] = boss_x;

	}else if(height[x] < height[y]){

		boss[boss_x] = boss_y;

	}else{ //height[x] == height[y]

		boss[boss_y] = boss_x;
		height[x]++;
	}
}


int main(){

	int N,M;
	scanf("%d %d",&N,&M);

	for(int i = 0; i < N; i++){
		boss[i] = i;
		height[i] = 0;
		is_Integrated[i] = false;
	}

	int a,b;

	for(int loop = 0; loop < M; loop++){
		scanf("%d %d",&a,&b);
		a--;
		b--;
		unite(a,b);
		is_Integrated[a] = true;
		is_Integrated[b] = true;
	}

	int city_num = 0,village_num = 0;

	for(int i = 0; i < N; i++){
		if(is_Integrated[i] == true && get_boss(i) == i){
			city_num++;
		}else if(is_Integrated[i] == false){
			village_num++;
		}
	}

	printf("%d\n",abs(city_num-village_num));

	return 0;
}

C++: #include<bits/stdc++.h>

#define rep(i,n) for(int i=0;i<(int)n;i++)
#define all(c) (c).begin(),(c).end()
#define mp make_pair
#define pb push_back
#define each(i,c) for(__typeof((c).begin()) i=(c).begin();i!=(c).end();i++)
#define dbg(x) cerr<<__LINE__<<": "<<#x<<" = "<<(x)<<endl

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef pair<int,int> pi;
const int inf = (int)1e9;
const double INF = 1e12, EPS = 1e-9;

int p[1000];
int root(int x){
	return p[x] < 0 ? x : p[x] = root(p[x]);
}

int main(){
	int n, m; cin >> n >> m;
	int c = 0, v = n;
	rep(i, n) p[i] = -1;
	rep(i, m){
		int a, b; cin >> a >> b; a--; b--;
		int ra = root(a), rb = root(b);
		if(ra == rb) continue;
		if(p[ra] == -1 && p[rb] == -1) c++, v -= 2;
		if(p[ra] != -1 && p[rb] != -1) c--;
		if(p[ra] != -1 && p[rb] == -1 || p[ra] == -1 && p[rb] != -1) v--;
		p[ra] += p[rb];
		p[rb] = ra;
	}
	cout << abs(c - v) << endl;
	
	return 0;
}

C++: #define _USE_MATH_DEFINES
#include <iostream>
#include <fstream>
#include<vector>
#include<algorithm>
#include<numeric>
#include<set>
using namespace std;
class UnionFind{
private:
	vector<int> par, rank;
public:
	int find(int x){
		if (par[x] == x)return x;
		else return par[x] = find(par[x]);
	}

	UnionFind(int n) :par(n), rank(n, 0){
		iota(par.begin(), par.end(), 0);
	}
	bool unite(int x, int y){
		x = find(x);
		y = find(y);
		if (x == y)return false;
		if (rank[x] < rank[y])par[x] = y;
		else{
			par[y] = x;
			if (rank[x] == rank[y])rank[x]++;
		}
		return true;
	}

};
struct init{
	init(){
		cin.tie(0); ios::sync_with_stdio(false);
	}
}________init;
int main() {

#ifdef INPUT_FROM_FILE
	ifstream cin("sample.in");
	ofstream cout("sample.out");
#endif
	int  N, M;
	while (cin >> N >> M){
		UnionFind uf(N);
		while (M--){
			int a, b;
			cin >> a >> b;
			a--, b--;
			uf.unite(a, b);
		}
		set<int> cnt;
		for (int i = 0; i < N; i++){
			if (i != uf.find(i))cnt.insert(uf.find(i));
		}
		int sz1 = (int)cnt.size();
		int sz2 = 0;
		for (int i = 0; i < N; i++){
			if (i == uf.find(i) && cnt.count(i) == 0)sz2++;
		}
		cout << abs(sz1 - sz2) << endl;
	}
	return 0;
}