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

#include <functional>
#include <type_traits>
#include <bits/stdc++.h>

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace std;
using namespace __gnu_pbds;

template <typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;








// #define ASC
// #pragma GCC optimize("Ofast")
// #pragma GCC target("avx,avx2,fma")
#define int long long


#define all(X) (X).begin(), (X).end()
#define reset(X) memset(X, 0, sizeof(X))

#define pb push_back
#define endl '\n'
#define fi first
#define se second

bool flag_last_endl;

const int mod = 1e9 + 7;
// const int mod=998'244'353;


// const int &MOD = mod;

const int INF = 4e18 + 10;
// const int INF=1e9+10;


#define readv(x, n)   \
    vector<int> x(n); \
    for (auto &i : x) \
        cin >> i;

#define rep(i, x,y) for(int i = x;i<y;i++)



std::ostream& operator << (std::ostream& stream, const std::string& str)
    {
    stream << str.c_str();
    return stream;
    }

std::wostream& operator << (std::wostream& stream, const std::wstring& str)
    {
    stream << str.c_str();
    return stream;
    }

template <template <typename... Args> class ContainerT, typename... Args>
std::ostream& operator << (std::ostream& stream, const ContainerT <Args...> & container)
    {
    for (auto&& elem : container){

         cout<<" ";
         stream << elem;


       }
    stream<<endl;
    return stream;
    }

template <template <typename T, size_t N, typename... Args> class ContainerT, typename T, size_t N, typename... Args>
std::ostream& operator << (std::ostream& stream, const ContainerT <T, N, Args...> & container)
    {
    for (auto&& elem : container){

        cout<<" ";
         stream << elem;


       }
    stream<<endl;
    return stream;
    }

template<typename T1, typename T2>
std::ostream& operator << (std::ostream& stream, const std::pair <T1, T2> & val)
    {
    stream << val.first << " " << val.second ;
    stream<<endl;
    return stream;
    }


template <typename T>
    using v = vector<T>;

template <typename T>
    using vv = vector<vector<T>>;

typedef vector<int> vi;
typedef vector<double> vd;
typedef vector<vector<int>> vvi;
typedef vector<vector<double>> vvd;


typedef pair<int, int> pii;

template <typename T1, typename T2>
bool sort_by_sec(pair<T1, T2> a, pair<T1, T2> b)
{
    return make_pair(a.se, a.fi) < make_pair(b.se, b.fi);
}



int multiply(int a, int b, int in_mod) { return (int)(1LL * a * b % in_mod); }
int mult_identity(int a) { return 1; }

template<typename T>
array<T, 2> multiply(const array<T, 2> &a, const array<T, 2> &b, int mod);
template<typename T>
array<T, 2> mult_identity(array<T, 2> a) { return {1}; }

const double PI = acosl(-1);





template<typename T>
T power(T a, int b, int in_mod)
{

    T prod = mult_identity(a);
    T mult = a % in_mod;
    while (b != 0)
    {
        if (b % 2)
        {
            prod = multiply(prod, mult, in_mod);
        }
        mult = multiply(mult, mult, in_mod);
        b /= 2;
    }
    return prod;
}
int mod_inv(int q, int in_mod)
{

    return power(q, in_mod - 2, in_mod);
}

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
#define stp cout << fixed << setprecision(15);



// -----------------------------|||||||||||||----------------------------------




const int maxn =2e5 + 100;
vv<pair<int, int>> adj(maxn);

vi parent(maxn);
vi sz(maxn);
vi comp(maxn);

void build()
{
    for(int i= 0;i<maxn;i++)
    {
        parent[i] = i;
        sz[i] =1 ;
        comp[i] = 0;
    }
}

int fp(int x)
{
    if( x== parent[x])
        return x;
    return parent[x] = fp(parent[x]);
}


void merge(int a, int b)
{
    a = fp(a);
    b = fp(b);
    if(a!=b)
    {
        if(sz[a]<sz[b])
            swap(a,b);
        parent[b] = a;
        sz[a] += sz[b];
    }
}


template <typename T>
vector<int> coordinate_compress(vector<T> a)
{
    set<T> s;
    for (T elem : a)
        s.insert(elem);

    vector<T> temp;
    for (T elem : s)
        temp.push_back(elem);
    map<T, int> counter;
    for (int i = 0; i < temp.size(); i++)
        counter[temp[i]] = i;
    vector<int> to_return;
    for (T elem : a)
        to_return.push_back(counter[elem]);
    return to_return;
}


#define parent par
#define rank rank_lubba
vector<int> parent, rank;

