#include<iostream>
#include<vector>
#include<algorithm>
#include<queue>
#include<cstdlib>

using namespace std;

struct Box{
  int num,d,tre;
  Box(){}
  Box(int n, int d, int t):num(n),d(d),tre(t){}
};
struct State{
  int visited,pos,t,w;
  State();
  State(int v, int p, int t, int w):visited(v),pos(p),t(t),w(w){}
  bool operator < (const State& s) const { return t > s.t;}
};
const int MAX = 16;
const int INF = (1<<25);
int T[(1<<MAX)][MAX];
int pre[(1<<MAX)][MAX];
int n;
vector<Box> V;

void init(){
  fill(T[0],T[0]+(1<<MAX)*MAX,INF);
}

void input(){
  cin >> n;
  for(int i = 0; i < n; i++){
    Box b;
    cin >> b.num >> b.d >> b.tre;
    V.push_back(b);
  }
}

int speed(int d, int w){return d*(70+20*w);}

void dijkstra(){

  priority_queue<State> Q;
  for(int i = 0; i < V.size(); i++){
    T[(1<<i)][i] = 0;
    Q.push(State((1<<i),i,0,V[i].tre));
    pre[(1<<i)][i] = -1;
  }

  while(!Q.empty()){
    State now = Q.top();
    Q.pop();
    
    if(T[now.visited][now.pos] < now.t) continue;

    for(int i = 0; i < V.size(); i++){
      if(!(now.visited&(1<<i))){

	State nex = now;
	nex.visited+=(1<<i);
	nex.pos = i;
	nex.t += speed(abs(V[now.pos].d-V[i].d),now.w);
	nex.w += V[i].tre;
	
	if(T[nex.visited][nex.pos] > nex.t){
	  T[nex.visited][nex.pos] = nex.t;
	  pre[nex.visited][nex.pos] = now.pos;
	  Q.push(State(nex));
	}
      }
    }
    
  }
}

vector<int> makepath(){
  int mincos = INF;
  int minpos;

  for(int i = 0; i < V.size(); i++){
    if(T[(1<<V.size())-1][i] < mincos){
      mincos = T[(1<<V.size())-1][i];
      minpos = i;
    }
  }

  vector<int> path;
  int S = (1<<V.size())-1, v = minpos;

  while(1){
    if(v == -1) break;
    path.push_back(V[v].num);
    int tmp = v;
    v = pre[S][v];
    S -= (1<<tmp);
  }
  reverse(path.begin(),path.end());
  return path;
}

void solve(){

  dijkstra();
  vector<int> path = makepath();

  for(int i = 0; i < path.size(); i++){
    if(i) cout << " ";
    cout << path[i];
  }
  cout << endl;
}


int main(){
  init();
  input();
  solve();
  return 0;
}