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;

int main () {
    int N, M; cin >> N >> M;
    int C = N + 1;
    vector<int> T(N);
    for (int i = 0; i < N; i++) T[i] = i + 1;

    for (int i = 0; i < M; i++) {
        int x, y; cin >> x >> y;
        x = T[x-1], y = T[y-1];
        for (auto &j : T) {
            if (j == x || j == y) j = C;
        }
        C++;
    }

    set<int> u, l;
    for (auto i : T) {
        if (i > N) u.insert(i);
        else l.insert(i);
    }

    cout << abs((int)u.size() - (int)l.size()) << endl;

    return 0;
}

C++: #include <vector>
#include <map>
#include <cstdio>
#include <cstdlib>
class union_find{
	std::vector<int> parent;
public:
	int root(int a){return parent[a]==a?a:(parent[a]=root(parent[a]));}
	union_find(int n):parent(n+1){for(int i=1;i<=n;i++)parent[i]=i;}
	int same(int a,int b){return root(a)==root(b);}
	int unite(int a,int b){
		int x=root(a),y=root(b);//if(x==y)return 0;
		parent[x]=y;
		return 1;
	}
	int calc(){
		std::map<int,int> m;
		for(int i=1;i<parent.size();i++)m[root(i)]++;
		int r=0;
		for(auto &e:m)r+=e.second>1?1:-1;
		return abs(r);
	}
};
int main(){
	int n,m;
	scanf("%d%d",&n,&m);
	union_find uf(n);
	int a,b;
	for(;m--;uf.unite(a,b))scanf("%d%d",&a,&b);
	printf("%d\n",uf.calc());
}

C++: #include <fstream>
#include <iostream>
#include <vector>
#include <iomanip>
#include <algorithm>

using namespace std;
#define ALL(c) (c).begin(), (c).end()
#define REP(i,n) for(ll i=0; i < (n); ++i)
using ll = long long;
using vl = vector<ll>;

struct union_find{
	vl v;
	union_find(ll n) : v(n, -1){}
	ll find(ll x) { return (v[x] < 0) ? x : (v[x] = find(v[x])); }
	void unite(ll x, ll y){
		x = find(x); y = find(y);
		if (x == y) return;
		if (-v[x] < -v[y]) swap(x, y);
		v[x] += v[y];
		v[y] = x;
	}
	bool same(ll x, ll y){
		return find(x) == find(y);
	}
	ll size(ll x) { return -v[find(x)]; }
};

int main(){
#ifdef _WIN32
	ifstream cin("sample.in");
	ofstream cout("sample.out");
#endif
	cout << fixed << setprecision(8);

	ll n, m; cin >> n >> m;
	vl a(m), b(m);
	REP(i, m) cin >> a[i] >> b[i];

	union_find uf(n);
	REP(i, m) uf.unite(a[i]-1, b[i]-1);
	
	ll cntm = 0;
	ll cnts = 0;
	REP(i, n){
		if (uf.size(i) == 1){
			cntm++;
		}
		else{
			if (uf.find(i) == i){
				cnts++;
			}
		}
	}

	cout << abs(cntm - cnts) << endl;
}

C++: #include <bits/stdc++.h>
#define rep(i,n) for(int i=0;i<(int)(n);i++)
#define rep1(i,n) for(int i=1;i<=(int)(n);i++)
#define all(c) c.begin(),c.end()
#define pb push_back
#define fs first
#define sc second
#define show(x) cout << #x << " = " << x << endl
#define chmin(x,y) x=min(x,y)
#define chmax(x,y) x=max(x,y)
using namespace std;
struct unionfind{
	int par[1000],sz[1000];
	void init(int N){rep(i,N) par[i]=i;}
	int find(int x){
		if(par[x]==x) return x;
		return par[x]=find(par[x]);
	}
	bool same(int x,int y){
		return find(x)==find(y);
	}
	void unite(int x,int y){
		x=find(x),y=find(y);
		par[y]=x;
		sz[x]+=sz[y];
	}
}UF;
int main(){
	int N,M;
	cin>>N>>M;
	UF.init(N);
	rep(i,M){
		int a,b;
		cin>>a>>b;
		a--,b--;
		UF.unite(a,b);
	}
	int x=0;
	rep(i,N) if(UF.find(i)==i){
		if(UF.sz[i]==1) x++;
		else x--;
	}
	cout<<abs(x)<<endl;
}

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

