#include using namespace std; struct Edge { int to; long long w; }; int N, M; vector> g; map, long long> memo; long long dfs(int A, int B) { int used = A | B; int turn = __builtin_popcount((unsigned)used); if (turn == N) return 0; auto key = make_pair(A, B); if (memo.count(key)) return memo[key]; if (turn % 2 == 0) { // Alice の手番 long long res = LLONG_MIN; for (int v = 0; v < N; ++v) { if (used >> v & 1) continue; long long gain = 0; for (auto [to, w] : g[v]) { if (A >> to & 1) gain += w; } res = max(res, gain + dfs(A | (1 << v), B)); } return memo[key] = res; } else { // Bob の手番 long long res = LLONG_MAX; for (int v = 0; v < N; ++v) { if (used >> v & 1) continue; long long gain = 0; for (auto [to, w] : g[v]) { if (B >> to & 1) gain -= w; } res = min(res, gain + dfs(A, B | (1 << v))); } return memo[key] = res; } } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); cin >> N >> M; g.resize(N); vector D(N); for (int i = 0; i < M; ++i) { int u, v; long long w; cin >> u >> v >> w; u--, v--; g[u].push_back({v, w}); g[v].push_back({u, w}); D[u] += w; D[v] += w; } if (N <= 10) { cout << dfs(0, 0) << '\n'; return 0; } // 想定解法 sort(D.begin(), D.end(), greater<>()); long long ans = 0; for (int i = 0; i < N; ++i) { if (i % 2 == 0) ans += D[i]; else ans -= D[i]; } cout << ans / 2 << '\n'; }