#include using namespace std; const int INF = 0x3f3f3f3f; int n, m; // n条顶点,m条边 int res; // 最小生成树的权值和 int cnt; // 组成最小生成树的结点数 // Kruskal用到的结构体 const int N = 100010, M = N << 1; struct Node { int a, b, w; bool const operator<(const Node &ed) const { return w < ed.w; } } edge[M]; // 并查集 int p[N]; int find(int x) { if (p[x] != x) p[x] = find(p[x]); return p[x]; } // Kruskal算法 int kruskal() { sort(edge, edge + m); for (int i = 1; i <= n; i++) p[i] = i; for (int i = 0; i < m; i++) { int a = edge[i].a, b = edge[i].b, w = edge[i].w; a = find(a), b = find(b); if (a != b) p[a] = b, res += w, cnt++; // cnt是指已经连接上边的数量 } if (cnt < n - 1) return INF; return res; } int main() { cin >> n >> m; for (int i = 0; i < m; i++) { int a, b, c; cin >> a >> b >> c; edge[i] = {a, b, c}; } int t = kruskal(); if (t == INF) puts("impossible"); else printf("%d\n", t); return 0; }