void make_set(int v) {
    parent[v] = v;
    rank[v] = 0;
}

int find_set(int v) {
    if (v == parent[v])
        return v;
    return parent[v] = find_set(parent[v]);
}

void union_sets(int a, int b) {
    a = find_set(a);
    b = find_set(b);
    if (a != b) {
        if (rank[a] < rank[b])
            swap(a, b);
        parent[b] = a;
        if (rank[a] == rank[b])
            rank[a]++;
    }
}

struct Edge {
    int u, v, weight;
    bool operator<(Edge const& other) {
        return weight < other.weight;
    }
};

#undef parent
void solve()
{
    int n, m;
    cin>>n>>m;

    build();
    int x= 0;

    vector<array<int, 3>> kappa;

    for(int i= 0;i<m;i++)
    {
        int u, v, w;
        cin>>u>>v>>w;
        adj[u].pb({v,w});
        adj[v].pb({u,w});
        x^=w;
        kappa.pb({u, v, w});
    }

    vi biggies;
    vi smallies;

    for(int i=1 ;i<=n;i++)
    {
        if(2*adj[i].size() >n)
            biggies.pb(i);
        else
        {
            smallies.pb(i);
        }
    }

    for(auto i:smallies)
    {
       set<int> a;

       for(auto j:adj[i])
       {
          a.insert(j.fi);
       }

       for(int j=1;j<=n;j++)
       {
           if(j == i)
           {

                continue;


           }

           if(a.find(j) == a.end())
           {
               merge(i,j);
           }
       }

    }

    for(int i= 1;i<biggies.size();i++)
    {
        merge(biggies[i-1], biggies[i]);
    }

    vvi art(maxn);
    for(int i= 1;i<=n;i++)
    {
        art[fp(i)].pb(i);
    }


    int mx = 0;
    for(int i= 1;i<=n;i++)
        mx = max(mx,(int) art[i].size());


    vi edge_cnt(maxn);


    for(auto i:kappa)
    {
        int v = fp(i[1]);
        int u = fp(i[0]);
        if( u == v)
            edge_cnt[u]++;
    }

    #define parent par
    vector<Edge> edges;

    int cost = 0;
    vector<Edge> result;
    parent.resize(n + 1);
    rank.resize(n + 1);
    for (int i = 1; i <= n; i++)
        make_set(i);


    for(auto i:kappa)
    {
        edges.pb({fp(i[0]), fp(i[1]), i[2]});
    }



    sort(edges.begin(), edges.end());

    for (Edge e : edges) {
        if (find_set(e.u) != find_set(e.v)) {
            cost += e.weight;
            result.push_back(e);
            union_sets(e.u, e.v);
        }
    }

    bool flag = false;
    for(int i= 1;i<=n;i++)
    {
        if(fp(i) == i)
        {
            int cmp = art[i].size();
            int free_edges = (cmp *(cmp-1))/2 - (cmp - 1) - edge_cnt[i];
            if(free_edges>0)
                flag = true;
        }
    }

    if(!flag)
        cost+=x;

    cout<<cost<<endl;










}


// -----------------------------|||||||||||||----------------------------------



signed main()
{

    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cerr.tie(NULL);

#ifndef ONLINE_JUDGE
    if (fopen("INPUT.txt", "r"))
    {
        freopen("INPUT.txt", "r", stdin);
        freopen("OUTPUT.txt", "w", stdout);
    }
#else
    #ifdef ASC

        namespace fs = std::filesystem;
        std::string path = "./";

        string filename;
        for (const auto & entry : fs::directory_iterator(path))
        {
            if( entry.path().extension().string() == ".in")
            {
                filename = entry.path().filename().stem().string();

            }

        }
        if(filename != "")
        {

            string input_file = filename +".in";
            string output_file = filename +".out";
            if (fopen(input_file.c_str(), "r"))
            {
                freopen(input_file.c_str(), "r", stdin);
                freopen(output_file.c_str(), "w", stdout);
            }
        }


    #endif

#endif
    auto clk = clock();
    // -------------------------------------Code starts here---------------------------------------------------------------------

    signed t = 1;
    // cin >> t;
//
    for (signed test = 1; test <= t; test++)
    {
        // cout<<"Case #"<<test<<": ";
        // cout<<endl;

        solve();
    }

    // -------------------------------------Code ends here------------------------------------------------------------------

    clk = clock() - clk;
    cerr << fixed << setprecision(6) << "\nTime: " << ((float)clk) / CLOCKS_PER_SEC << "\n";
    return 0;
}
