#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
// 定義選手結構
struct Athlete {
int id;
double time;
// 依成績由好到壞(時間由小到大)排序
bool operator<(const Athlete& other) const {
return time < other.time;
}
};
void solve() {
int n;
if (!(cin >> n)) return;
vector<Athlete> athletes(n);
for (int i = 0; i < n; ++i) {
cin >> athletes[i].id >> athletes[i].time;
}
// 1. 依實力從最優秀開始排序
sort(athletes.begin(), athletes.end());
int num_groups = n / 8;
vector<vector<Athlete>> groups(num_groups);
// 2. S型常態分組
bool forward = true; // 控制蛇行方向
int g_idx = 0; // 目前要分發的組別
for (int i = 0; i < n; ++i) {
groups[g_idx].push_back(athletes[i]);
if (forward) {
if (g_idx == num_groups - 1) {
forward = false; // 到底了,下一輪反向
} else {
g_idx++;
}
} else {
if (g_idx == 0) {
forward = true; // 到頭了,下一輪正向
} else {
g_idx--;
}
}
}
// 3. 賽道編排與輸出
// 賽道 1~8 分別對應組內排序後的第幾名 (0-indexed)
// 題目順序 4 5 3 6 2 7 1 8 對應名次為:第4道是第0名, 第5道是第1名, 第3道是第2名...
int lane_to_rank[] = {6, 4, 2, 0, 1, 3, 5, 7};
for (int i = 0; i < num_groups; ++i) {
// 輸出組別 (從 1 開始)
cout << (i + 1);
// 依第1道到第8道的順序輸出選手 ID
for (int j = 0; j < 8; ++j) {
int rank_idx = lane_to_rank[j];
cout << " " << groups[i][rank_idx].id;
}
cout << "\n";
}
}
int main() {
// 最佳化輸入輸出
ios_base::sync_with_stdio(false);
cin.tie(NULL);
solve();
return 0;
}