#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<vector>
#include<queue>
#include<stack>
#include<string>
#include<map>
#include<set>
#define rep(i,n) for(int i=0;i<n;i++)
#define INF 1<<29
#define MAX 15

using namespace std;
double d[MAX];
double km[MAX],kazu[MAX],num[MAX];
double dp[1<<MAX][MAX];
int n;
vector<int> prev[(1<<MAX)][MAX];  //同じく経路復元用　最短経路の直前の頂点を示す
//vector<int> path[(1<<n)][MAX];  //経路復元用
void solve();

int main(){
  rep(i,MAX+1)d[i]=INF;
  cin >> n;
  for(int i=0;i<n;i++)
    {
      cin >> num[i] >> d[i] >> kazu[i];
      kazu[i]*=20;
    }

  solve();


}

void solve()
{

  rep(i,(1<<n))rep(j,n)dp[i][j]=INF;

  rep(i,n)
    {
    dp[1<<i][i]=0.0;
    prev[1<<i][i].push_back(i);
    }
  double cost;

  for(int S=1;S<(1<<n);S++)
    {
      for(int i=0;i<n;i++)
	{
	  for(int j=0;j<n;j++)
	    {
	      if(!(S & (1<<j)))
		{
		  cost = ((70.0+kazu[i])/2000.0)*abs(d[i] - d[j]);
		  if(dp[S|(1<<j)][j] > dp[S][i] + cost)
		    {
		      dp[S|(1<<j)][j]=dp[S][i]+cost;
		      prev[S|(1<<j)][j]=prev[S][i];
		      prev[S|(1<<j)][j].push_back(j);
		    }
		}
	    }
	}
    }
    
  double mini = INF;
  vector<int> path;

  for(int i=0;i<n;i++){
    if(mini > dp[(1<<n)-1][i]){
      mini = dp[(1<<n)-1][i];
      path = prev[(1<<n)-1][i];
    }
  }

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



}