/**
 *
 */
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)
        }

        
        private fun getRootNodeIndex(id: Int, previewId: Int? = null): Int {
            if (nodeList[id].parent == null) {
                return id
            }
            
            if (previewId != null) {
                // 改良
                nodeList[previewId].parent = nodeList[id].parent
            }

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

}

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) : Comparable<Edge> {
    override operator fun compareTo(other: Edge): Int {
        return this.weight.compareTo(other.weight)
    }
}


Measured memory_bytes: 96108