/*/ Author: kal013 /*/
// #pragma GCC optimize ("O3")
#include "bits/stdc++.h"
#include "ext/pb_ds/assoc_container.hpp"
#include "ext/pb_ds/tree_policy.hpp"
using namespace std;
using namespace __gnu_pbds;

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

template<class key, class value, class cmp = std::less<key>>
using ordered_map = tree<key, value, cmp, rb_tree_tag, tree_order_statistics_node_update>;
// find_by_order(k)  returns iterator to kth element starting from 0;
// order_of_key(k) returns count of elements strictly smaller than k;

template<class T>
using min_heap = priority_queue<T,vector<T>,greater<T> >; 

struct custom_hash { // Credits: https://codeforces.com/blog/entry/62393
    static uint64_t splitmix64(uint64_t x) {
        // http://xorshift.di.unimi.it/splitmix64.c
        x += 0x9e3779b97f4a7c15;
        x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
        x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
        return x ^ (x >> 31);
    }

    size_t operator()(uint64_t x) const {
        static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
        return splitmix64(x + FIXED_RANDOM);
    }
    size_t operator()(pair<int64_t,int64_t> Y) const{
        static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
        return splitmix64(Y.first * 31 + Y.second + FIXED_RANDOM);
    }
};

template<class T> ostream& operator<<(ostream &os, vector<T> V) {
    os << "[ ";
    for(auto v : V) os << v << " ";
    return os << "]";
}
template<class T> istream& operator>>(istream &is, vector<T>& V) {
    for(auto &e : V)
        is >> e;
    return is;
}

#ifdef __SIZEOF_INT128__
ostream& operator << (ostream &os, __int128 T){
    const static long long N = (long long)(1e18);
    if (T < 0){
        os << '-';
        T *= -1;
    }
    unsigned long long a = T / N, b = T % N;
    if (a == 0)
        return os << b ;
    os << a;
    __int128 mul = 10;
    while( mul*b < N){
        os << '0';
        mul *= 10;
    }
    return os << b;
}
istream& operator >> (istream& is, __int128& T){
    string U;
    is >> U;
    T = 0;
    size_t pos = 0;
    int mul = 1;
    if (U[pos] == '-'){
        ++pos;
        mul *= -1;
    }
    for(; pos < U.size(); ++pos){
        T *= 10;
        T += (U[pos] - '0');
    }
    T *= mul;

    return is;
}
#endif
template<class T> ostream& operator<<(ostream &os, set<T> S){
    os << "{ ";
    for(auto s:S) os<<s<<" ";
    return os<<"}";
}
template<class T> ostream& operator<<(ostream &os, unordered_set<T> S){
    os << "{ ";
    for(auto s:S) os<<s<<" ";
    return os<<"}";
}
template<class T> ostream& operator << (ostream& os, multiset<T> S){
    os << "{ ";
    for(auto s:S) os<<s<<" ";
    return os<<"}";
}
template<class T> ostream& operator<<(ostream &os, ordered_set<T> S){
    os << "{ ";
    for(auto s:S) os<<s<<" ";
    return os<<"}";
}
template<class L, class R> ostream& operator<<(ostream &os, pair<L,R> P) {
    return os << "(" << P.first << "," << P.second << ")";
}
template<class L, class R> ostream& operator<<(ostream &os, map<L,R> M) {
    os << "{ ";
    for(auto m:M) os<<"("<<m.first<<":"<<m.second<<") ";
    return os<<"}";
}
template<class L, class R, class chash = std::hash<R>> ostream& operator<<(ostream &os, unordered_map<L,R,chash> M) {
    os << "{ ";
    for(auto m:M) os<<"("<<m.first<<":"<<m.second<<") ";
    return os<<"}";
}
template<class L, class R, class chash = std::hash<R> > ostream& operator<<(ostream &os, gp_hash_table<L,R,chash> M) {
    os << "{ ";
    for(auto m:M) os<<"("<<m.first<<":"<<m.second<<") ";
    return os<<"}";
}

#define TRACE
#ifdef TRACE
    #define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
    template <typename Arg1>
    void __f(const char* name, Arg1&& arg1){
        cerr << name << " : " << arg1 << endl;
    }
    template <typename Arg1, typename... Args>
    void __f(const char* names, Arg1&& arg1, Args&&... args){
        const char* comma = strchr(names + 1, ',');
        cerr.write(names, comma - names) << " : " << arg1<<" | ";
        __f(comma+1, args...);
    }
