Problem:
Flipping Colors
You are given an undirected complete graph.
Every pair of the nodes in the graph is connected by an edge,
colored either red or black.
Each edge is associated with an integer value called
penalty.
By repeating certain operations on the given graph,
a “spanning tree” should be formed with only the red edges.
That is, the number of red edges should be made exactly one less than
the number of nodes, and all the nodes should be made connected
only via red edges, directly or indirectly.
If two or more such trees can be formed,
one with the least sum of penalties of red edges should be chosen.
In a single operation step, you choose one of the nodes and flip the colors
of
all
the edges connected to it:
Red ones will turn to black, and black ones to red.
Fig. F-1 The first dataset of Sample Input and its solution
For example, the leftmost graph of Fig. F-1 illustrates the first
dataset of Sample Input.
By flipping the colors of all the edges connected to the node 3, and
then flipping all the edges connected to the node 2,
you can form a spanning tree made of red edges as shown in the
rightmost graph of the figure.
Input
The input consists of multiple datasets, each in the following format.
n
e
1,2
e
1,3
...
e
1,
n
-1
e
1,
n
e
2,3
e
2,4
...
e
2,
n
...
e
n
-1,
n
The integer
n
(2 ≤
n
≤ 300) is the number of nodes.
The nodes are numbered from 1 to
n
.
The integer
e
i
,
k
(1 ≤ |
e
i
,
k
| ≤ 10
5
)
denotes the penalty and the initial color of the edge between the node
i
and the node
k
.
Its absolute value |
e
i
,
k
| represents the penalty of the edge.
e
i
,
k
> 0 means that the edge is initially red,
and
e
i
,
k
< 0 means it is black.
The end of the input is indicated by a line containing a zero.
The number of datasets does not exceed 50.
Output
For each dataset, print the sum of edge penalties of the red spanning tree
with the least sum of edge penalties obtained by the above-described operations.
If a red spanning tree can never be made by such operations, print
-1
.
Sample Input
4
3 3 1
2 6
-4
3
1 -10
100
5
-2 -2 -2 -2
-1 -1 -1
-1 -1
1
4
-4 7 6
2 3
-1
0
Output for the Sample Input
7
11
-1
9

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
using namespace std;

typedef long long ll;
#define REP(i,n) for(int i=0,_n=(int)(n);i<_n;++i)
#define ALL(v) (v).begin(),(v).end()
#define CLR(t,v) memset(t,(v),sizeof(t))
template<class T1,class T2>ostream& operator<<(ostream& os,const pair<T1,T2>&a){return os<<"("<<a.first<<","<<a.second<< ")";}
template<class T>void pv(T a,T b){for(T i=a;i!=b;++i)cout<<(*i)<<" ";cout<<endl;}
template<class T>void chmin(T&a,const T&b){if(a>b)a=b;}
template<class T>void chmax(T&a,const T&b){if(a<b)a=b;}


int nextInt() { int x; scanf("%d", &x); return x;}
ll nextLong() { ll x; scanf("%lld", &x); return x;}

const int MAX_N = 305;

vector<int> g[MAX_N];
int e[MAX_N][MAX_N];
int flip[MAX_N];
bool vis[MAX_N];

int ans = 1001001001;
int dfs(int N, int b, int cur, int prev, int &cost) {
    if (cost > ans) { throw -1; }
    if (vis[cur]) { throw -1; }
    vis[cur] = true;
    int res = 1;
    
    if (cur == b) {
        REP(nxt, N) if (nxt != prev && e[cur][nxt] * flip[cur] * flip[nxt] > 0) {
            cost += abs(e[cur][nxt]);
            res += dfs(N, b, nxt, cur, cost);
        }
    } else {
        
        {
            int nxt = b;
            if (nxt != prev && e[cur][nxt] * flip[cur] * flip[nxt] > 0) {
                cost += abs(e[cur][nxt]);
                res += dfs(N, b, nxt, cur, cost);
            }
        }
        for(int nxt : g[cur]) if (nxt != prev && nxt != b && e[cur][nxt] * flip[cur] * flip[nxt] > 0) {
            cost += abs(e[cur][nxt]);
            res += dfs(N, b, nxt, cur, cost);
        }
        
    }
    return res;
}

int main2(int N) {
    CLR(e, 0);
    ans = 1001001001;
    for (int i = 0; i < N; i++) {
        for (int j = i + 1; j < N; j++) {
            e[i][j] = e[j][i] = nextInt();
        }
    }
    for (int a = 0; a < N; a++) {
        REP(i, N) g[i].clear();
        REP(i, N) flip[i] = 1;
        for (int x = 0; x < N; x++){
            if (x != a) {
                if (e[a][x] > 0) flip[x] = -1;
            }
        }
        REP(i, N) {
            vector<int> v;
            REP(j, N) if (e[i][j] * flip[i] * flip[j] > 0) v.push_back(j);
            g[i] = v;
        }
        
        for (int b = 0; b < N; b++) if (a != b) {
            flip[b] *= -1;
            try {
                CLR(vis, 0);
                int cost = 0;
                int c = dfs(N, b, 0, -1, cost);
                if (c == N) {
                    if (ans > cost) {
                        ans = cost;
                    }
                }
            } catch (int e) {}
            flip[b] *= -1;
        }
    }
    if (ans == 1001001001) cout << -1 << endl;
    else cout << ans << endl;
    return 0;
}

int main() {
    for (;;) {
        int N = nextInt();
        if (N == 0) break;
        main2(N);
    }
    return 0;
}
accuracy: 1
time_ms: 2970
memory_kb: 4164
final_rank: 15

code_snippet: #include <bits/stdc++.h>
using namespace std;
bool solve();

using ll = long long;
#define rep(i, a, b) for (int i = a; i < (b); ++i)
#define sz(x) (int)(x).size()
#define all(x) x.begin(), x.end()
typedef pair<int, int> pii;
typedef vector<int> vi;
template <class T>
inline bool chmin(T &a, T b) {
  return ((a > b) ? (a = b, 1) : (0));
}
template <class T>
inline bool chmax(T &a, T b) {
  return ((a < b) ? (a = b, 1) : (0));
}

int main() {
  while (solve());
  return 0;
}

struct UF {
	vi e;
	UF(int n) : e(n, -1) {}
	bool sameSet(int a, int b) { return find(a) == find(b); }
	int size(int x) { return -e[find(x)]; }
	int find(int x) { return e[x] < 0 ? x : e[x] = find(e[x]); }
	bool join(int a, int b) {
		a = find(a), b = find(b);
		if (a == b) return false;
		if (e[a] > e[b]) swap(a, b);
		e[a] += e[b]; e[b] = a;
		return true;
	}
};


bool solve() {
  int N;cin>>N;
  if (N==0) return 0;
  vector e(N,vi(N));

  rep(i,0,N){
    rep(j,i+1,N){
      cin>>e[i][j];
      e[j][i]=e[i][j];
    }
  }

  const int inf = 1001001001;

  int ans = inf;
  rep(a,0,N){
    //aからの辺をすべて黒にする
    vector<vi>G(N);
    {
      vi v(N,0);
      rep(i,0,N)if(e[i][a]>0)v[i]=1;      
      rep(i,0,N)if(v[i]){
        rep(j,0,N){
          if(i==j)continue;
            e[i][j]=e[j][i]=-e[i][j];
          }
        }
        rep(i,0,N)rep(j,i+1,N)
          if(e[i][j]>0)G[i].push_back(j);
    }

    rep(b,0,N){
      if(b==a)continue;
      //aにはbへの赤辺が一つだけあるとする
      UF uf(N);
      bool ng=false;
      int ret = 0;
      rep(i,0,N){
        if(i==b)continue;
        for(int j:G[i]){
          if(j==b)continue;
          assert(e[i][j]>0);
          if(!uf.join(i,j))ng=true;
          ret+=e[i][j];
          if(ng)break;
        }
        if(ng)break;
      }
      rep(i,0,N){
        if(ng)break;
        if(e[i][b]<0){
          if(!uf.join(i,b))ng=true;
          ret+=-e[i][b];
        }
      }
      if(uf.size(0)!=N)ng=true;
      if(!ng)ans=min(ans,ret);
    }
  }
  if(ans>=inf)ans=-1;
  cout<<ans<<endl;
  return 1;
}
accuracy: 1
time_ms: 810
memory_kb: 4224
final_rank: 4

code_snippet: #include<bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i, a, b) for(ll i = a; i < (b); i++)
#define all(a) (a).begin(), (a).end()
#ifndef ATCODER_DSU_HPP
#define ATCODER_DSU_HPP 1

#include <algorithm>
#include <cassert>
#include <vector>

namespace atcoder {

// Implement (union by size) + (path compression)
// Reference:
// Zvi Galil and Giuseppe F. Italiano,
// Data structures and algorithms for disjoint set union problems
struct dsu {
  public:
    dsu() : _n(0) {}
    explicit dsu(int n) : _n(n), parent_or_size(n, -1) {}

    int merge(int a, int b) {
        assert(0 <= a && a < _n);
        assert(0 <= b && b < _n);
        int x = leader(a), y = leader(b);
        if (x == y) return x;
        if (-parent_or_size[x] < -parent_or_size[y]) std::swap(x, y);
        parent_or_size[x] += parent_or_size[y];
        parent_or_size[y] = x;
        return x;
    }

    bool same(int a, int b) {
        assert(0 <= a && a < _n);
        assert(0 <= b && b < _n);
        return leader(a) == leader(b);
    }

    int leader(int a) {
        assert(0 <= a && a < _n);
        if (parent_or_size[a] < 0) return a;
        return parent_or_size[a] = leader(parent_or_size[a]);
    }

    int size(int a) {
        assert(0 <= a && a < _n);
        return -parent_or_size[leader(a)];
    }

    std::vector<std::vector<int>> groups() {
        std::vector<int> leader_buf(_n), group_size(_n);
        for (int i = 0; i < _n; i++) {
            leader_buf[i] = leader(i);
            group_size[leader_buf[i]]++;
        }
        std::vector<std::vector<int>> result(_n);
        for (int i = 0; i < _n; i++) {
            result[i].reserve(group_size[i]);
        }
        for (int i = 0; i < _n; i++) {
            result[leader_buf[i]].push_back(i);
        }
        result.erase(
            std::remove_if(result.begin(), result.end(),
                           [&](const std::vector<int>& v) { return v.empty(); }),
            result.end());
        return result;
    }

  private:
    int _n;
    // root node: -1 * component size
    // otherwise: parent
    std::vector<int> parent_or_size;
};

}  // namespace atcoder

#endif  // ATCODER_DSU_HPP
using namespace atcoder;
int main(){
    while(true){
    ll n;
    cin>>n;
    if(n==0)break;
    vector<vector<ll>> z(n,vector<ll>(n));
    rep(i,0,n){
        rep(j,i+1,n){
            ll a;
            cin>>a;
            z[i][j]=a;
            z[j][i]=a;
        }
    }
    ll ans=1000000000000000000;
    rep(i,0,n){
        ll a=0;
        rep(j,0,n){
            if(z[i][j]>0){
                rep(k,0,n){
                    z[j][k]*=-1;
                    z[k][j]*=-1;
                }
            }
        }
        vector<ll> d;
        vector<ll> e;
        rep(j,0,n){
            rep(k,0,j){
                if(z[j][k]>0)a++;
            }
        }
        if(a>2*n)continue;
        rep(j,0,n){
            rep(k,0,j){
                if(z[j][k]>0){
                    d.push_back(j);
                    e.push_back(k);
                }
            }
        }
        rep(j,0,n){
            ll p=0;
            if(i==j)continue;
            dsu dd(n);
            ll pp=0;
            ll zans=0;
            rep(k,0,d.size()){
                if(d[k]!=j&&e[k]!=j){
                    if(dd.same(d[k],e[k])){
                        p=1;
                        break;

                    }
                    pp++;
                    zans+=z[d[k]][e[k]];
                    dd.merge(d[k],e[k]);
                }
            }
            if(p==1)continue;
            rep(k,0,n){
                if(z[j][k]<0){
                    if(dd.same(j,k)){
                        p=1;
                        break;

                    }
                    pp++;
                    zans+=-z[j][k];
                    dd.merge(j,k);
                }
            }
            if(p==1)continue;
            if(pp!=n-1)continue;
            ans=min(ans,zans);
        }

    }
        if(ans==1000000000000000000)cout<<-1<<endl;
        else cout<<ans<<endl;

    
}
}
accuracy: 1
time_ms: 550
memory_kb: 4224
final_rank: 3

code_snippet: /**
	author:  shobonvip
	created: 2025.05.20 17:48:50
**/

