#include <iostream>
#include <vector>
#include <map>
#include <cmath>

using namespace std;

#define MN 15

struct E {
    int from, to;
    double dist;
    E() {};
    E(int from, int to, double dist) : from(from), to(to), dist(dist) {}
};

struct V {
    double dist;
    int w;
};


map<int, int> index;
map<int, int> rindex;
V G[MN];

struct A {
    double v;
    vector<int> path;
    bool operator<(const A& o) const {
        return v < o.v;
    }
    A() {
        v = 1e10;
    }
};

int n;
double cost(int from, int to, int used) {
    double w = 0;
    for (int i = 0; i < n; i++) {
        if (used & (1<<i)) {
            w += G[i].w;
        }
    }
    return abs(G[from].dist - G[to].dist) / ( 2000.0 / (70.0 + w) );
}

A memo[MN][(1<<MN)];
A solve(int m, int used) {
    if (memo[m][used].v != 1e10) return memo[m][used];
    if (used == (1<<n) - 1) {
        A ans;
        ans.v = 0;
        ans.path.push_back(m);
        return ans;
    }
    A ans;
    for (int i = 0; i < n; i++) {
        if (not (used & (1<<i))) {
            A a = solve(i, used | (1<<i));
            a.v += cost(m, i, used);
            ans = min(ans, a);
        }
    }
    ans.path.push_back(m);
    return memo[m][used] = ans;
}

int main() {
    cin >> n;
    for (int i = 0; i < n; i++) {
        int number, dist, w; cin >> number >> dist >> w;
        index[number] = i;
        rindex[i] = number;
        G[i].dist = dist;
        G[i].w = w * 20;
    }
    A ans;
    for (int i = 0; i < n; i++) {
        A c = solve(i, (1<<i));
        ans = min(ans, c);
    }
    bool isFirst = true;
    for (int i = ans.path.size() - 1; i >= 0; i--) {
        if (isFirst) {
            isFirst = false;
            cout << rindex[ans.path[i]];
        } else {
            cout << ' ' << rindex[ans.path[i]];
        }
    }
    cout << endl;
    return 0;
}