#include <iostream>
#include <vector>
#include <map>
#include <algorithm>
using namespace std;

const double INF = 1e+9;
const double EPS = 1e-9;
const int MAX_N = 15;

int main(){
	int n;
	cin >> n;
	
	int ID[MAX_N], d[MAX_N], w[MAX_N];
	for(int i=0 ; i < n ; i++ ){
		cin >> ID[i] >> d[i] >> w[i];
	}
	
	// dp[s][i] := 訪れた蔵 s(集合), 現在の蔵 i のときの最小の時間
	double dp[1<<MAX_N][MAX_N];
	// ws[s] := 訪れた蔵 s(集合)から千両箱の重さを返す.
	int ws[1<<MAX_N];
	// p[s][i] := 訪れた蔵 s(集合), 現在の蔵 i のときの一つ前の蔵
	int p[1<<MAX_N][MAX_N];
	
	// 任意の集合に対して重さを計算しておく
	for(int k=0 ; k < (1<<n) ; k++ ){
		for(int i=0 ; i < n ; i++ ){
			ws[k|(1<<i)] = ws[k] + 20 * w[i];
		}
	}
	
	// 初期化
	for(int s = 1 ; s < (1<<n) ; s++ ){
		fill( dp[s] , dp[s]+n , INF );
	}
	// bitDP
	for(int s=0 ; s < (1<<n) ; s++){
		for(int j=0 ; j < n ; j++ ){
			for(int i=0 ; i < n ; i++ ){
				if( (s >> i & 1) == 0 ){
					double v = dp[s][j] + abs(d[i]-d[j]) / 2000.0 * (70 + ws[s]);
					if( v + EPS < dp[s|1<<i][i] ){
						dp[s|1<<i][i] = v;
						p[s|1<<i][i] = j;
					}
				}
			}
		}
	}
		
	// path を求める.
	int m = 0;
	for(int i=0 ; i < n ; i++ ){
		if( dp[(1<<n)-1][i] + EPS < dp[(1<<n)-1][m] ){
			m=i;
		}
	}
	vector<int> path;
	for(int i=m, sup=(1<<n)-1 ; sup != 0 ; ){
		path.push_back( i );
		int j = p[sup][i];
		sup &= ~(1<<i);
		i=j;
	}
	reverse( path.begin() , path.end() );
	for(int i=0 ; i < path.size() ; i++ ){
		cout << ID[ path[i] ];
		if( i == path.size()-1 ){
			cout << endl;
		}else{
			cout << " ";
		}
	}
}