#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#include<bits/stdc++.h>
using namespace std;
/* BOOST MULTIPRECISION
#include<boost/multiprecision/cpp_int.hpp>
using namespace boost::multiprecision;
//*/

typedef long long ll;

#define rep(i, s, n) for (int i = (int)(s); i < (int)(n); i++)
#define rrep(i, s, n) for (int i = (int)(n)-1; i >= (int)(s); i--)
#define all(v) v.begin(), v.end()

template <typename T> bool chmin(T &a, const T &b) {
	if (a <= b) return false;
	a = b;
	return true;
}

template <typename T> bool chmax(T &a, const T &b) {
	if (a >= b) return false;
	a = b;
	return true;
}

template <typename T> T max(vector<T> &a){
	assert(!a.empty());
	T ret = a[0];
	for (int i=0; i<(int)a.size(); i++) chmax(ret, a[i]);
	return ret;
}

template <typename T> T min(vector<T> &a){
	assert(!a.empty());
	T ret = a[0];
	for (int i=0; i<(int)a.size(); i++) chmin(ret, a[i]);
	return ret;
}

template <typename T> T sum(vector<T> &a){
	T ret = 0;
	for (int i=0; i<(int)a.size(); i++) ret += a[i];
	return ret;
}

typedef bitset<305> B;

void solve(int n) {
	vector<vector<ll>> e(n, vector<ll>(n));
	rep(i,0,n) {
		rep(j,i+1,n) {
			cin >> e[i][j];
			e[j][i] = e[i][j];
		}
	}

	int ans = 2e9;

	rep(st,0,n) {
		for (int stdat: {-1, 1}) {
			vector<int> dat(n);
			dat[st] = stdat;
			ll x = stdat;
			int edge_number = 0;
			rep(i,0,n) {
				if (i == st) {
					continue;
				}
				int y = x * e[st][i];
				if (y < 0) {
					dat[i] = 1;
				}else{
					dat[i] = -1;
				}
			}

			int tmp=0;
			vector<B> edges(n);
			rep(i,0,n) {
				rep(j,i+1,n){
					if (dat[i] * dat[j] * e[i][j] > 0) {
						edge_number++;
						edges[i][j] = 1;
						edges[j][i] = 1;
						tmp += abs(e[i][j]);
					}
				}
			}
			
			rep(nx,0,n) {
				if (nx == st) continue;
				rep(j,0,n) {
					if (nx==j) continue;
					if (edges[nx][j]) {
						edges[nx][j] = 0;
						edges[j][nx] = 0;
						tmp -= abs(e[nx][j]);
						edge_number--;
					}else{
						edges[nx][j] = 1;
						edges[j][nx] = 1;
						tmp += abs(e[nx][j]);
						edge_number++;
					}
				}

				if (edge_number == n-1) {
					vector<bool> tansaku(n);
					vector<int> mada;
					mada.push_back(st);
					int seen = 0;
					tansaku[st] = 1;
					while(!mada.empty()) {
						int i = mada.back();
						mada.pop_back();
						seen++;
						int j=-1;
						while(j<n){
							j=edges[i]._Find_next(j);
							if(j>=n)break;
							if(tansaku[j])continue;
							tansaku[j] = 1;
							mada.push_back(j);
						}
						
						/*
						rep(j,0,n) {
							if (edges[i][j] && !tansaku[j]) {
								tansaku[j] = 1;
								tmp += abs(e[i][j]);
								mada.push_back(j);
							}
						}
							*/
							
					}

					if (seen == n) {
						chmin(ans, tmp);
					}
				}

				rep(j,0,n) {
					if (nx == j) continue;
					if (edges[nx][j]) {
						edges[nx][j] = 0;
						edges[j][nx] = 0;
						tmp -= abs(e[nx][j]);
						edge_number--;
					}else{
						edges[nx][j] = 1;
						edges[j][nx] = 1;
						tmp += abs(e[nx][j]);
						edge_number++;
					}
				}
			}
		}
	}

	if (ans==(int)2e9){
		cout<<-1<<endl;
	}else{
		cout << ans << endl;
	}
}

int main(){
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	
	while(1) {
		int n; cin >> n;
		if (n == 0) {
			break;
		}

		solve(n);
	}
}
accuracy: 1
time_ms: 4150
memory_kb: 3812
final_rank: 19

code_snippet: // AOJ #1637 Flipping Colors
// // 2025.5.1

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;

#define gc() getchar_unlocked()
#define pc(c) putchar_unlocked(c)

int Cin() {
	int n = 0; int c = gc();
	if (c == '-') {	c = gc();
		do n = 10*n + (c & 0xf), c = gc(); while (c >= '0');
		return -n;
	}
	do n = 10*n + (c & 0xf), c = gc(); while (c >= '0');
	return n;
}

void Cout(ll n) {
	char b[30];
	if (!n) pc('0');
	else {
		if (n < 0) pc('-'), n = -n;
		int i = 0; while (n) b[i++] = n % 10 + '0', n /= 10;
		while (i--) pc(b[i]);
	}
	pc('\n');
}

const ll INF = (ll)1e18;
const int NMAX = 300;
const int B = 64;
const int S = (NMAX + B - 1) / B;

ull c[NMAX][S];
ull g[NMAX][S];
ull ma[S];
int wgt[NMAX][NMAX];
int parent_[NMAX], rnk_[NMAX];

inline int findp(int x) {
    return parent_[x] == x ? x : parent_[x] = findp(parent_[x]);
}
inline bool unite(int a, int b) {
    a = findp(a); b = findp(b);
    if (a == b) return false;
    if (rnk_[a] < rnk_[b]) swap(a, b);
    parent_[b] = a;
    if (rnk_[a] == rnk_[b]) rnk_[a]++;
    return true;
}

int main() {
    for (int u = 0; u < NMAX; u++) {
        for (int s = 0; s < S; s++) {
            ull m = 0;
            int base = s * B;
            for (int b = 0; b < B; b++) {
                int v = base + b;
                if (v > u && v < NMAX) m |= 1ULL << b;
            }
            g[u][s] = m;
            ma[s] = ~0ULL;
        }
    }

    while (true) {
        int n = Cin();
        if (n == 0) break;

        {
            int rem = n % B;
            for (int s = 0; s < S; s++) {
                if (s < n / B) {
                    ma[s] = ~0ULL;
                } else if (s == n / B) {
                    ma[s] = rem ? ((1ULL << rem) - 1) : ~0ULL;
                } else {
                    ma[s] = 0ULL;
                }
            }
            for (int u = 0; u < n; u++) {
                for (int s = 0; s < S; s++) {
                    ull m = 0ULL;
                    int base = s * B;
                    for (int b = 0; b < B; b++) {
                        int v = base + b;
                        if (v > u && v < n) m |= 1ULL << b;
                    }
                    g[u][s] = m;
                }
            }
        }

        for (int u = 0; u < n; u++) {
            for (int s = 0; s < S; s++) c[u][s] = 0;
            for (int v = 0; v < n; v++) wgt[u][v] = 0;
        }
        for (int i = 0; i < n; i++) {
            for (int j = i + 1, e; j < n; j++) {
                e = Cin();
                if (e > 0) {
                    c[i][j / B] |= 1ULL << (j % B);
                    c[j][i / B] |= 1ULL << (i % B);
                }
                wgt[i][j] = wgt[j][i] = abs(e);
            }
        }

        ll best = INF;
        static ull f0[S], fmask[S], fflip[S];

        for (int a = 0; a < n; a++) {
            memcpy(f0, c[a], sizeof(f0));
            int sa = a / B, ba = a % B;
            f0[sa] &= ~(1ULL << ba);

            for (int b = 0; b < n; b++) {
                if (b == a) continue;
                memcpy(fmask, f0, sizeof(f0));
                int sb = b / B, bb = b % B;
                bool fb = (c[a][sb] >> bb) & 1ULL;
                if (fb) fmask[sb] &= ~(1ULL << bb);
                else    fmask[sb] |=  (1ULL << bb);
                for (int s = 0; s < S; s++) fflip[s] = (~fmask[s]) & ma[s];

                int cnt = 0;
                for (int u = 0; u < n && cnt <= n - 1; u++) {
                    int su = u / B, bu = u % B;
                    bool fu = (fmask[su] >> bu) & 1ULL;
                    for (int s = 0; s < S; s++) {
                        ull cm = c[u][s];
                        ull fmw = fu ? fflip[s] : fmask[s];
                        ull fin = (cm ^ fmw) & g[u][s];
                        cnt += __builtin_popcountll(fin);
                    }
                }
                if (cnt != n - 1) continue;

                for (int i = 0; i < n; i++) {
                    parent_[i] = i;
                    rnk_[i] = 0;
                }
                int comps = n;
                ll sum = 0;
                for (int u = 0; u < n; u++) {
                    int su = u / B, bu = u % B;
                    bool fu = (fmask[su] >> bu) & 1ULL;
                    for (int s = 0; s < S; s++) {
                        ull cm = c[u][s];
                        ull fmw = fu ? fflip[s] : fmask[s];
                        ull fin = (cm ^ fmw) & g[u][s];
                        while (fin) {
                            ull lb = fin & -fin;
                            int b2 = __builtin_ctzll(fin);
                            fin ^= lb;
                            int v = s * B + b2;
                            sum += wgt[u][v];
                            if (unite(u, v)) comps--;
                        }
                    }
                }
                if (comps == 1) best = min(best, sum);
            }
        }
        Cout(best == INF? -1: best);
    }
    return 0;
}
accuracy: 1
time_ms: 3350
memory_kb: 3752
final_rank: 16

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef vector<ll> vi;
typedef vector<vi> vvi;
typedef vector<vvi> vvvi;
typedef vector<bool> vb;
typedef vector<vb> vvb;
typedef vector<vvb> vvvb;
typedef vector<vvvb> vvvvb;
typedef pair<ll,ll> pi;
typedef pair<ll,pi> ppi;
#define FOR(i,l,r) for(ll i=l;i<r;i++)
#define REP(i,n) FOR(i,0,n)
#define RFOR(i,l,r) for(ll i=r-1;i>=l;i--)
#define RREP(i,n) RFOR(i,0,n)
#define sz(A) (ll)(A.size())
#define ALL(A) A.begin(),A.end()
#define LB(A,x) (ll)(lower_bound(ALL(A),x)-A.begin())
#define UB(A,x) (ll)(upper_bound(ALL(A),x)-A.begin())
#define COU(A,x) (UB(A,x)-LB(A,x))
#define F first
#define S second
template<typename T>using min_priority_queue=priority_queue<T,vector<T>,greater<T>>;
template<typename T1,typename T2>ostream&operator<<(ostream&os,pair<T1,T2>&p){os<<p.F<<" "<<p.S;return os;}
template<typename T1,typename T2>istream&operator>>(istream&is,pair<T1,T2>&p){is>>p.F>>p.S;return is;}
template<typename T>ostream&operator<<(ostream&os,vector<T>&v){REP(i,sz(v))os<<v[i]<<(i+1!=sz(v)?" ":"");return os;}
template<typename T>istream&operator>>(istream&is,vector<T>&v){for(T&in:v)is>>in;return is;}
template<class T>bool chmax(T&a,T b){if(a<b){a=b;return 1;}return 0;}
template<class T>bool chmin(T&a,T b){if(b<a){a=b;return 1;}return 0;}
const ll mod=998244353;
template<const long long int mod=998244353>
struct modint{
  using mint=modint<mod>;
  long long int x;
  modint(long long int _x=0):x(_x%mod){if(x<0)x+=mod;}
  long long int val(){return x;}
  mint&operator=(const mint&a){x=a.x;return *this;}
  mint&operator+=(const mint&a){x+=a.x;if(x>=mod)x-=mod;return *this;}
  mint&operator-=(const mint&a){x-=a.x;if(x<0)x+=mod;return *this;}
  mint&operator*=(const mint&a){x*=a.x;x%=mod;return *this;}
  friend mint operator+(const mint&a,const mint&b){return mint(a)+=b;}
  friend mint operator-(const mint&a,const mint&b){return mint(a)-=b;}
  friend mint operator*(const mint&a,const mint&b){return mint(a)*=b;}
  mint operator-()const{return mint(0)-*this;}
  mint pow(long long int n){
    if(!n)return 1;
    mint a=1;
    mint _x=x;
    while(n){
      if(n&1)a*=_x;
      _x=_x*_x;n>>=1;
    }
    return a;
  }
  mint inv(){return pow(mod-2);}
  mint&operator/=(mint&a){return *this*=a.inv();}
  friend mint operator/(const mint&a,mint b){return mint(a)/=b;}
};
using mint=modint<998244353>;
struct dsu{
    private:
	vector<int>parent;
    public:
    dsu()=default;
	  dsu(size_t n):parent(n,-1){}
	  int leader(int i){
		    if(parent[i]<0)return i;
		    return parent[i]<0?i:(parent[i]=leader(parent[i]));
	  }
	  int merge(int a,int b){
		    a=leader(a);
		    b=leader(b);
		    if (a!=b){
			      if(-parent[a]<-parent[b])swap(a,b);
			      parent[a]+=parent[b];
			      parent[b]=a;
		    }
		    return a;
	  }
	  bool same(int a,int b){return leader(a)==leader(b);}
	  int size(int i){return -parent[leader(i)];}
	  vector<vector<int>>groups(){
	      size_t n=parent.size();
	      vector<vector<int>>A(n);
	      for(int i=0;i<n;i++)A[leader(i)].emplace_back(i);
	      vector<vector<int>>res;
	      for(auto a:A)if(a.size())res.emplace_back(a);
	      return res;
	  }
};
int main(){
    while(1){
        ll N;cin>>N;
        if(!N)return 0;
        vvi E(N,vi(N));
        REP(i,N)FOR(j,i+1,N){cin>>E[i][j];E[j][i]=E[i][j];}
        ll ans=1e18;
        REP(v,N){
          vi T(N);
          REP(i,N)if(i!=v){
            if(E[i][v]>0)T[i]=1;
            else T[i]=0;
          }
          vvi F=E;
          REP(i,N)REP(j,N)if(T[i]!=T[j])F[i][j]*=-1;
          vi D(N);
          ll cnt=0;
          vector<pi>es;
          REP(i,N)REP(j,i)if(F[i][j]>0)es.emplace_back(pi(i,j)),cnt++;
          REP(i,N)REP(j,N)if(F[i][j]>0)D[i]++;
          REP(u,N)if(u!=v&&cnt==2*D[u]){
            dsu G(N);
            for(auto[a,b]:es)if(a!=u&&b!=u)G.merge(a,b);
            REP(i,N)if(F[i][u]<0)G.merge(i,u);
            if(G.size(0)==N){
              ll ab=0;
              for(auto[a,b]:es)if(a!=u&&b!=u)ab+=F[a][b];
              REP(i,N)if(F[i][u]<0)ab-=F[i][u];
              chmin(ans,ab);
            }
          }
        }
        if(ans>1e17)ans=-1;
        cout<<ans<<endl;
    }
    return 0;
}
accuracy: 1
time_ms: 1290
memory_kb: 5976
final_rank: 10

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (int i = 0; i < n; i++)
struct UnionFind {
    vector<int> par, siz, es;
    UnionFind(int x) {
        par.resize(x);
        siz.resize(x);
        es.resize(x);
        for (int i = 0; i < x; i++) {
            par[i] = i;
            siz[i] = 1;
            es[i] = 0;
        }
    }
    int find(int x) {
        if (par[x] == x) return x;
        return par[x] = find(par[x]);
    }
    bool unite(int x, int y) {
        x = find(x), y = find(y);
        if (x == y) {
            es[x]++;
            return false;
        }
        if (siz[x] < siz[y]) swap(x, y);
        par[y] = x;
        siz[x] += siz[y];
        es[x] += es[y] + 1;
        return true;
    }
    bool same(int x, int y) { return find(x) == find(y); }
    int size(int x) { return siz[find(x)]; }
    int edges(int x) { return es[find(x)]; }
};

