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)

#[allow(unused_imports)]
use std::cmp::{min,max};
use std::collections::BinaryHeap;

struct DisjointSet {
    ps: Vec<Option<usize>>,
    ns: Vec<i64>,
}

impl DisjointSet {
    #[allow(dead_code)]
    fn new(n: usize) -> DisjointSet {
        DisjointSet { ps: vec![None; n], ns: vec![1; n] }
    }

    #[allow(dead_code)]
    fn unite(&mut self, x: usize, y: usize) {
        let nx = self.find(x);
        let ny = self.find(y);
        if nx == ny {
            return;
        }
        let (a,b) = if self.ns[nx] < self.ns[ny] { (nx,ny) } else { (ny,nx) };
        self.ps[a] = Some(b);
        self.ns[b] += self.ns[a];
    }

    #[allow(dead_code)]
    fn find(&mut self, x: usize) -> usize {
        match self.ps[x] {
            Some(y) => {
                let res = self.find(y);
                self.ps[x] = Some(res);
                res
            },
            None => {
                x
            },
        }
    }

    #[allow(dead_code)]
    fn same(&mut self, x: usize, y: usize) -> bool {
        self.find(x) == self.find(y)
    }
}

fn main() {
    let (v,e) = {
        let xs = read_vec_i64();
        (xs[0] as usize, xs[1] as usize)
    };
    let edges = {
        let mut res = vec![];
        for _ in 0..e {
            let ys = read_vec_i64();
            let (s,t,w) = (ys[0] as usize, ys[1] as usize, ys[2]);
            res.push((s,t,w));
        }
        res
    };
    let mut ds = DisjointSet::new(v);
    let mut heap = BinaryHeap::new();
    for (i,&(_,_,w)) in edges.iter().enumerate() {
        heap.push((-w,i));
    }
    let mut res = 0;
    while let Some((_,i)) = heap.pop() {
        let (s,t,w) = edges[i];
        if ! ds.same(s,t) {
            ds.unite(s,t);
            res += w;
        }
    }
    println!("{}", res);
}

#[allow(dead_code)]
fn read_line() -> String {
    let mut ret = String::new();
    std::io::stdin().read_line(&mut ret).ok();
    ret.pop();
    return ret;
}

#[allow(dead_code)]
fn read_i64() -> i64 {
    let ss = read_line();
    return ss.parse::<i64>().unwrap();
}

#[allow(dead_code)]
fn read_vec_i64() -> Vec<i64> {
    let mut res = vec![];
    let ss = read_line();
    for ts in ss.split_whitespace() {
        let x = ts.parse::<i64>().unwrap();
        res.push(x);
    }
    return res;
}