Problem:
Minimum Spanning Tree

Find the sum of weights of edges of the Minimum Spanning Tree for a given weighted undirected graph G = (V, E).

Input

|V| |E|
s0 t0 w0
s1 t1 w1
:
s|E|-1 t|E|-1 w|E|-1

, where |V| is the number of vertices and |E| is the number of edges in the graph. The graph vertices are named with the numbers 0, 1,..., |V|-1 respectively.

si and ti represent source and target verticess of i-th edge (undirected) and wi represents the weight of the i-th edge.

Output

Print the sum of the weights of the Minimum Spanning Tree.

Constraints

1 ≤ |V| ≤ 10,000

0 ≤ |E| ≤ 100,000

0 ≤ wi ≤ 10,000

The graph is connected

There are no parallel edges

There are no self-loops

Sample Input 1

4 6
0 1 2
1 2 1
2 3 1
3 0 1
0 2 3
1 3 5

Sample Output 1

3

Sample Input 2

6 9
0 1 1
0 2 3
1 2 1
1 3 7
2 4 1
1 4 3
3 4 1
3 5 1
4 5 6

Sample Output 2

5

Solution in C++ (judge verdict: Accepted)

// 以下のライブラリを使ってみる.
// beet氏.
// http://judge.u-aizu.ac.jp/onlinejudge/review.jsp?rid=2068814#1
// 素集合データ構造(Union-Find)
// https://ei1333.github.io/luzhiled/snippets/structure/union-find.html
#include<bits/stdc++.h>
using namespace std;
#define MAX 100000
#define MAX_E 100000
int V,E;

struct edge{
   int u; // 始点.
   int v; // 終点.
   int c; // コスト.
   bool operator < (const edge &E) const{ return (c < E.c); };
};
edge es[MAX_E];

// Union-Find木.
struct UnionFind{

    vector<int> data;
    UnionFind(int sz){ data.assign(sz, -1); }
    
    // 1. 頂点 x, y の 結合.
    bool unite(int x, int y){
        x = find(x), y = find(y);
        if(x == y)            return false;
        if(data[x] > data[y]) swap(x, y);
        data[x] += data[y];
        data[y] = x;
        return true;
    }
    
    // 2. 頂点 k を 探索.
    int find(int k){
        if(data[k] < 0) return k;
        return data[k] = find(data[k]);
    }
    
    // 3. 頂点 k を含む集合 の 大きさ.
    int size(int k){ return (-data[find(k)]); }
};

// クラスカル法.
int kruskal(){

    // 1. 辺をコストで昇順ソート.
    sort(es, es + E);

    // 2. Union-Find木を作成.
    UnionFind uf(V);

    // 3. 最小全域木の辺の重みの総和を計算.
    int res = 0;
    for(int i = 0; i < E; i++){
        edge e = es[i];
        if(uf.find(e.u) != uf.find(e.v)){
            uf.unite(e.u, e.v);
            res += e.c;
        }
    }
    return res;
}

int main(){

    // 1. 入力情報.
    scanf("%d %d", &V, &E);
    
    // 2. グラフ.
    for(int i = 0; i < E; i++){
        int a, b, c;
        scanf("%d %d %d", &a, &b, &c);
        es[i] = (edge){a, b, c};
    }
    
    // 3. 出力.
    int ans = kruskal();
    printf("%d\n", ans);
    return 0;

}