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 PHP (judge verdict: Wrong Answer)

/**
 *
 */
fun main(args: Array<String>) {
    Main.init()

    Main.execute()

    Main.display()
}

data class Timestamp(var findedAt: Int? = null, var endedAt: Int? = null)

class Main {

    companion object {
        private lateinit var edgeList: Array<Edge>

        private val nodeList = arrayListOf<Node>()

        private var weightSum = 0

        fun init() {
            val (nodeNum, edgeNum) = readLine()!!.split(" ")


            edgeList = Array(edgeNum.toInt()) {
                val (source, target, weight) = readLine()!!.split(" ")
                Edge(source.toInt(), target.toInt(), weight.toInt())
            }

            val sortManager = MergeSortManager()

            // そーと
            edgeList = sortManager.execute(edgeList)

            for (index in 1..nodeNum.toInt()) {
                nodeList.add(Node())
            }
        }


        fun execute() {

            var currentIndex = 0

            var unionNum = 0
            while (true) {
                val edge = edgeList.getOrNull(currentIndex) ?: break

                val sourceRootId = getRootNodeIndex(edge.source)
                val targetRootId = getRootNodeIndex(edge.target)

                // くっつける
                if (sourceRootId != targetRootId) {
                    unionNum++
                    weightSum += edge.weight
                    nodeList[sourceRootId].parent = targetRootId

                    if (unionNum == nodeList.size) {
                        break
                    }
                }

                currentIndex++
            }
        }

        fun display() {

            println(weightSum)
        }


        fun getRootNodeIndex(id: Int): Int {
            if (nodeList[id].parent == null) {
                return id
            }

            return getRootNodeIndex(nodeList[id].parent!!)
        }
    }

}

class MergeSortManager {

//    fun init() {
//
//        readLine()
//
//        inputs = readLine()!!.split(" ").map { it.toInt() }
//
//    }

    fun execute(inputs: Array<Edge>): Array<Edge> {
        return mergeSort(inputs)
    }

    /**
     * 配列をまーじそーと。
     */
    fun mergeSort(list: Array<Edge>): Array<Edge> {

        if (list.size <= 1) {
            return list
        }

        val mediumIndex = (list.size / 2.0).toInt()

        val sortList1 = if (mediumIndex == 1)
            Array(1) { list[0] }
//            arrayListOf(list[0])
//        else mergeSort(list.subList(0, mediumIndex))
        else mergeSort(list.copyOfRange(0, mediumIndex))


        val sortList2 = if (mediumIndex - list.size == 1)
//            arrayListOf(list[mediumIndex])
            Array(1) { list[mediumIndex] }
        else mergeSort(list.copyOfRange(mediumIndex, list.size))

        val orderList = arrayListOf<Edge>()

        var sortList1Index = 0
        var sortList2Index = 0
        while (orderList.size != (sortList1.size + sortList2.size)) {

            /**
             * 空の確認
             */
            if (sortList2.size == sortList2Index) {
                orderList.add(sortList1[sortList1Index])
                sortList1Index++
                continue
            } else if (sortList1.size == sortList1Index) {
                orderList.add(sortList2[sortList2Index])
                sortList2Index++
                continue
            }

            /**
             * 比較
             */
            if (sortList1[sortList1Index] < sortList2[sortList2Index]) {
                orderList.add(sortList1[sortList1Index])
                sortList1Index++
            } else {
                orderList.add(sortList2[sortList2Index])
                sortList2Index++
            }
        }

        return orderList.toTypedArray()
    }
}


data class Node(var parent: Int? = null)

/**
 * エッジ
 */
data class Edge(val source: Int, val target: Int, val weight: Int) {
    operator fun compareTo(other: Edge): Int {
        return this.weight.compareTo(other.weight)
    }
}