#else
    #define trace(...) 1
#endif

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());

inline int64_t random_long(long long l,long long r){
    uniform_int_distribution<int64_t> generator(l,r);
    return generator(rng);
}
inline int64_t random_long(){
    uniform_int_distribution<int64_t> generator(LLONG_MIN,LLONG_MAX);
    return generator(rng);
}


/*/---------------------------Defines----------------------/*/
typedef vector<int> vi;
typedef pair<int,int> pii;

#define For(i,n) for(int i = 0; i < (int) n; ++i)
#define Rep(i,n) for(int i = 1; i <= (int) n; ++i)
#define ll long long
#define F first
#define S second
#define pb push_back
#define endl "\n"
#define all(v) (v).begin(),(v).end()
/*/-----------------------Modular Arithmetic---------------/*/

const int mod=1e9+7;

/*/-----------------------------Code begins----------------------------------/*/
const long long INF = 1e18 + 2;
const int N = 15;
vector<pair<int,int> > mask_x[(1ll<<N) + 4], mask_y[(1ll<<N) + 4];

long long ans_x[(1ll<<N) + 4], ans_y[(1ll<<N) + 4];

long long dp[(1ll<<N) + 4][N + 2];

long long get_mid(const vector<pair<int,int>> & V){
	long long tot = 0;
	for(auto e: V){
		tot += e.second;
	}

	long long cur = 0;

	for(auto e: V){
		cur += e.second;
		if (2*cur >= tot)
			return e.first;
	}
}

long long get_val(const vector<pair<int,int>> & V){
	long long t = get_mid(V);
	long long ans = 0;
	for(auto e: V){
		ans += abs(e.first - t) * 1ll * e.second;
	}

	return ans;
}



void solve(){
    int n;
    cin >> n;
    vector<int> x(n),y(n),p(n);

    for(int i = 0; i < n; ++i){
    	cin >> x[i] >> y[i] >> p[i];
    }
    for(int i = 1; i < (1ll<<n); ++i){
    	for(int j = 0; j <= n; ++j){
    		dp[i][j] = INF;
    	}
    }

    for(int i = 1; i < (1ll << n); ++i){
    	dp[i][0] = 0;
    	for(int j = 0; j < n; ++j){
    		if (i&(1ll<<j)){
    			mask_x[i].push_back({x[j],p[j]});
    			mask_y[i].push_back({y[j],p[j]});

    			dp[i][0] += min(abs(x[j]), abs(y[j])) * 1ll * p[j];
    		}
    	}

    	sort(all(mask_x[i]));
    	sort(all(mask_y[i]));

    	ans_x[i] = get_val(mask_x[i]);
    	ans_y[i] = get_val(mask_y[i]);

    	dp[i][1] = min(ans_x[i], ans_y[i]);
    }
    for(int i = 0; i <= n; ++i){
    	dp[0][i] = 0;
    }

    // trace(dp[6][1], dp[1][0]);

    for(int i = 1; i < (1ll << n); ++i){
    	for(int k = 2; k <= n; ++k){
    		dp[i][k] = dp[i][k-1];
    	}
    	for(int j = i; j > 0; j = (j-1)&i){
    		for(int k = 1; k <= n; ++k){
    			dp[i][k] = min(dp[i][k],dp[i ^ j][k - 1] + min(ans_x[j],ans_y[j]));
    			dp[i][k] = min(dp[i][k], dp[i ^ j][k] + dp[j][0]);
    		}
    		// trace(i,j, dp[i^j][0], dp[j][1]);
    	}

    }

    for(int i = 0; i <= n; ++i){
    	cout << dp[(1ll<<n) - 1][i] << endl;
    }




}
int main(){
    // Use "set_name".max_load_factor(0.25);"set_name".reserve(512); with unordered set
    // Or use gp_hash_table<X,null_type>
    ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
    cout<<fixed<<setprecision(25);
    cerr<<fixed<<setprecision(10);
    auto start = std::chrono::high_resolution_clock::now();
    int t=1;
    while(t--) {
        solve();
    }
    auto stop = std::chrono::high_resolution_clock::now(); 
    auto duration = std::chrono::duration_cast<std::chrono::nanoseconds>(stop - start); 
    
    // cerr << "Time taken : " << ((long double)duration.count())/((long double) 1e9) <<"s "<< endl;     
}

Measured memory_bytes: 16288