void solve() {
    int n;
    cin >> n;
    if (n == 0) exit(0);
    vector<vector<int>> g(n, vector<int>(n));
    rep(i, n) {
        for (int j = i + 1; j < n; j++) {
            cin >> g[i][j];
            g[j][i] = g[i][j];
        }
    }
    int ans = INT_MAX;
    rep(s, n) {
        rep(f, 2) {
            vector<bool> flip(n);
            rep(k, n) {
                if (k == s) continue;
                flip[k] = (g[k][s] > 0);
            }
            vector<pair<int, int>> st;
            vector<vector<bool>> edge(n, vector<bool>(n));
            rep(i, n) rep(j, i) {
                edge[i][j] = edge[j][i] = (g[i][j] > 0) ^ flip[i] ^ flip[j];
                if (edge[i][j]) st.push_back({i, j});
            }

            // 全域木の条件 : n-1辺かつ連結
            rep(t, n) {
                if (s == t) continue;
                if (st.size() <= 2 * n) {
                    UnionFind uf(n);
                    int sum = 0;
                    int cnt = 0;
                    for (auto [i, j] : st) {
                        if (i == t || j == t) continue;
                        uf.unite(i, j);
                        cnt++;
                        sum += abs(g[i][j]);
                    }
                    rep(i, n) {
                        if (i != t && !edge[i][t]) {
                            uf.unite(i, t);
                            cnt++;
                            sum += abs(g[i][t]);
                        }
                    }

                    if (cnt == n - 1 && uf.size(0) == n) ans = min(ans, sum);
                }
            }

            rep(i, n) {
                if (i != s) {
                    g[i][s] = -g[i][s];
                    g[s][i] = -g[s][i];
                }
            }
        }
    }
    if (ans == INT_MAX) ans = -1;
    cout << ans << endl;
}
int main() {
    while (1) solve();
}
accuracy: 1
time_ms: 2860
memory_kb: 4252
final_rank: 14

code_snippet: #if 1
// clang-format off
#include <bits/stdc++.h>

using namespace std;
using uint = unsigned int;
using ll = long long;
using ull = unsigned long long;
using lf = long double;
using pll = pair<ll, ll>;
#define vec vector
template <class T> using v = vector<T>;
template <class T> using vv = v<v<T>>;
template <class T> using vvv = v<vv<T>>;
using vl = v<ll>;
using vvl = vv<ll>;
using vvvl = vvv<ll>;
using vpl = v<pll>;
using vs = v<string>;
using vb = v<bool>;
using vvb = v<vb>;
using vvvb = v<vvb>;
template<class T> using PQ = priority_queue<T, v<T>, greater<T>>;
constexpr ll TEN(int n) { return (n == 0) ? 1 : 10 * TEN(n - 1); }

#define FOR(i, a, b) for (ll i = (ll)(a); i < (ll)(b); i++)
#define rep(i, N) for (ll i = 0; i < (ll)(N); i++)
#define rep1(i, N) for (ll i = 1; i <= (ll)(N); i++)
#define rrep(i, N) for (ll i = N - 1; i >= 0; i--)
#define rrep1(i, N) for (ll i = N; i > 0; i--)
#define fore(i, a) for (auto &i : a)
#define fs first
#define sc second
#define eb emplace_back
#define pb push_back
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define UNIQUE(x) (x).erase(unique((x).begin(), (x).end()), (x).end());
#define YES(x) cout << ((x) ? "YES\n" : "NO\n");
#define Yes(x) cout << ((x) ? "Yes\n" : "No\n");
#define yes(x) cout << ((x) ? "yes\n" : "no\n");
template <class T, class U> void chmin(T &t, const U &u) { if (t > u) t = u; }
template <class T, class U> void chmax(T &t, const U &u) { if (t < u) t = u; }
template <class T> T min(const v<T> &lis) { return *min_element(all(lis)); }
template <class T> T max(v<T> &lis) { return *max_element(all(lis)); }
const int inf = (1 << 30);
const ll infl = (1LL << 60);
const ll mod93 = 998244353;
const ll mod17 = 1000000007;
int popcnt(uint x) { return __builtin_popcount(x); }
int popcnt(ull x) { return __builtin_popcountll(x); }
// 桁数
int bsr(uint x) { return 31 - __builtin_clz(x); }
int bsr(ull x) { return 63 - __builtin_clzll(x); }
// 2で割れる回数
int bsf(uint x) { return __builtin_ctz(x); }
int bsf(ull x) { return __builtin_ctzll(x); }

template <class T, class S> istream &operator>>(istream &is, pair<T, S> &x) { return is >> x.first >> x.second; }
template <class T, class S> ostream &operator<<(ostream &os, const pair<T, S> &x) { return os << x.first << " " << x.second; }
template <class T> istream &operator>>(istream &is, vector<T> &x) { for (auto &y : x) is >> y; return is; }
template <class T> ostream &operator<<(ostream &os, const vector<T> &x) {
  for (size_t i = 0, size = x.size(); i < size; i++)
    os << x[i] << (i == size - 1 ? "" : " ");
  return os;
}

ll rand_int(ll l, ll r) {  // [l, r]
  static random_device rd;
  static mt19937 gen(rd());
  return uniform_int_distribution<ll>(l, r)(gen);
}

// #include <boost/multiprecision/cpp_int.hpp>
// using cpp_int = boost::multiprecision::cpp_int;

// clang-format on
#endif

// #define _GLIBCXX_DEBUG
using bs = bitset<301>;
struct Solver {
  void solve(ll n) {
    // cout << "n: " << n << "\n";
    vvl g(n, vl(n));
    rep(i, n) {
      FOR(j, i + 1, n) {
        cin >> g[i][j];
        g[j][i] = g[i][j];
      }
    }

    ll ans = infl;
    bs flip;
    rep(i, n) flip[i] = 1;
    unordered_map<bs, int> mp;
    rep(leaf, n) {
      rep(par, n) {
        if (leaf == par) continue;
        bs x;
        rep(i, n) {
          if (i == leaf) continue;
          if (i == par) {
            x[i] = g[leaf][par] < 0;
          } else {
            x[i] = g[leaf][i] > 0;
          }
        }
        mp[x]++;
        mp[x ^ flip]++;
      }
    }
    v<bs> bit(n);
    rep(i, n) {
      rep(j, n) {
        if (i == j) continue;
        bit[i][j] = g[i][j] > 0;
      }
    }
    for (auto [key, val] : mp) {
      if (val < 2) continue;
      ll edge_cnt = 0;
      bs bit_or;
      rep(i, n) {
        bs tmp = bit[i];
        if (key[i]) tmp ^= flip;
        tmp ^= key;
        edge_cnt += tmp.count();
        bit_or |= tmp;
      }
      if (edge_cnt != 2 * n - 2 || bit_or != flip) continue;
      vvl h(n);
      ll tmp = 0;
      ll edge_cnt_ = 0;
      rep(i, n) {
        rep(j, n) {
          if (i == j) continue;
          ll cnt = g[i][j] > 0;
          cnt += key[i];
          cnt += key[j];
          if (cnt % 2 == 1) {
            edge_cnt_++;
            tmp += abs(g[i][j]);
            h[i].pb(j);
          }
        }
      }
      if (edge_cnt_ != 2 * n - 2) continue;
      queue<ll> q({0});
      vb used(n);
      ll cnt = 0;
      while (q.size()) {
        ll now = q.front();
        q.pop();
        if (used[now]) continue;
        used[now] = true;
        cnt++;
        fore(to, h[now]) { q.push(to); }
      }
      if (cnt == n) {
        chmin(ans, tmp);
        // cout << edge_cnt << " " << bit_or.count() << "\n";
      }
    }
    if (ans == infl) ans = -2;
    cout << ans / 2 << "\n";
  }
};

int main() {
  cin.tie(nullptr);
  ios::sync_with_stdio(false);
  cout << fixed << setprecision(20);

  ll t = 1;
  // cin >> t;
  while (t) {
    ll n;
    cin >> n;
    if (n == 0) break;
    Solver solver;
    solver.solve(n);
  }
}
accuracy: 1
time_ms: 1700
memory_kb: 16524
final_rank: 20

code_snippet: #line 2 "cp-library/src/cp-template.hpp"
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using uint = unsigned int;
using ull  = unsigned long long;
using i32 = int;
using u32 = unsigned int;
using i64 = long long;
using u64 = unsigned long long;
using i128 = __int128_t;
template < class T > bool chmin(T& a, T b) { if(a > b) { a = b; return true; } return false; }
template < class T > bool chmax(T& a, T b) { if(a < b) { a = b; return true; } return false; }
template < class T, class U > T ceil (T x, U y) { return (x > 0 ? (x + y - 1) / y :           x / y); }
template < class T, class U > T floor(T x, U y) { return (x > 0 ?           x / y : (x - y + 1) / y); }
int popcnt(i32 x) { return __builtin_popcount(x); }
int popcnt(u32 x) { return __builtin_popcount(x); }
int popcnt(i64 x) { return __builtin_popcountll(x); }
int popcnt(u64 x) { return __builtin_popcountll(x); }

#line 2 "cp-library/src/utility/rep_itr.hpp"
template < class T > struct itr_rep {
    T i, d;
    constexpr itr_rep(const T i) noexcept : i(i), d(1) {}
    constexpr itr_rep(const T i, const T d) noexcept : i(i), d(d) {}
    void operator++() noexcept { i += d; }
    constexpr int operator*() const noexcept { return i; }
    constexpr bool operator!=(const itr_rep x) const noexcept { return d > 0 ? i < x.i : i > x.i; }
};

