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 FOR(i,s,e) for(int (i)=(s);(i)<(int)(e);(i)++)
#define REP(i,e) FOR(i,0,e)
#define RFOR(i,e,s) for(int (i)=(e)-1;(i)>=(int)(s);(i)--)
#define RREP(i,e) RFOR(i,e,0)

#define all(o) (o).begin(), (o).end()
#define psb(x) push_back(x)
#define mp(x,y) make_pair((x),(y))

typedef long long ll;
typedef pair<int, int> PII;
typedef priority_queue<int> PQI;
typedef priority_queue<PII> PQII;

typedef struct edge_def {
  int from;
  int to;
  int cost;

  edge_def(int _from, int _to, int _cost) {
    from = _from;
    to   = _to;
    cost = _cost;
  };
} edge;

const int INF = 1e9;
const int V = 1000;   //??????????????§??°
const int E = 100;  //???????????§??°
int nv, ne;        //?????????????????°
int usd[V];        //?¢??????????????????§????????¨
vector<edge> es[V];  //dijkstra??¨(es[i].from == i)

int dfs(int k) {
  int res = 1;
  usd[k] = 1;
  REP(i,(int)es[k].size()) {
    int nxt = es[k][i].to;
    if (!usd[nxt]) res += dfs(nxt);
  }
  return res;
}

int main() {
  scanf("%d%d ", &nv, &ne);
  REP(i,nv) es[i].clear();
  REP(i,ne) {
    int a, b;
    scanf("%d%d ", &a, &b);
    a--; b--;
    es[a].psb(edge(a,b,1));
    es[b].psb(edge(b,a,1));
  }

  memset(usd, 0, sizeof(usd));
  int prf=0, vlg=0;
  REP(i,nv) {
    if (!usd[i]) {
      if (dfs(i)>1)
        vlg++;
      else
        prf++;
    }
  }

  printf("%d\n", abs(prf-vlg));

  return 0;
}