Problem: Kolya has a turtle and a field of size 2 × n. The field rows are numbered from 1 to 2 from top to bottom, while the columns are numbered from 1 to n from left to right.

Suppose in each cell of the field there is a lettuce leaf. The energy value of lettuce leaf in row i and column j is equal to a_{i,j}. The turtle is initially in the top left cell and wants to reach the bottom right cell. The turtle can only move right and down and among all possible ways it will choose a way, maximizing the total energy value of lettuce leaves (in case there are several such paths, it will choose any of them).

Kolya is afraid, that if turtle will eat too much lettuce, it can be bad for its health. So he wants to reorder lettuce leaves in the field, so that the energetic cost of leaves eaten by turtle will be minimized.

Input

The first line contains an integer n (2 ≤ n ≤ 25) — the length of the field.

The second line contains n integers a_{1, i} (0 ≤ a_{1, i} ≤ 50 000), the energetic cost of lettuce leaves in the first row of the field.

The third line contains n integers a_{2, i} (0 ≤ a_{2, i} ≤ 50 000), the energetic cost of lettuce leaves in the second row of the field.

Output

Print two lines with n integers in each — the optimal reordering of lettuce from the input data.

In case there are several optimal ways to reorder lettuce, print any of them.

Examples

Input


2
1 4
2 3


Output


1 3 
4 2 


Input


3
0 0 0
0 0 0


Output


0 0 0 
0 0 0 


Input


3
1 0 1
0 0 0


Output


0 0 1
0 1 0

Note

In the first example, after reordering, the turtle will eat lettuce with total energetic cost 1+4+2 = 7.

In the second example, the turtle will eat lettuce with energetic cost equal 0.

In the third example, after reordering, the turtle will eat lettuce with total energetic cost equal 1.

Solution (in CPP):

Solution:
#include <bits/stdc++.h>
using namespace std;
const int MAXSUM = 50000 * 24 + 10;
void my_sort(vector<pair<int, int>>& V) {
  vector<int> x(MAXSUM, -1);
  for (int i = 0; i < (int)V.size(); i++) x[V[i].first] = V[i].second;
  V.clear();
  for (int i = 0; i < MAXSUM; i++)
    if (x[i] != -1) V.push_back({i, x[i]});
}
vector<vector<pair<int, int>>> calc(vector<int>& x) {
  int n = x.size();
  vector<vector<pair<int, int>>> V(n + 1);
  for (int mask = 0; mask < (1 << n); mask++) {
    int sum = 0;
    for (int i = 0; i < n; i++)
      if ((1 << i) & mask) sum += x[i];
    V[__builtin_popcount(mask)].push_back({sum, mask});
  }
  for (int i = 0; i <= n; i++) my_sort(V[i]);
  return V;
}
void print(vector<int>& x, int mask, bool reversed) {
  int n = x.size();
  vector<int> y;
  for (int i = 0; i < n; i++)
    if ((1 << i) & mask) y.push_back(x[i]);
  if (reversed) reverse(y.begin(), y.end());
  for (int i = 0; i < (int)y.size(); i++) cout << y[i] << " ";
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  int n;
  cin >> n;
  vector<int> x(2 * n);
  for (int i = 0; i < 2 * n; i++) cin >> x[i];
  sort(x.begin(), x.end());
  vector<int> a(n - 1), b(n - 1);
  for (int i = 0; i < n - 1; i++) {
    a[i] = x[2 + i];
    b[i] = x[n + 1 + i];
  }
  auto A = calc(a);
  auto B = calc(b);
  int goal = (A[n - 1][0].first + B[n - 1][0].first) / 2;
  int best = -1, mask_a, mask_b;
  for (int k = 0; k < n; k++) {
    int j = (int)B[n - 1 - k].size() - 1;
    for (int i = 0; i < (int)A[k].size(); i++) {
      while (j >= 0 && A[k][i].first + B[n - 1 - k][j].first > goal) j--;
      if (j == -1) break;
      int tmp = A[k][i].first + B[n - 1 - k][j].first;
      if (tmp > best) {
        best = tmp;
        mask_a = A[k][i].second;
        mask_b = B[n - 1 - k][j].second;
      }
    }
  }
  cout << x[0] << " ";
  print(a, mask_a, false);
  print(b, mask_b, false);
  cout << "\n";
  print(b, ~mask_b, true);
  print(a, ~mask_a, true);
  cout << x[1] << "\n";
  return 0;
}