template < class T > struct rep {
    const itr_rep< T > s, t;
    constexpr rep(const T t) noexcept : s(0), t(t) {}
    constexpr rep(const T s, const T t) noexcept : s(s), t(t) {}
    constexpr rep(const T s, const T t, const T d) noexcept : s(s, d), t(t, d) {}
    constexpr auto begin() const noexcept { return s; }
    constexpr auto end  () const noexcept { return t; }
};

template < class T > struct revrep {
    const itr_rep < T > s, t;
    constexpr revrep(const T t) noexcept : s(t - 1, -1), t(-1, -1) {}
    constexpr revrep(const T s, const T t) noexcept : s(t - 1, -1), t(s - 1, -1) {}
    constexpr revrep(const T s, const T t, const T d) noexcept : s(t - 1, -d), t(s - 1, -d) {}
    constexpr auto begin() const noexcept { return s; }
    constexpr auto end  () const noexcept { return t; }
};
#line 3 "cp-library/src/utility/io.hpp"

/* 128bit integer */
istream& operator>>(istream& is, i128& x) {
    std::string s; is >> s;
    int pm = (s[0] == '-');
    x = 0;
    for(int i : rep(pm, int(s.size()))) x = x * 10 + (s[i] - '0');
    if(pm) x *= -1;
    return is;
}
ostream& operator<<(ostream& os, const i128& x) {
    if(x == 0) return os << '0';
    i128 y = x;
    if(y < 0) { os << '-'; y *= -1; }
    std::vector<int> ny;
    while(y > 0) { ny.push_back(y % 10); y /= 10; }
    for(int i : revrep(ny.size())) os << ny[i];
    return os;
}

template < class S, class T > istream& operator>>(istream& is,       std::pair< S, T >& x) { is >> x.first        >> x.second; return is; }
template < class S, class T > ostream& operator<<(ostream& os, const std::pair< S, T >& x) { os << x.first << " " << x.second; return os; }

namespace scanner {
    struct sca {
        template < class T > operator T() {
            T s; std::cin >> s; return s;
        }
    };
    struct vec {
        int n;
        vec(int n) : n(n) {}
        template < class T > operator std::vector< T >() {
            std::vector< T > v(n);
            for(T& x : v) std::cin >> x;
            return v;
        }
    };
    struct mat {
        int h, w;
        mat(int h, int w) : h(h), w(w) {}
        template < class T > operator std::vector< std::vector< T > >() {
            std::vector m(h, std::vector< T >(w));
            for(std::vector< T >& v : m) for(T& x : v) std::cin >> x;
            return m;
        }
    };
    struct speedup {
        speedup() {
            std::cin.tie(0);
            std::ios::sync_with_stdio(0);
        }
    } speedup_instance;
}
scanner::sca in() { return scanner::sca(); }
scanner::vec in(int n) { return scanner::vec(n); }
scanner::mat in(int h, int w) { return scanner::mat(h, w); }

namespace printer {
    void precision(int d) { std::cout << std::fixed << std::setprecision(d); }
    void flush() { std::cout.flush(); }
}

template < class T >
ostream& operator<<(ostream& os, const std::vector< T > a) {
    int n = a.size();
    for(int i : rep(n)) { os << a[i]; if(i != n - 1) os << ' '; }
    return os;
}

int print() { std::cout << '\n'; return 0; }
template < class head, class... tail > int print(head&& h, tail&&... t) {
    std::cout << h; if(sizeof...(tail)) std::cout << ' ';
    return print(std::forward<tail>(t)...);
}
template < class T > int print_n(const std::vector< T > a) {
    int n = a.size();
    for(int i : rep(n)) std::cout << a[i] << "\n";
    return 0;
}


#line 2 "cp-library/src/utility/key_val.hpp"

template < class K, class V >
struct key_val {
    K key; V val;
    key_val() {}
    key_val(K key, V val) : key(key), val(val) {}
    template < std::size_t Index >
    std::tuple_element_t< Index, key_val >& get() {
        if constexpr (Index == 0) return key;
        if constexpr (Index == 1) return val;
    }
};

namespace std {

template < class K, class V > struct tuple_size < key_val< K, V > > : integral_constant< size_t, 2 > {};
template < class K, class V > struct tuple_element < 0, key_val< K, V > > { using type = K; };
template < class K, class V > struct tuple_element < 1, key_val< K, V > > { using type = V; };

}
#line 2 "cp-library/src/utility/vec_op.hpp"
template < class T > key_val< int, T > max_of(const vector< T >& a) {
    int i = std::max_element(a.begin(), a.end()) - a.begin();
    return {i, a[i]};
}
template < class T > key_val< int, T > min_of(const vector< T >& a) {
    int i = std::min_element(a.begin(), a.end()) - a.begin();
    return {i, a[i]};
}
template < class S, class T > S sum_of(const vector< T >& a) {
    S sum = 0;
    for(const T x : a) sum += x;
    return sum;
}
template < class S, class T > vector< S > freq_of(const vector< T >& a, T L, T R) {
    vector< S > res(R - L, S(0));
    for(const T x : a) res[x - L] += 1;
    return res;
}
template < class S, class T > struct prefix_sum {
    vector< S > s;
    prefix_sum(const vector< T >& a) : s(a) {
        s.insert(s.begin(), S(0));
        for(int i : rep(a.size())) s[i + 1] += s[i];
    }
    // [L, R)
    S sum(int L, int R) { return s[R] - s[L]; }
};
#line 3 "cp-library/src/utility/heap.hpp"

template < class T > using heap_min = std::priority_queue< T, std::vector< T >, std::greater< T > >;
template < class T > using heap_max = std::priority_queue< T, std::vector< T >, std::less< T > >;

#line 27 "cp-library/src/cp-template.hpp"

#line 1 "cp-library/src/algorithm/bin_search.hpp"
template < class T, class F >
T bin_search(T ok, T ng, F f) {
    while(abs(ng - ok) > 1) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}

template < class T, class F >
T bin_search_real(T ok, T ng, F f, int step = 80) {
    while(step--) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}
#line 2 "cp-library/src/algorithm/argsort.hpp"

template < class T > std::vector< int > argsort(const std::vector< T > &a) {
    std::vector< int > ids((int)a.size());
    std::iota(ids.begin(), ids.end(), 0);
    std::sort(ids.begin(), ids.end(), [&](int i, int j) {
        return a[i] < a[j] || (a[i] == a[j] && i < j);
    });
    return ids;
}
#line 1 "macro.hpp"
namespace macro {

using size_type = int;
template < class container > void  sort(container& a) { std::sort(std:: begin(a), std:: end(a)); }
template < class container > void rsort(container& a) { std::sort(std::rbegin(a), std::rend(a)); }
template < class container > void reverse(container& a) { std::reverse(std::begin(a), std::end(a)); }
template < class container > void unique(container& a) {
    std::sort(std::begin(a), std::end(a));
    a.erase(std::unique(std::begin(a), std::end(a)), std::end(a));
}
template < class container > container  sorted(const container& a) { container b = a;  sort(b); return std::move(b); }
template < class container > container rsorted(const container& a) { container b = a; rsort(b); return std::move(b); }
template < class container, class compare > void sort(container& a, const compare& cmp) { std::sort(std::begin(a), std::end(a), cmp); }
template < class container, class compare > container sorted(const container& a, const compare& cmp) { container b = a; sort(b, cmp); return std::move(b); }
template < class container, class value > size_type lower_bound(const container& a, const value& x) { return std::lower_bound(std::begin(a), std::end(a), x) - std::begin(a); }
template < class container, class value > size_type upper_bound(const container& a, const value& x) { return std::upper_bound(std::begin(a), std::end(a), x) - std::begin(a); }

const std::vector<std::pair<size_type, size_type>> dir4 = { {+1,  0}, {-1,  0}, { 0, +1}, { 0, -1} };
const std::vector<std::pair<size_type, size_type>> dir8 = { {-1, -1}, {-1,  0}, {-1, +1}, { 0, -1}, { 0, +1}, {+1, -1}, {+1,  0}, {+1, +1} };

#ifdef _DEBUG
#define debug(x) std::cout << "[" << __LINE__ << "] " << #x << ": " << x << std::endl
#else
#define debug(x)
#endif

template < class container > void concat(container& a, const container& b) {
    a.insert(std::end(a), std::begin(b), std::end(b));
}
std::vector<size_type> iota(const size_type n) {
    std::vector<size_type> I(n);
    std::iota(std::begin(I), std::end(I), 0);
    return I;
}
template < class container > std::vector<size_type> sort_idx(const container& a) {
    const size_type n = a.size();
    std::vector<size_type> I = iota(n);
    std::sort(std::begin(I), std::end(I), [&](size_type i, size_type j) { return a[i] < a[j] or (a[i] == a[j] and i < j); });
    return I;
}
template < class container, class compare > std::vector<size_type> sort_idx(const container& a, const compare& cmp) {
    const size_type n = a.size();
    std::vector<size_type> I = iota(n);
    std::sort(std::begin(I), std::end(I), [&](size_type i, size_type j) { return cmp(a[i], a[j]) or (a[i] == a[j] and i < j); });
    return std::move(I);
}

struct grid {
    using size_type = int;
    size_type H, W;
    grid(const size_type H, const size_type W) : H(H), W(W) {}
    bool contains(const size_type i, const size_type j) {
        return 0 <= i and i < H and 0 <= j and j < W;
    }
};

using f64 = long double;

template < class T > vector< T >& operator++(vector< T >& a) { for(T& x : a) x++; return a; }
template < class T > vector< T >& operator--(vector< T >& a) { for(T& x : a) x--; return a; }
template < class T > vector< T >  operator++(vector< T >& a, signed) { vector< T > res = a; for(T& x : a) x++; return res; }
template < class T > vector< T >  operator--(vector< T >& a, signed) { vector< T > res = a; for(T& x : a) x--; return res; }

} // namespace macro

using namespace macro;
#line 1 "cp-library/src/data_structure/union_find.hpp"
class union_find {
  public:
    union_find(int n) : data(n, -1) {}
    int unite(int x, int y) {
        x = root(x), y = root(y);
        if(x != y) {
            if(size(x) < size(y)) swap(x, y);
            data[x] += data[y];
            return data[y] = x;
        }
        return -1;
    }
    int root(int x) { return data[x] < 0 ? x : data[x] = root(data[x]); }
    int size(int x) { return -data[root(x)]; }
    bool same(int x, int y) { return root(x) == root(y); }

  private:
    vector<int> data;
};
#line 4 "A.cpp"

void solve(int n) {
    vector A(n, vector(n, 0));
    vector X(n, vector(n, 0));

    for(int i : rep(n)) {
        for(int j : rep(i + 1, n)) {
            int a = in();
            A[i][j] = A[j][i] = abs(a);
            X[i][j] = X[j][i] = (a > 0);
        }
    }

    auto push = [&](int v) {
        for(int i : rep(n)) if(i != v) {
            X[v][i] ^= 1;
            X[i][v] ^= 1;
        }
    };

    const int INF = 1e9;
    int ans = INF;
    for(int s : rep(n)) {
        for(int v : rep(n)) if(v != s and X[s][v]) push(v);
        vector<vector<int>> g(n);
        for(int u : rep(n)) for(int v : rep(n)) if(u != v and X[u][v]) g[u].push_back(v);

        for(int t : rep(n)) if(t != s) {
            push(t);

            int cost = 0;
            bool ok = [&] {
                union_find uf(n);
                for(int v : rep(n)) if(v != t and X[t][v]) {
                    if(uf.same(t, v)) return false;
                    uf.unite(t, v);
                    cost += A[t][v];
                }
                for(int v : rep(n)) if(v != t) {
                    for(int u : g[v]) if(u != t and u < v) {
                        if(uf.same(u, v)) return false;
                        uf.unite(u, v);
                        cost += A[u][v];
                    }
                }
                return uf.size(0) == n;
            }();
            if(ok) chmin(ans, cost);

            push(t);
        }
    }

    print(ans == INF ? -1 : ans);
}

int main() {
    while(true) {
        int n = in(); if(n == 0) return 0;
        solve(n);
    }
}
accuracy: 1
time_ms: 1730
memory_kb: 4408
final_rank: 8

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
#include <climits>
#include <cstring>

using namespace std;

class UnionFind {
public:
    vector<int> parents;
    int group_count;

    UnionFind(int n) {
        parents.resize(n, -1);
        group_count = n;
    }