struct UnionFind {
	vector<int> data;
	UnionFind(int size) : data(size, -1) { }
	bool unionSet(int x, int y) {
		x = root(x); y = root(y);
		if (x != y) {
			if (data[y] < data[x]) swap(x, y);
			data[x] += data[y]; data[y] = x;
		}
		return x != y;
	}
	int root(int x) {
		return data[x] < 0 ? x : data[x] = root(data[x]);
	}
	int size(int x) {
		return -data[root(x)];
	}
};

int main() {
	int N, M; cin >> N >> M;
	UnionFind uf(N);
	for (int i = 0; i < M; ++i) {
		int a, b; cin >> a >> b;
		a--; b--;
		uf.unionSet(a, b);
	}
	set<int>aset;
	int ans = 0;
	for (int i = 0; i < N; ++i) {
		int num = uf.size(i);
		int root = uf.root(i);
		if (aset.find(root) == aset.end()) {
			if (num == 1)ans++;
			else ans--;
			aset.emplace(root);
		}
	}
	cout << (abs(ans)) << endl;
	return 0;
}

C++: #include <bits/stdc++.h>
#define rep(i, a, n) for(int i = a; i < n; i++)
#define repb(i, a, b) for(int i = a; i >= b; i--)
#define all(a) a.begin(), a.end()
#define int long long
using namespace std;

struct UF{
    vector<int> par;
    vector<int> sz;
    void init(int n){
        par.resize(n);
        sz.resize(n, 1);
        rep(i, 0, n) par[i] = i;
    }
    int find(int x){
        if(x == par[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(sz[x] < sz[y]) swap(x, y);
        sz[x] += sz[y];
        par[y] = x;
    }
};

signed main(){
    int n, m;
    cin >> n >> m;
    UF uf;
    uf.init(n);
    set<int> vil;
    rep(i, 0, m){
        int a, b;
        cin >> a >> b;
        a--; b--;
        uf.unite(a, b);
        vil.insert(a);
        vil.insert(b);
    }
    int cnt = n - vil.size();
    set<int> st;
    rep(i, 0, n){
        st.insert(uf.find(i));
    }
    // cout << cnt << ' ' << st.size() << endl;
    cout << abs(st.size() - 2*cnt) << endl;
}

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

#define int long long

typedef long long ll;
typedef pair<int,int>pint;
typedef vector<int>vint;
typedef vector<pint>vpint;
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define all(v) (v).begin(),(v).end()
#define rep(i,n) for(int i=0;i<(n);i++)
#define reps(i,f,n) for(int i=(f);i<(n);i++)
#define each(it,v) for(__typeof((v).begin()) it=(v).begin();it!=(v).end();it++)
template<class T,class U>void chmin(T &t,U f){if(t>f)t=f;}
template<class T,class U>void chmax(T &t,U f){if(t<f)t=f;}

struct UF{
    int N;
    vint par,sz;
    void init(int n){
        N=n;
        par.resize(N);
        sz.resize(N);
        for(int i=0;i<N;i++)par[i]=i,sz[i]=1;
    }
    int find(int x){
        return x==par[x]?x:par[x]=find(par[x]);
    }
    void unite(int x,int y){
        x=find(x);y=find(y);
        if(x==y)return;
        sz[x]+=sz[y];
        par[y]=x;
    }
    bool same(int x,int y){
        return find(x)==find(y);
    }
};

int N,M;
UF uf;
signed main(){
    cin>>N>>M;
    uf.init(N);
    rep(i,M){
        int a,b;
        cin>>a>>b;
        a--;b--;
        uf.unite(a,b);
    }

    int x=0,y=0;
    rep(i,N)if(uf.find(i)==i){
        if(uf.sz[uf.find(i)]==1)y++;
        else x++;
    }

    cout<<abs(x-y)<<endl;
    return 0;
}