2 0
 6 8
1 4 1
1 5 1
1 6 1
2 4 1
2 5 1
2 6 1
3 5 1
3 6 1
 6 12
1 3 8763000
1 4 8763000
1 5 8763000
1 6 8763000
2 3 8763000
2 4 1
2 5 8763000
2 6 1
3 5 8763000
3 6 8763000
4 5 8763000
4 6 2

0
 0
 8763002

import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.PriorityQueue;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.AbstractCollection;
import java.util.StringTokenizer;
import java.io.BufferedReader;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        FastScanner in = new FastScanner(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskC solver = new TaskC();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskC {
        public void solve(int testNumber, FastScanner in, PrintWriter out) {
            int n = in.nextInt();
            int m = in.nextInt();
            Graph g = new Graph(n);
            int xor = 0;
            int[] edgeA = new int[m];
            int[] edgeB = new int[m];
            int[] edgeC = new int[m];
            for (int i = 0; i < m; i++) {
                int a = in.nextInt() - 1;
                int b = in.nextInt() - 1;
                int c = in.nextInt();
                g.addEdge(a, b, c);
                g.addEdge(b, a, c);
                xor ^= c;

                edgeA[i] = a;
                edgeB[i] = b;
                edgeC[i] = c;
            }

            PriorityQueue<VertexWithDeg> pqDeg = new PriorityQueue<>();
            PriorityQueue<VertexWithDist> pqDist = new PriorityQueue<>();

            int[] deg = new int[n];
            final int infinity = 1 << 30;
            int[] min = new int[n];
            Arrays.fill(min, infinity);
            int[] minAt = new int[n];
            Arrays.fill(minAt, -1);

            for (int i = 0; i < n; i++) {
                pqDeg.offer(new VertexWithDeg(i, deg[i]));
                pqDist.offer(new VertexWithDist(i, min[i]));
            }

            boolean canHide = false;
            DSU dsu = new DSU(n);
            boolean[] inMst = new boolean[n];
            long mstCost = 0;
            for (int step = 0; step < n; step++) {
                int x = -1;
                int px = -1;
                while (!pqDeg.isEmpty()) {
                    VertexWithDeg v = pqDeg.peek();
                    if (v.deg != deg[v.id]) {
                        pqDeg.poll();
                        continue;
                    }
                    if (inMst[v.id]) {
                        pqDeg.poll();
                        continue;
                    }
                    if (v.deg < step) {
                        x = v.id;
                        pqDeg.poll();
                        if (v.deg < step - 1) {
                            canHide = true;
                        }
                    }
                    break;
                }
                if (x < 0) {
                    while (!pqDist.isEmpty()) {
                        VertexWithDist v = pqDist.poll();
                        if (v.dist != min[v.id]) {
                            continue;
                        }
                        if (!inMst[v.id]) {
                            x = v.id;
                            if (step != 0) {
                                mstCost += v.dist;
                                px = minAt[x];
                            }
                            break;
                        }
                    }
                }
                if (x < 0) {
                    throw new AssertionError();
                }

                if (px >= 0) {
                    dsu.merge(x, px);
                }

                inMst[x] = true;
                for (int e = g.firstEdge[x]; e >= 0; e = g.edgeNxt[e]) {
                    int u = g.edgeDst[e];
                    ++deg[u];
                    if (min[u] > g.edgeWeight[e]) {
                        min[u] = g.edgeWeight[e];
                        minAt[u] = x;
                    }
                    pqDeg.offer(new VertexWithDeg(u, deg[u]));
                    pqDist.offer(new VertexWithDist(u, min[u]));
                }
            }

            if (canHide) {
                out.println(mstCost);
                return;
            }

            int extra = xor;
            for (int e = 0; e < m; e++) {
                if (dsu.findComp(edgeA[e]) != dsu.findComp(edgeB[e])) {
                    extra = Math.min(extra, edgeC[e]);
                }
            }

            out.println(mstCost + extra);
        }

        class VertexWithDeg implements Comparable<VertexWithDeg> {
            int id;
            int deg;

            VertexWithDeg(int id, int deg) {
                this.id = id;
                this.deg = deg;
            }

            public int compareTo(VertexWithDeg o) {
                if (deg != o.deg) {
                    return deg < o.deg ? -1 : 1;
                }
                if (id != o.id) {
                    return id < o.id ? -1 : 1;
                }
                return 0;
            }

        }

        class VertexWithDist implements Comparable<VertexWithDist> {
            int id;
            int dist;

            VertexWithDist(int id, int dist) {
                this.id = id;
                this.dist = dist;
            }

            public int compareTo(VertexWithDist o) {
                if (dist != o.dist) {
                    return dist < o.dist ? -1 : 1;
                }
                if (id != o.id) {
                    return id < o.id ? -1 : 1;
                }
                return 0;
            }

        }

        class Graph {
            int[] firstEdge;
            int[] edgeNxt;
            int[] edgeDst;
            int[] edgeWeight;
            int numEdges;
            int n;

            Graph(int n) {
                this.n = n;
                firstEdge = new int[n];
                Arrays.fill(firstEdge, -1);
                final int initialCapacity = 10;
                edgeNxt = new int[initialCapacity];
                edgeDst = new int[initialCapacity];
                edgeWeight = new int[initialCapacity];
                numEdges = 0;
            }

            void addEdge(int a, int b, int c) {
                int e = numEdges++;
                if (e >= edgeNxt.length) {
                    reallocate();
                }
                edgeNxt[e] = firstEdge[a];
                edgeDst[e] = b;
                edgeWeight[e] = c;
                firstEdge[a] = e;
            }

            void reallocate() {
                int k = edgeNxt.length;
                k = 3 * k / 2;
                edgeNxt = Arrays.copyOf(edgeNxt, k);
                edgeDst = Arrays.copyOf(edgeDst, k);
                edgeWeight = Arrays.copyOf(edgeWeight, k);
            }

        }

        class DSU {
            int[] f;
            int numComps;

            DSU(int n) {
                f = new int[n];
                for (int i = 0; i < f.length; i++) {
                    f[i] = i;
                }
                numComps = f.length;
            }

            int findComp(int x) {
                int r;
                int saved;

                saved = x;
                while (x != f[x]) {
                    x = f[x];
                }
                r = x;

                x = saved;
                while (x != r) {
                    saved = f[x];
                    f[x] = r;
                    x = saved;
                }
                return r;
            }

            void merge(int p0, int q0) {
                int p1 = f[p0];
                int q1 = f[q0];
                while (p1 != q1) {
                    if (p1 > q1) {
                        if (p0 == p1) {
                            --numComps;
                        }
                        f[p0] = q1;
                        p0 = p1;
                        p1 = f[p1];
                    } else {
                        if (q0 == q1) {
                            --numComps;
                        }
                        f[q0] = p1;
                        q0 = q1;
                        q1 = f[q1];
                    }
                }
            }

        }

    }

    static class FastScanner {
        private BufferedReader in;
        private StringTokenizer st;

        public FastScanner(InputStream stream) {
            in = new BufferedReader(new InputStreamReader(stream));
        }

        public String next() {
            while (st == null || !st.hasMoreTokens()) {
                try {
                    String rl = in.readLine();
                    if (rl == null) {
                        return null;
                    }
                    st = new StringTokenizer(rl);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return st.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

    }
}