    int find(int x) {
        if (parents[x] < 0) {
            return x;
        } else {
            return parents[x] = find(parents[x]);
        }
    }

    void union_sets(int x, int y) {
        x = find(x);
        y = find(y);

        if (x == y) {
            return;
        }

        if (parents[x] > parents[y]) {
            swap(x, y);
        }

        parents[x] += parents[y];
        parents[y] = x;
        group_count--;
    }

    int size(int x) {
        return -parents[find(x)];
    }

    bool same(int x, int y) {
        return find(x) == find(y);
    }
};

int main() {
    while (true) {
        int n;
        cin >> n;
        if (n == 0) {
            return 0;
        }

        vector<vector<int>> a(n, vector<int>(n, 0));
        for (int i = 0; i < n - 1; ++i) {
            for (int j = i + 1; j < n; ++j) {
                cin >> a[i][j];
                a[j][i] = a[i][j];
            }
        }

        int ans = INT_MAX;
        vector<vector<int>> memo(n, vector<int>(n, 0));
        int tmp = 0;

        for (int leaf = 0; leaf < n; ++leaf) {
            vector<vector<pair<int, int>>> red(n), black(n);
            vector<int> flip(n, 0);
            for (int v = 0; v < n; ++v) {
                if (v == leaf) continue;
                if (a[v][leaf] > 0) {
                    flip[v] = 1;
                }
            }
            for (int v = 0; v < n; ++v) {
                if (leaf == v) continue;
                for (int u = 0; u < n; ++u) {
                    if (u == v) continue;
                    if ((flip[v] ^ flip[u] ^ (a[v][u] > 0)) == 1) {
                        red[v].emplace_back(u, abs(a[v][u]));
                    } else {
                        black[v].emplace_back(u, abs(a[v][u]));
                    }
                }
            }

            for (int vr = 0; vr < n; ++vr) {
                if (vr == leaf) continue;
                flip[vr] ^= 1;
                tmp++;
                UnionFind uf(n);
                bool flag = true;
                int cost = 0;
                vector<pair<int, int>> edges;

                for (int v = 0; v < n; ++v) {
                    if (!flag) break;
                    if (v == vr) {
                        for (const auto& [u, c] : black[v]) {
                            if ((flip[v] ^ flip[u] ^ (a[v][u] > 0)) == 0) continue;
                            if (!uf.same(u, v)) {
                                cost += c;
                                uf.union_sets(u, v);
                                memo[u][v] = tmp;
                                memo[v][u] = tmp;
                                edges.emplace_back(u, v);
                            } else if (memo[u][v] != tmp) {
                                flag = false;
                                break;
                            }
                        }
                    } else {
                        for (const auto& [u, c] : red[v]) {
                            if ((flip[v] ^ flip[u] ^ (a[v][u] > 0)) == 0) continue;
                            if (!uf.same(u, v)) {
                                cost += c;
                                uf.union_sets(u, v);
                                memo[u][v] = tmp;
                                memo[v][u] = tmp;
                                edges.emplace_back(u, v);
                            } else if (memo[u][v] != tmp) {
                                flag = false;
                                break;
                            }
                        }
                    }
                }

                if (flag && uf.size(0) == n) {
                    ans = min(ans, cost);
                }
                flip[vr] ^= 1;
            }
        }

        if (ans == INT_MAX) {
            ans = -1;
        }
        cout << ans << endl;
    }

    return 0;
}
accuracy: 1
time_ms: 2880
memory_kb: 5272
final_rank: 17

code_snippet: #line 2 "/Users/noya2/Desktop/Noya2_library/template/template.hpp"
using namespace std;

#include<bits/stdc++.h>
#line 1 "/Users/noya2/Desktop/Noya2_library/template/inout_old.hpp"
namespace noya2 {

template <typename T, typename U>
ostream &operator<<(ostream &os, const pair<T, U> &p){
    os << p.first << " " << p.second;
    return os;
}
template <typename T, typename U>
istream &operator>>(istream &is, pair<T, U> &p){
    is >> p.first >> p.second;
    return is;
}

template <typename T>
ostream &operator<<(ostream &os, const vector<T> &v){
    int s = (int)v.size();
    for (int i = 0; i < s; i++) os << (i ? " " : "") << v[i];
    return os;
}
template <typename T>
istream &operator>>(istream &is, vector<T> &v){
    for (auto &x : v) is >> x;
    return is;
}

void in() {}
template <typename T, class... U>
void in(T &t, U &...u){
    cin >> t;
    in(u...);
}

void out() { cout << "\n"; }
template <typename T, class... U, char sep = ' '>
void out(const T &t, const U &...u){
    cout << t;
    if (sizeof...(u)) cout << sep;
    out(u...);
}

template<typename T>
void out(const vector<vector<T>> &vv){
    int s = (int)vv.size();
    for (int i = 0; i < s; i++) out(vv[i]);
}

struct IoSetup {
    IoSetup(){
        cin.tie(nullptr);
        ios::sync_with_stdio(false);
        cout << fixed << setprecision(15);
        cerr << fixed << setprecision(7);
    }
} iosetup_noya2;

} // namespace noya2
#line 1 "/Users/noya2/Desktop/Noya2_library/template/const.hpp"
namespace noya2{

const int iinf = 1'000'000'007;
const long long linf = 2'000'000'000'000'000'000LL;
const long long mod998 =  998244353;
const long long mod107 = 1000000007;
const long double pi = 3.14159265358979323;
const vector<int> dx = {0,1,0,-1,1,1,-1,-1};
const vector<int> dy = {1,0,-1,0,1,-1,-1,1};
const string ALP = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const string alp = "abcdefghijklmnopqrstuvwxyz";
const string NUM = "0123456789";

void yes(){ cout << "Yes\n"; }
void no(){ cout << "No\n"; }
void YES(){ cout << "YES\n"; }
void NO(){ cout << "NO\n"; }
void yn(bool t){ t ? yes() : no(); }
void YN(bool t){ t ? YES() : NO(); }

} // namespace noya2
#line 1 "/Users/noya2/Desktop/Noya2_library/template/utils.hpp"
namespace noya2{

unsigned long long inner_binary_gcd(unsigned long long a, unsigned long long b){
    if (a == 0 || b == 0) return a + b;
    int n = __builtin_ctzll(a); a >>= n;
    int m = __builtin_ctzll(b); b >>= m;
    while (a != b) {
        int mm = __builtin_ctzll(a - b);
        bool f = a > b;
        unsigned long long c = f ? a : b;
        b = f ? b : a;
        a = (c - b) >> mm;
    }
    return a << min(n, m);
}

template<typename T> T gcd_fast(T a, T b){ return static_cast<T>(inner_binary_gcd(abs(a),abs(b))); }

long long sqrt_fast(long long n) {
    if (n <= 0) return 0;
    long long x = sqrt(n);
    while ((x + 1) * (x + 1) <= n) x++;
    while (x * x > n) x--;
    return x;
}

template<typename T> T floor_div(const T n, const T d) {
    assert(d != 0);
    return n / d - static_cast<T>((n ^ d) < 0 && n % d != 0);
}

template<typename T> T ceil_div(const T n, const T d) {
    assert(d != 0);
    return n / d + static_cast<T>((n ^ d) >= 0 && n % d != 0);
}

template<typename T> void uniq(vector<T> &v){
    sort(v.begin(),v.end());
    v.erase(unique(v.begin(),v.end()),v.end());
}

template <typename T, typename U> inline bool chmin(T &x, U y) { return (y < x) ? (x = y, true) : false; }

template <typename T, typename U> inline bool chmax(T &x, U y) { return (x < y) ? (x = y, true) : false; }

template<typename T> inline bool range(T l, T x, T r){ return l <= x && x < r; }

} // namespace noya2
#line 8 "/Users/noya2/Desktop/Noya2_library/template/template.hpp"

#define rep(i,n) for (int i = 0; i < (int)(n); i++)
#define repp(i,m,n) for (int i = (m); i < (int)(n); i++)
#define reb(i,n) for (int i = (int)(n-1); i >= 0; i--)
#define all(v) (v).begin(),(v).end()

using ll = long long;
using ld = long double;
using uint = unsigned int;
using ull = unsigned long long;
using pii = pair<int,int>;
using pll = pair<ll,ll>;
using pil = pair<int,ll>;
using pli = pair<ll,int>;

namespace noya2{

/*　~ (. _________ . /)　*/

}

using namespace noya2;


#line 2 "c.cpp"


void solve(int n){
    vector<vector<ll>> a(n,vector<ll>(n));
    rep(i,n-1) repp(j,i+1,n){
        cin >> a[i][j];
        a[j][i] = a[i][j];
    }
    // red : 0
    auto get = [&](ll x){
        return (x > 0 ? 0 : 1);
    };
    auto calc = [&](vector<int> fs){
        queue<int> que;
        ll cost = 0;
        vector<int> par(n,-2);
        que.push(0);
        par[0] = -1;
        while (!que.empty()){
            int v = que.front(); que.pop();
            rep(u,n){
                if (u == v) continue;
                if ((get(a[u][v]) ^ fs[u] ^ fs[v]) == 1) continue;
                if (u == par[v]) continue;
                if (par[u] == -2){
                    par[u] = v;
                    cost += abs(a[u][v]);
                    que.push(u);
                }
                else {
                    return linf;
                }
            }
        }
        repp(i,1,n) if (par[i] == -2) return linf;
        return cost;
    };
    ll ans = linf;
    rep(f0,2) repp(v,1,n) rep(f1,2){
        vector<int> fs(n);
        fs[0] = f0;
        fs[v] = (get(a[0][v]) ^ f0);
        int ma = -1;
        repp(u,1,n){
            if (u == v) continue;
            if ((get(a[u][0]) ^ f0) == (get(a[u][v]) ^ fs[v])){
                fs[u] = (get(a[u][0]) ^ f0 ^ 1);
            }
            else {
                chmax(ma,u);
            }
        }
        if (ma != -1){
            fs[ma] = f1;
            repp(u,1,n){
                if (u == v) continue;
                if (u == ma) continue;
                if ((get(a[u][0]) ^ f0) == (get(a[u][v]) ^ fs[v])) continue;
                fs[u] = (get(a[u][ma]) ^ f1 ^ 1);
            }
        }
        chmin(ans,calc(fs));
        // out(f0,v,f1,":",fs);
    }
    if (ans == linf) ans = -1;
    out(ans);
}

int main(){
    while (true){
        int n; cin >> n;
        if (n == 0) break;
        solve(n);
    }
}
accuracy: 1
time_ms: 590
memory_kb: 4004
final_rank: 2

code_snippet: // #pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")

#include <functional>
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <numeric>
#include <cassert>
#include <complex>
#include <memory>
#include <vector>
#include <random>
#include <bitset>
#include <cmath>
#include <stack>
#include <queue>
#include <set>
#include <map>

// #include <immintrin.h>

using namespace std;

using ll=long long;
using LL=__int128;
using ld=long double;
using uint=unsigned int;
using ull=unsigned long long;
using P=pair<int,int>;
using pll=pair<ll,ll>;
template<typename T> using vc=vector<T>;
template<typename T> using vvc=vector<vc<T>>;
template<typename T> using vvvc=vector<vvc<T>>;
using vi=vc<int>;
using vvi=vvc<int>;
using vd=vc<double>;
using vvd=vvc<double>;
using vl=vc<ll>;
using vvl=vvc<ll>;
using vs=vc<string>;
using vp=vc<P>;
using vvp=vvc<P>;
using vpll=vc<pll>;
using pip=pair<P,int>;
using vip=vc<pip>;

#define overload3(_1,_2,_3,name,...) name
#define overload4(_1,_2,_3,_4,name,...) name
#define rep1(n) for(ll _=0;_<(n);_++)
#define rep2(i,n) for(ll i=0;i<(n);i++)
#define rep3(i,a,b) for(ll i=(a);i<(b);i++)
#define rep4(i,a,b,c) for(ll i=(a);i<(b);i+=(c))
#define rep(...) overload4(__VA_ARGS__,rep4,rep3,rep2,rep1)(__VA_ARGS__)
#define rrep1(n) for(ll _=(n);_--;)
#define rrep2(i,n) for(ll i=(n);i--;)
#define rrep3(i,a,b) for(ll i=(b);i-->(a);)
#define rrep(...) overload3(__VA_ARGS__,rrep3,rrep2,rrep1)(__VA_ARGS__)

#define ALL(a) (a).begin(),(a).end()
#define RALL(a) (a).rbegin(),(a).rend()

