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 Rust (judge verdict: Accepted)

use std::io::*;
use std::str::FromStr;
use std::clone::Clone;

fn read<T: FromStr>() -> T {
    let stdin = stdin();
    let stdin = stdin.lock();
    let token: String = stdin
        .bytes()
        .map(|c| c.expect("failed to read char") as char)
        .skip_while(|c| c.is_whitespace())
        .take_while(|c| !c.is_whitespace())
        .collect();
    token.parse().ok().expect("failed to parse token")
}

struct UnionFind {
    par: Vec<usize>,
    rank: Vec<usize>,  
    size: Vec<usize>
}

impl UnionFind {
    fn new(n: usize) -> UnionFind {
        let mut vec = vec![0; n];
        for i in 0..n {
            vec[i] = i;
        }
        UnionFind {
            par: vec, 
            rank: vec![0; n], 
            size: vec![1; n]
        }
    }

    fn find(&mut self, x: usize) -> usize {
        if self.par[x] == x {
            x
        } else {
            let p = self.par[x];
            let pp = self.find(p);
            self.size[x] = self.size[pp];
            self.par[x] = pp;
            pp
        }
    }

    fn unite(&mut self, x: usize, y: usize) {
        let p_x = self.find(x);
        let p_y = self.find(y);
        if p_x != p_y {
            self.size[p_x] += self.size[p_y];
            self.size[p_y] = self.size[p_x];
            if self.rank[p_x] < self.rank[p_y] {
                self.par[p_x] = p_y;
            } else {
                self.par[p_y] = p_x;
                if self.rank[p_x] == self.rank[p_y] {
                    self.rank[p_x] += 1;
                }
            }
        }
    }

    fn are_same(&mut self, x: usize, y: usize) -> bool {
        self.find(x) == self.find(y)
    }
}

#[derive(Clone)]
struct Edge {
    from: usize, 
    to: usize, 
    cost: u32
}

fn main() {
    let V: usize = read();
    let E: usize = read();
    let mut edges: Vec<Edge> = vec![
        Edge{ from: 0, to: 0, cost: 0 }; E
    ];

    for i in 0..E {
        edges[i].from = read();
        edges[i].to = read();
        edges[i].cost = read();
    }
    edges.sort_by(
        |e1, e2| { e1.cost.cmp(&e2.cost) }
    );

    let mut uf = UnionFind::new(V);
    let mut ans = 0;
    for edge in &edges {
        if !uf.are_same(edge.from, edge.to) {
            uf.unite(edge.from, edge.to);
            ans += edge.cost;
        }
    }

    println!("{}", ans);
}