istream& operator>>(istream& is,__int128& v){
    string s;
    is>>s;
    v=0;
	rep(i,s.size())if(isdigit(s[i])) v=v*10+s[i]-'0';
	if(s[0]=='-') v*=-1;
    return is;
}
ostream& operator<<(ostream& os,__int128 v){
	ostream::sentry s(os);
	if(s){
		__uint128_t t=v<0?-v:v;
		char buf[128];
		char* d=end(buf);
		do{
			d--;
			*d="0123456789"[t%10];
			t/=10;
		}while(t);
		if(v<0){
			d--;
			*d='-';
		}
		int len=end(buf)-d;
		if(os.rdbuf()->sputn(d,len)!=len) os.setstate(ios_base::badbit);
	}
	return os;
}

void syosu(int x=15){
	cout<<fixed<<setprecision(x);
}

void YN(bool x){
	cout<<(x?"Yes":"No")<<endl;
}

template<class T>
void chmin(T &x,T y){
	if(x>y) x=y;
}

template<class T>
void chmax(T &x,T y){
	if(x<y) x=y;
}

template<class T>
void read(vector<T> &a,int n,int off=0){
	a=vector<T>(n);
	for(auto &i:a){
		cin>>i;
		i-=off;
	}
}

void read(vs &a,int n){
	a=vs(n);
	for(auto &i:a) cin>>i;
}

template<class T>
void read(vector<pair<T,T>> &a,int n,int off=0){
	a=vector<pair<T,T>>(n);
	for(auto &[x,y]:a){
		cin>>x>>y;
		x-=off,y-=off;
	}
}

template<class T>
void read(vector<vector<T>> &a,int n,int m,int off=0){
	a=vector<vector<T>>(n,vector<T>(m));
	for(auto &i:a) for(auto &j:i){
		cin>>j;
		j-=off;
	}
}

template<class T>
void readGraph(vector<vector<T>> &g,int n,int m,bool rv=1,int off=1){
	g=vector<vector<T>>(n);
	for(int i=0;i<m;i++){
		T u,v;
		cin>>u>>v;
		u-=off,v-=off;
		g[u].push_back(v);
		if(rv) g[v].push_back(u);
	}
}

template<class T>
void readGraph(vector<vector<pair<T,T>>> &g,int n,int m,bool id=0,bool rv=1,int off=1){
	g=vector<vector<pair<T,T>>>(n);
	for(int i=0;i<m;i++){
		if(id){
			T u,v;
			cin>>u>>v;
			u-=off,v-=off;
			g[u].push_back({v,i});
			if(rv) g[v].push_back({u,i});
		}
		else{
			T u,v,w;
			cin>>u>>v>>w;
			u-=off,v-=off;
			g[u].push_back({v,w});
			if(rv) g[v].push_back({u,w});
		}
	}
}

void output(){cout<<endl;}

template<class T>
void output(T x){
	cout<<x<<endl;
}

template<class T>
void output(vector<T> a,bool next_line=0){
	int N=a.size();
	if(N==0) cout<<endl;
	else for(int i=0;i<N;i++){
		cout<<a[i];
		if(i==N-1||next_line) cout<<endl;
		else cout<<' ';
	}
}

template<class T>
void output(vector<vector<T>> a){
	for(auto i:a) output(i);
}

template<class S,class T>
void output(pair<S,T> a){
	cout<<a.first<<' '<<a.second<<endl;
}

template<class S,class T>
void output(vector<pair<S,T>> &a){
	for(auto p:a) output(p);
}

string out2(ll x,ll n,bool rev=0){
	assert(0<=x&&x<1LL<<n);
	string s(n,'0');
	for(int i=0;i<n;i++) if(x&1LL<<i) s[n-i-1]='1';
	if(rev) reverse(s.begin(),s.end());
	return s;
}

constexpr int inf=1<<30;
constexpr ll INF=1ll<<60;
const double pi=acos(-1);
constexpr double eps=1e-9;
//constexpr ll mod=1e9+7;
constexpr ll mod=998244353;
constexpr int dx[9]={-1,0,1,0,1,1,-1,-1,0},dy[9]={0,1,0,-1,1,-1,1,-1,0};

class Union_Find_Tree{
    public:
    vi p,r,s;
    Union_Find_Tree(int n){
        p=r=vi(n);
        s=vi(n,1);
        for(int i=0;i<n;i++) p[i]=i;
    }
    int Par(int x){
        if(p[x]==x) return x;
        return p[x]=Par(p[x]);
    }
    int Size(int x){return s[Par(x)];}
    bool Unite(int x,int y){
        x=Par(x);
        y=Par(y);
        if(x==y) return 0;
        if(r[x]<r[y]){
            p[x]=y;
            s[y]+=s[x];
        }
        else{
            p[y]=x;
            s[x]+=s[y];
            if(r[x]==r[y]) r[x]++;
        }
        return 1;
    }
    bool Same(int x,int y){return Par(x)==Par(y);}
};

void solve();

int main(){
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	ll q=1;
//	cin>>q;
	while(q--) solve();
}

void solve(){
    while(1){
		ll n;
		cin>>n;
		if(n==0) break;
		vvl g(n,vl(n));
		rep(i,n-1)rep(j,i+1,n){
			ll x;
			cin>>x;
			g[i][j]=g[j][i]=x;
		}
		auto flip=[&](ll u,ll v){
			if(u>v) swap(u,v);
			g[v][u]*=-1;
			g[u][v]*=-1;
		};
		auto query=[&](ll v){
			rep(i,n)if(i!=v) flip(i,v);
		};
		ll rs=INF;
		rep(i,n){
			rep(j,n)if(i!=j&&g[i][j]>0) query(j);
			vpll b;
			rep(j,n)if(j!=i)rep(k,j+1,n)rep(k!=i)if(g[j][k]>0) b.emplace_back(j,k);
			if(b.size()>2*n) continue;
			rep(j,n){
				query(j);
				vpll c;
				for(auto [u,v]:b) if(u!=j&&v!=j) c.emplace_back(u,v);
				rep(k,n)if(k!=j&&g[k][j]>0) c.emplace_back(k,j);
				if(c.size()==n-1){
					Union_Find_Tree uft(n);
					ll tp=0;
					for(auto [u,v]:c) uft.Unite(u,v),tp+=g[u][v];
					if(uft.Size(0)==n) chmin(rs,tp);
				}
				query(j);
			}
		}
		if(rs==INF) rs=-1;
		output(rs);
	}
}
accuracy: 1
time_ms: 1510
memory_kb: 5380
final_rank: 11

code_snippet: #include <bits/stdc++.h>
using namespace std;

#pragma GCC target("avx2")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")

using ll = long long;

template<class T>
bool chmin(T &a, const T &b) {if (a > b) {a = b; return 1;} return 0;}

template<class T>
bool chmax(T &a, const T &b) {if (a < b) {a = b; return 1;} return 0;}

bool is_end = false;

const ll INF = 1e18;
const ll nmax = 300;

struct UnionFind
{
    int n;
    vector<int> par;
    
    UnionFind() = default;
    UnionFind(int _n) : n(_n), par(_n)
    {
        for (int i = 0; i < n; ++i) par[i] = i;
    }
    
    int root(int x)
    {
        if (par[x] == x) return x;
        else return par[x] = root(par[x]);
    }
    
    void merge(int x, int y)
    {
        par[root(y)] = root(x);
        return;
    }
    
    int siz(int x)
    {
        int r = root(x);
        int ret = 0;
        for (int i = 0; i < n; ++i)
        {
            ret += (root(i) == r);
        }
        return ret;
    }
    
};

void solve()
{
    ll N; cin >> N;
    
    if (N == 0)
    {
        is_end = true;
        return;
    }
    
    vector<vector<ll>> A(N, vector<ll>(N, 0));
    vector<bitset<nmax>> isred(N, 0);
    ll suma = 0, cnta = 0;
    for (uint i = 0; i < N; ++i)
    {
        for (uint j = i+1; j < N; ++j)
        {
            int a; cin >> a;
            
            if (a > 0) isred[i][j] = isred[j][i] = 1;
            if (a > 0) suma += a, cnta += 1;
            
            A[i][j] = A[j][i] = abs(a);
        }
    }
    
    ll sum_max = 0;
    {
        vector<ll> vec;
        for (uint i = 0; i < N; ++i)
        {
            for (uint j = i+1; j < N; ++j)
            {
                vec.emplace_back(A[i][j]);
            }
        }
        sort(vec.begin(), vec.end());
        reverse(vec.begin(), vec.end());
        
        sum_max = accumulate(vec.begin(), vec.begin() + N-1, 0LL);
    }
    
    unordered_map<bitset<nmax>, ll> mp;
    bitset<nmax> mask(0);
    for (uint i = 0; i < N; ++i) mask.set(i);
    
    for (uint i = 0; i < N; ++i)
    {
        bitset<nmax> ispush(0);
        ll prej = -1;
        
        // i : off
        ispush[i] = 0;
        
        for (uint j = 0; j < N; ++j)
        {
            if (i == j) continue;
            
            if (prej == -1)
            {
                for (uint k = 0; k < N; ++k)
                {
                    if (k == i) ;
                    else if (k == j) ispush[k] = 1 ^ isred[i][k] ^ ispush[i];
                    else ispush[k] = 0 ^ isred[i][k] ^ ispush[i];
                }
            }
            else
            {
                ispush.flip(prej);
                ispush.flip(j);
            }
            prej = j;
            
            if (ispush[0]) mp[ispush ^ mask] += 1;
            else mp[ispush] += 1;
        }
    }
    
    ll res = INF;
    
    for (auto& [key, value] : mp)
    {
        if (value < 2) continue;
        
        ll cnt = 0;
        for (uint i = 0; i < N; ++i)
        {
            bitset<nmax> tmp = isred[i] ^ key;
            if (key[i]) tmp ^= mask;
            tmp[i] = 0;
            
            cnt += tmp.count();
        }
        cnt /= 2;
        
        if (cnt == (N - 1))
        {
            // cout << key << endl;
            UnionFind uf(N);
            ll sum = 0;
            for (uint i = 0; i < N; ++i)
            {
                bitset<nmax> tmp = isred[i] ^ key;
                if (key[i]) tmp ^= mask;
                tmp[i] = 0;
                
                for (uint j = 0; j < N; ++j)
                {
                    if (tmp[j])
                    {
                        uf.merge(i, j);
                        sum += A[i][j];
                    }
                }
            }
            sum /= 2;
            
            if (uf.siz(0) == N)
            {
                chmin(res, sum);
            }
            
        }
        
    }
    
    if (res == INF) res = -1;
    cout << res << endl;
    // cerr << res << endl;
    
    return;
}

int main()
{
    cin.tie(0);
    ios::sync_with_stdio(0);
    
    while (!is_end)
    {
        solve();
    }
    
    return 0;
}
accuracy: 1
time_ms: 260
memory_kb: 10376
final_rank: 13

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i, n) for (ll i = 0; i < (ll) (n); i++)


int main() {
    int N;
    while(cin>>N){
        if(N==0)return 0;
        vector<vector<int>> G(N,vector<int>(N,0));
        for(int i=0;i<N;i++){
            for(int j=i+1;j<N;j++){
                cin>>G[i][j];
                G[j][i]=G[i][j];
            }
        }
        int an=1e9;
        for(int a=0;a<N;a++){
            vector<vector<int>> CG=G;
            for(int b=0;b<N;b++){
                if(b==a)continue;
                if(CG[b][a]>0){
                    for(int k=0;k<N;k++){
                        CG[b][k]*=-1;
                        CG[k][b]*=-1;
                    }
                }    
            }
            vector<vector<int>> RD(N);
            for(int b=0;b<N;b++){
                for(int c=0;c<N;c++){
                    if(CG[b][c]>0)RD[b].push_back(c);
                }
            }

            for(int b=0;b<N;b++){
                if(a==b)continue;
                
                int edcnt=RD[b].size();
                for(int j=0;j<N;j++){
                    if(j==b)continue;
                    edcnt+=RD[j].size();
                    if(CG[b][j]>0)edcnt-=2;
                    else edcnt+=2;
                }
                if(edcnt!=2*(N-1))continue;

                queue<int> Q;
                vector<bool> seen(N,false);
                int res=0;
                for(int j=0;j<N;j++){
                    if(CG[b][j]<0){
                        Q.push(j);
                        res-=CG[b][j];
                    }
                }
                ll vcnt=0;
                while(!Q.empty()){
                    int p=Q.front();
                    Q.pop();
                    if(seen[p])continue;
                    seen[p]=1;
                    vcnt++;
                    for(auto v:RD[p]){
                        if(v==b)continue;
                        if(!seen[v]){
                            Q.push(v);
                            res+=CG[p][v];
                        }
                    }
                }
                if(vcnt==N-1){
                    an=min(an,res);
                }
            }
        }
        cout<<(an<5e8?an:-1)<<endl;
    }
    
}
accuracy: 1
time_ms: 1280
memory_kb: 4448
final_rank: 6

code_snippet: #include <algorithm>
#include <cassert>
#include <iostream>
#include <map>
#include <numeric>
#include <set>
#include <unordered_set>
#include <vector>

using ll = long long int;

using namespace std;

class unionfind {
private:
    vector<int> UF, rank, size_;

public:
    void init(int N) {
        UF.clear();
        rank.clear();
        size_.clear();
        for (int i = 0; i < N; i++) {
            UF.push_back(i);
            rank.push_back(0);
            size_.push_back(1);
        }
    }

    unionfind(int N) { init(N); }

    int root(int k) {
        if (UF[k] == k) {
            return k;
        }
        else {
            UF[k] = root(UF[k]);
            return UF[k];
        }
    }

    bool same(int p, int q) { return root(p) == root(q); }

    void unite(int P, int Q) {
        int p = root(P);
        int q = root(Q);
        if (p == q) return;
        if (rank[p] < rank[q]) swap(p, q);
        UF[q] = p;
        if (rank[p] == rank[q]) rank[p]++;
        size_[p] += size_[q];
        size_[q] = 0;
    }

    int size(int k) { return size_[root(k)]; }
};

int main() {
    while (true) {
        int N;
        cin >> N;
        if (N == 0) break;

        vector<vector<ll>> E(N);
        for (int i = 0; i < N; i++) {
            E[i].resize(N);
        }
        for (int i = 0; i < N; i++) {
            for (int j = i + 1; j < N; j++) {
                cin >> E[i][j];
                E[j][i] = E[i][j];
            }
            E[i][i] = 0;
        }

        /*for(int i=0;i<N;i++){
            for(int j=0;j<N;j++){
                cout << E[i][j] << " ";
            }
            cout << endl;
        }*/

        ll ans = -1;

        for (int leaf = 0; leaf < N; leaf++) {
            //ぜんぶ黒にする
            for (int k = 0; k < N; k++) {
                if (leaf == k) continue;
                //正のとき赤、負のとき黒
                if (E[leaf][k] > 0) {
                    for (int j = 0; j < N; j++) {
                        E[k][j] *= -1;
                        E[j][k] *= -1;
                    }
                }
            }

            /*for(int i=0;i<N;i++){
                for(int j=0;j<N;j++){
                    cout << R[i][j] << " ";
                }
                cout << endl;
            }
            cout << endl;*/

            std::vector<int> nanachi[310];

            for (int i = 0; i < N; i++) {
                for (int k = 0; k < i; k++) {
                    if (E[k][i] > 0) {
                        nanachi[k].push_back(i);
                    }
                }
            }

            for (int par = 0; par < N; par++) {
                if (leaf == par) continue;

                int nanachi_size = 0;
                for (int i = 0; i < N; i++) {
                    nanachi_size += nanachi[i].size();
                }

                // parとleafをつなげる
                for (int j = 0; j < N; j++) {
                    if (j == par) { continue; }
                    auto p = std::minmax(par, j);
                    if (E[par][j]*-1 > 0) {
                        ++nanachi_size;
                        //nanachi[p.first].insert(p.second);
                    }
                    else {
                        --nanachi_size;
                        //nanachi[p.first].erase(p.second);
                    }
                }

                if (nanachi_size == N - 1) {
                    //// parとleafをつなげる
                    //for (int j = 0; j < N; j++) {
                    //    E[par][j] *= -1;
                    //    E[j][par] *= -1;
                    //    auto p = std::minmax(par, j);
                    //    if (E[par][j] > 0) {
                    //        nanachi[p.first].insert(p.second);
                    //    }
                    //    else {
                    //        nanachi[p.first].erase(p.second);
                    //    }
                    //}

                    //木チェック
                    unionfind uf(N);
                    ll tmp = 0;
                    bool ok = true;
                    for (int i = 0; ok && i < N; i++) {
                        if (i == par) {
                            //parが関係するもの全部
                            for (size_t k = 0; k < N; k++) {
                                if (E[i][k] * -1 > 0) {
                                    if (uf.same(i, k)) { ok = false; break; }
                                    uf.unite(i, k);
                                    tmp += -E[i][k];
                                }
                            }
                            continue;
                        }

                        for (auto& k : nanachi[i]) {
                            assert(E[i][k] > 0);
                            if (k == par) { continue; }
                            if (uf.same(i, k)) { ok = false; break; }
                            uf.unite(i, k);
                            tmp += E[i][k];
                        }
                    }

                    if (ok && (ans < 0 || ans > tmp)) ans = tmp;


                    //// parとleafをつなげる
                    //for (int j = 0; j < N; j++) {
                    //    E[par][j] *= -1;
                    //    E[j][par] *= -1;
                    //    auto p = std::minmax(par, j);
                    //    if (E[par][j] > 0) {
                    //        nanachi[p.first].insert(p.second);
                    //    }
                    //    else {
                    //        nanachi[p.first].erase(p.second);
                    //    }
                    //}
                }

            }
        }

        std::cout << ans << '\n';
    }
}
accuracy: 1
time_ms: 1610
memory_kb: 4284
final_rank: 7

code_snippet: #include <algorithm>
#include <cassert>
#include <iostream>
#include <map>
#include <numeric>
#include <set>
#include <unordered_set>
#include <vector>

using ll = long long int;

using namespace std;

class unionfind {
private:
    vector<int> UF, rank, size_;

public:
    void init(int N) {
        UF.clear();
        rank.clear();
        size_.clear();
        for (int i = 0; i < N; i++) {
            UF.push_back(i);
            rank.push_back(0);
            size_.push_back(1);
        }
    }

    unionfind(int N) { init(N); }

    int root(int k) {
        if (UF[k] == k) {
            return k;
        }
        else {
            UF[k] = root(UF[k]);
            return UF[k];
        }
    }

    bool same(int p, int q) { return root(p) == root(q); }

    void unite(int P, int Q) {
        int p = root(P);
        int q = root(Q);
        if (p == q) return;
        if (rank[p] < rank[q]) swap(p, q);
        UF[q] = p;
        if (rank[p] == rank[q]) rank[p]++;
        size_[p] += size_[q];
        size_[q] = 0;
    }

    int size(int k) { return size_[root(k)]; }
};

int main() {
    while (true) {
        int N;
        cin >> N;
        if (N == 0) break;

        vector<vector<ll>> E(N);
        for (int i = 0; i < N; i++) {
            E[i].resize(N);
        }
        for (int i = 0; i < N; i++) {
            for (int j = i + 1; j < N; j++) {
                cin >> E[i][j];
                E[j][i] = E[i][j];
            }
            E[i][i] = 0;
        }

        /*for(int i=0;i<N;i++){
            for(int j=0;j<N;j++){
                cout << E[i][j] << " ";
            }
            cout << endl;
        }*/

        ll ans = -1;

        for (int leaf = 0; leaf < N; leaf++) {
            //ぜんぶ黒にする
            for (int k = 0; k < N; k++) {
                if (leaf == k) continue;
                //正のとき赤、負のとき黒
                if (E[leaf][k] > 0) {
                    for (int j = 0; j < N; j++) {
                        E[k][j] *= -1;
                        E[j][k] *= -1;
                    }
                }
            }

            /*for(int i=0;i<N;i++){
                for(int j=0;j<N;j++){
                    cout << R[i][j] << " ";
                }
                cout << endl;
            }
            cout << endl;*/

            std::vector<int> nanachi[310];

            for (int i = 0; i < N; i++) {
                for (int k = 0; k < i; k++) {
                    if (E[k][i] > 0) {
                        nanachi[k].push_back(i);
                    }
                }
            }

            for (int par = 0; par < N; par++) {
                if (leaf == par) continue;

                int nanachi_size = 0;
                for (int i = 0; i < N; i++) {
                    nanachi_size += nanachi[i].size();
                }

                // parとleafをつなげる
                for (int j = 0; j < N; j++) {
                    if (j == par) { continue; }
                    auto p = std::minmax(par, j);
                    if (E[par][j]*-1 > 0) {
                        ++nanachi_size;
                        //nanachi[p.first].insert(p.second);
                    }
                    else {
                        --nanachi_size;
                        //nanachi[p.first].erase(p.second);
                    }
                }

                if (nanachi_size == N - 1) {
                    //// parとleafをつなげる
                    //for (int j = 0; j < N; j++) {
                    //    E[par][j] *= -1;
                    //    E[j][par] *= -1;
                    //    auto p = std::minmax(par, j);
                    //    if (E[par][j] > 0) {
                    //        nanachi[p.first].insert(p.second);
                    //    }
                    //    else {
                    //        nanachi[p.first].erase(p.second);
                    //    }
                    //}

                    //木チェック
                    unionfind uf(N);
                    ll tmp = 0;
                    bool ok = true;
                    for (int i = 0; ok && i < N; i++) {
                        if (i == par) {
                            for (size_t k = i+1; k < N; k++) {
                                if (E[i][k] * -1 > 0) {
                                    if (uf.same(i, k)) { ok = false; break; }
                                    uf.unite(i, k);
                                    tmp += -E[i][k];
                                }
                            }
                            continue;
                        }

                        bool par_selected = false;
                        for (auto& k : nanachi[i]) {
                            assert(E[i][k] > 0);
                            if (k == par) { par_selected = true; continue; }
                            if (uf.same(i, k)) { ok = false; break; }
                            uf.unite(i, k);
                            tmp += E[i][k];
                        }
                        if (ok && i < par && !par_selected) {
                            auto k = par;
                            assert(-E[i][k] > 0);
                            if (uf.same(i, k)) { ok = false; break; }
                            uf.unite(i, k);
                            tmp += -E[i][k];
                        }
                    }

                    if (ok && (ans < 0 || ans > tmp)) ans = tmp;


                    //// parとleafをつなげる
                    //for (int j = 0; j < N; j++) {
                    //    E[par][j] *= -1;
                    //    E[j][par] *= -1;
                    //    auto p = std::minmax(par, j);
                    //    if (E[par][j] > 0) {
                    //        nanachi[p.first].insert(p.second);
                    //    }
                    //    else {
                    //        nanachi[p.first].erase(p.second);
                    //    }
                    //}
                }

            }
        }

        std::cout << ans << '\n';
    }
}
accuracy: 1
time_ms: 1830
memory_kb: 4268
final_rank: 9

code_snippet: #include <algorithm>
#include <cassert>
#include <iostream>
#include <map>
#include <numeric>
#include <set>
#include <unordered_set>
#include <vector>

using ll = long long int;

using namespace std;

class unionfind {
private:
    vector<int> UF, rank, size_;

public:
    void init(int N) {
        UF.clear();
        rank.clear();
        size_.clear();
        for (int i = 0; i < N; i++) {
            UF.push_back(i);
            rank.push_back(0);
            size_.push_back(1);
        }
    }

    unionfind(int N) { init(N); }

    int root(int k) {
        if (UF[k] == k) {
            return k;
        }
        else {
            UF[k] = root(UF[k]);
            return UF[k];
        }
    }

    bool same(int p, int q) { return root(p) == root(q); }

    void unite(int P, int Q) {
        int p = root(P);
        int q = root(Q);
        if (p == q) return;
        if (rank[p] < rank[q]) swap(p, q);
        UF[q] = p;
        if (rank[p] == rank[q]) rank[p]++;
        size_[p] += size_[q];
        size_[q] = 0;
    }

    int size(int k) { return size_[root(k)]; }
};

int main() {
    while (true) {
        int N;
        cin >> N;
        if (N == 0) break;

        vector<vector<ll>> E(N);
        for (int i = 0; i < N; i++) {
            E[i].resize(N);
        }
        for (int i = 0; i < N; i++) {
            for (int j = i + 1; j < N; j++) {
                cin >> E[i][j];
                E[j][i] = E[i][j];
            }
            E[i][i] = 0;
        }

        /*for(int i=0;i<N;i++){
            for(int j=0;j<N;j++){
                cout << E[i][j] << " ";
            }
            cout << endl;
        }*/

        ll ans = -1;

        for (int leaf = 0; leaf < N; leaf++) {
            //ぜんぶ黒にする
            for (int k = 0; k < N; k++) {
                if (leaf == k) continue;
                //正のとき赤、負のとき黒
                if (E[leaf][k] > 0) {
                    for (int j = 0; j < N; j++) {
                        E[k][j] *= -1;
                        E[j][k] *= -1;
                    }
                }
            }

            /*for(int i=0;i<N;i++){
                for(int j=0;j<N;j++){
                    cout << R[i][j] << " ";
                }
                cout << endl;
            }
            cout << endl;*/

            std::unordered_set<int> nanachi[310];

            for (int i = 0; i < N; i++) {
                for (int k = 0; k < i; k++) {
                    if (E[k][i] > 0) {
                        nanachi[k].insert(i);
                    }
                }
            }

            for (int par = 0; par < N; par++) {
                if (leaf == par) continue;

                int nanachi_size = 0;
                for (int i = 0; i < N; i++) {
                    nanachi_size += nanachi[i].size();
                }

                // parとleafをつなげる
                for (int j = 0; j < N; j++) {
                    if (j == par) { continue; }
                    auto p = std::minmax(par, j);
                    if (E[par][j]*-1 > 0) {
                        ++nanachi_size;
                        //nanachi[p.first].insert(p.second);
                    }
                    else {
                        --nanachi_size;
                        //nanachi[p.first].erase(p.second);
                    }
                }

                if (nanachi_size == N - 1) {
                    //// parとleafをつなげる
                    //for (int j = 0; j < N; j++) {
                    //    E[par][j] *= -1;
                    //    E[j][par] *= -1;
                    //    auto p = std::minmax(par, j);
                    //    if (E[par][j] > 0) {
                    //        nanachi[p.first].insert(p.second);
                    //    }
                    //    else {
                    //        nanachi[p.first].erase(p.second);
                    //    }
                    //}

                    //木チェック
                    unionfind uf(N);
                    ll tmp = 0;
                    bool ok = true;
                    for (int i = 0; ok && i < N; i++) {
                        if (i == par) {
                            for (size_t k = i+1; k < N; k++) {
                                if (E[i][k] * -1 > 0) {
                                    if (uf.same(i, k)) { ok = false; break; }
                                    uf.unite(i, k);
                                    tmp += -E[i][k];
                                }
                            }
                            continue;
                        }

                        bool par_selected = false;
                        for (auto& k : nanachi[i]) {
                            assert(E[i][k] > 0);
                            if (k == par) { par_selected = true; continue; }
                            if (uf.same(i, k)) { ok = false; break; }
                            uf.unite(i, k);
                            tmp += E[i][k];
                        }
                        if (ok && i < par && !par_selected) {
                            auto k = par;
                            assert(-E[i][k] > 0);
                            if (uf.same(i, k)) { ok = false; break; }
                            uf.unite(i, k);
                            tmp += -E[i][k];
                        }
                    }

                    if (ok && (ans < 0 || ans > tmp)) ans = tmp;


                    //// parとleafをつなげる
                    //for (int j = 0; j < N; j++) {
                    //    E[par][j] *= -1;
                    //    E[j][par] *= -1;
                    //    auto p = std::minmax(par, j);
                    //    if (E[par][j] > 0) {
                    //        nanachi[p.first].insert(p.second);
                    //    }
                    //    else {
                    //        nanachi[p.first].erase(p.second);
                    //    }
                    //}
                }

            }
        }

        std::cout << ans << '\n';
    }
}
accuracy: 1
time_ms: 2950
memory_kb: 5728
final_rank: 18

code_snippet: #include<cmath>
#include<algorithm>
#include<iostream>
#include<vector>
#include<map>
#include<set>
#include<cassert>
#include<stack>
const int INF=1e9;
template<class T>
bool chmin(T &a,T b){
	if(a>b){
		a=b;
		return true;
	}
	return false;
}
using namespace std;
#define rep(i,a,b) for(int i=(int)a;i<(int)b;i++)

void solve(int n){
	vector<vector<int>> p(n,vector<int>(n));
	rep(i,0,n) rep(j,i+1,n){
		cin>>p[i][j];
		p[j][i]=p[i][j];
	}
	vector<int> s(n);
	int E=0;
	rep(i,0,n) rep(j,0,n){
		if(p[i][j]>0) E++,s[i]++;
	}
	auto f=[&](int ind)->void{
		rep(i,0,n){
			if(ind==i) continue;
			if(p[i][ind]>0){
				s[i]--;
				s[ind]--;
				E-=2;
			}
			else{
				s[i]++;
				s[ind]++;
				E+=2;
			}
			p[i][ind]*=-1;
			p[ind][i]*=-1;
		}
	};
	int ans=INF;
	rep(i,0,n){
		rep(j,0,n){
			if(p[i][j]>0) f(j);
		}
		vector<vector<int>> H(n);
		rep(j,0,n) rep(k,0,n){
			if(p[j][k]>0) H[j].push_back(k);
		}
		rep(j,0,n){
			if(j==i) continue;
			f(j);
			if(E!=n*2-2){
				f(j);
				continue;
			}
			int tmp=p[i][j];
			vector<int> seen(n);
			seen[i]=1,seen[j]=1;
			vector<int> order={i,j};
			rep(k,0,n){
				if(k==i||k==j) continue;
				if(p[k][j]>0) tmp+=p[k][j],order.push_back(k),seen[k]=1;
			}
			rep(k,2,n){
				if(k==(int)order.size()){
					tmp=INF;
					break;
				}
				int a=order[k];
				for(auto x:H[a]){
					if(seen[x]==0){
						seen[x]=1;
						order.push_back(x);
						tmp+=p[a][x];
					}
				}
			}
			chmin(ans,tmp);
			f(j);
		}
	}
	cout<<(ans==INF?-1:ans)<<"\n";
}

int main(){
	while(true){
		int n;
		cin>>n;
		if(n) solve(n);
		else break;
	}
}
accuracy: 1
time_ms: 2040
memory_kb: 4084
final_rank: 12

code_snippet: #include <bits/stdc++.h>
using namespace std;

#define rep(i, n) for(int i = 0; i < n; i++)
#define per(i, n) for(int i = (n)-1; i >= 0; i--)
#define rep2(i, l, r) for (int i = l; i < r; i++)
#define per2(i, l, r) for (int i = (r)-1; i >= (l); i--)
#define pb push_back
#define eb emplace_back
#define all(x) begin(x), end(x)
#define rall(x) rbegin(x), rend(x)
#define sz(x) (int)x.size()
#define each(e, x) for (auto &e: x)
using ll = long long;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
#define TT template<typename T>

TT void print(vector<T> v, T x = 0) {
    int n = sz(v);
    rep(i, n) cout << v[i] << (i + 1 == n ? '\n' : ' ');
    if (n == 0) cout << '\n';
}

TT void printn(vector<T> v, T x = 0) {
    int n = sz(v);
    rep(i, n) cout << v[i] << '\n';
}

TT bool chmax(T &x, const T &y) {
    return (x < y) ? (x = y, true) : false;
}

TT bool chmin(T &x, const T &y) {
    return (x > y) ? (x = y, true) : false;
}

TT using minheap = priority_queue<T, vector<T>, greater<T>>;
TT using maxheap = priority_queue<T>;

TT int lb(vector<T> &v, T x) {
    return lower_bound(all(v), x) - begin(v);
}

TT int ub(vector<T> &v, T x) {
    return upper_bound(all(v), x) - begin(v);
}

TT void rearrange(vector<T> &v) {
    sort(all(v));
    v.erase(unique(all(v)), end(v));
}

struct io_setup {
    io_setup() {
        ios_base::sync_with_stdio(false);
        cin.tie(NULL);
        cout << fixed << setprecision(15);
    }
} io_setup;

const ll MOD = 998244353;

struct UnionFind {
    vector<int> data;
    stack<pair<int, int>> history;
    const int n;
    int cnt;

    UnionFind(int n) : data(n, -1), n(n), cnt(n) {}

    int operator[](int i) { return root(i); }

    int root(int x) {
        return (data[x] < 0 ? x : root(data[x]));
    }

    bool unite(int x, int y) {
        x = root(x), y = root(y);
        if (x == y) return false;
        history.emplace(x, data[x]), history.emplace(y, data[y]);
        if (data[x] > data[y])
            swap(x, y);
        data[x] += data[y];
        data[y] = x;
        cnt--;
        return true;
    }

    void undo(int k) {
        cnt += k;
        k <<= 1;
        while (k--) {
            data[history.top().first] = history.top().second;
            history.pop();
        }
    }

    int count() { return cnt; }
};

void solve() {
    int n;
    cin >> n;
    if (n == 0)
        exit(0);
    vector<vector<int>> e(n, vector<int>(n)), w = e, c = e;
    rep(i, n) rep2(j, i + 1, n) cin >> e[i][j], w[i][j] = abs(e[i][j]), c[i][j] = (e[i][j] > 0);
    const int INF = 2e9;
    int ans = INF;
    auto dfs = [&](vector<int> &st, UnionFind &uf, int sw, int idx, auto &&dfs) ->void {
        if (idx == n) {
            if (uf.count() == 1)
                chmin(ans, sw);
            return;
        }
        rep(f, 2) {
            st[idx] = f;
            bool ok = true;
            int k = 0, csw = sw;
            rep(i, idx) {
                if (st[i] ^ st[idx] ^ c[i][idx]) {
                    if (!uf.unite(i, idx)) {
                        ok = false;
                        break;
                    }
                    k++, csw += w[i][idx];
                }
            }
            if (ok)
                dfs(st, uf, csw, idx + 1, dfs);
            uf.undo(k);
        }
    };
    vector<int> st(n, 0);
    UnionFind uf(n);
    dfs(st, uf, 0, 1, dfs);
    cout << (ans == INF ? -1 : ans) << '\n';
}

int main() {
    while (true)
        solve();
}
accuracy: 1
time_ms: 70
memory_kb: 4544
final_rank: 1

code_snippet: #pragma GCC optimize ("Ofast")
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;

struct UnionFind{
    vector<int> par,num;
    UnionFind(int n):par(n),num(n,1){
        iota(par.begin(),par.end(),0);  //include<numeric>
    }
    int find(int v){
        return (par[v]==v)?v:(par[v]=find(par[v]));
    }
    void unite(int u, int v){
        u = find(u),v = find(v);
        if(u == v) return;
        if(num[u] < num[v]) swap(u,v);
        num[u] += num[v];
        par[v] = u;
    }
    bool same(int u, int v){
        return find(u) == find(v);
    }
    int size(int v){
        return num[find(v)];
    }
};

int main(){
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    int n;
    while(cin >> n,n){
        vector<vector<int>> e(n,vector<int>(n));
        for (int i = 0; i < n; ++i) {
            for (int j = i+1; j < n; ++j) {
                cin >> e[i][j];
                e[j][i] = e[i][j];
            }
        }
        vector<vector<int>> eg(n,vector<int>(n));
        int res = 1e9;
        vector<int> flip(n);
        // 葉を固定(flipしないとしても良い)
        for (int i = 0; i < n; ++i) {
            int pre = -1;
            flip[i] = 0;
            int m = 0;
            int sum = 0;
            for (int j = 0; j < n; ++j) {
                if(i == j) continue;
                if(pre == -1){
                    if(e[i][j] > 0) flip[j] = false;
                    else flip[j] = true;
                    for (int k = 0; k < n; ++k) {
                        if(i == k or j == k) continue;
                        if(e[i][k] > 0) flip[k] = true;
                        else flip[k] = false;
                    }
                }
                else{
                    flip[j] ^= 1;
                    flip[pre] ^= 1;
                }
                if(pre == -1){
                    for (int k = 0; k < n; ++k) {
                        for (int l = k+1; l < n; ++l) {
                            int f = (flip[k]^flip[l]);
                            if(!f and e[k][l] > 0){
                                eg[k][l] = true; m++;
                                sum += e[k][l];
                            }
                            else if(f and e[k][l] < 0){
                                eg[k][l] = true; m++;
                                sum -= e[k][l];
                            }
                            else{
                                eg[k][l] = false;
                            }
                        }
                    }
                }
                else{
                    auto update = [&](int x,int y)->void{
                        if(x > y) swap(x, y);
                        if(eg[x][y]){
                            m--; eg[x][y] = false;
                            sum -= abs(e[x][y]);
                        }
                        else{
                            m++; eg[x][y] = true;
                            sum += abs(e[x][y]);
                        }
                    };
                    for (int k = 0; k < n; ++k) {
                        if(k == pre) continue;
                        update(pre, k);
                    }
                    for (int k = 0; k < n; ++k) {
                        if(k == j) continue;
                        update(j, k);
                    }
                }
                if(m == n-1 and sum < res){
                    UnionFind uf(n);
                    for (int k = 0; k < n; ++k) {
                        for (int l = k+1; l < n; ++l) {
                            if(eg[k][l]){
                                uf.unite(k, l);
                            }
                        }
                    }
                    if(uf.size(0) == n) res = min(res, sum);
                }
                pre = j;
            }
        }

        if(res == 1e9) res = -1;
        cout << res << "\n";
    }
}
accuracy: 1
time_ms: 1220
memory_kb: 3932
final_rank: 5