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.
#include <bits/stdc++.h>
const int inf = 0x3f3f3f3f, Inf = 0x7fffffff;
const long long INF = 0x7fffffffffffffff;
const double eps = 1e-10;
unsigned int seed = 19260817;
const unsigned int _RAND_MAX_ = 4294967295u;
__inline__ __attribute__((always_inline)) unsigned int Rand() {
  return seed = seed * 998244353u + 1000000007u;
}
template <typename _Tp>
_Tp gcd(const _Tp &a, const _Tp &b) {
  return (!b) ? a : gcd(b, a % b);
}
template <typename _Tp>
__inline__ __attribute__((always_inline)) _Tp abs(const _Tp &a) {
  return a > 0 ? a : -a;
}
template <typename _Tp>
__inline__ __attribute__((always_inline)) _Tp max(const _Tp &a, const _Tp &b) {
  return a < b ? b : a;
}
template <typename _Tp>
__inline__ __attribute__((always_inline)) _Tp min(const _Tp &a, const _Tp &b) {
  return a < b ? a : b;
}
template <typename _Tp>
__inline__ __attribute__((always_inline)) void chmax(_Tp &a, const _Tp &b) {
  (a < b) && (a = b);
}
template <typename _Tp>
__inline__ __attribute__((always_inline)) void chmin(_Tp &a, const _Tp &b) {
  (a > b) && (a = b);
}
template <typename _Tp>
__inline__ __attribute__((always_inline)) bool _cmp(const _Tp &a,
                                                    const _Tp &b) {
  return abs(a - b) <= eps;
}
template <typename _Tp>
__inline__ __attribute__((always_inline)) void read(_Tp &x) {
  register char ch(getchar());
  bool f(false);
  while (ch < 48 || ch > 57) f |= ch == 45, ch = getchar();
  x = ch & 15, ch = getchar();
  while (ch >= 48 && ch <= 57)
    x = (((x << 2) + x) << 1) + (ch & 15), ch = getchar();
  if (f) x = -x;
}
template <typename _Tp, typename... Args>
__inline__ __attribute__((always_inline)) void read(_Tp &t, Args &...args) {
  read(t);
  read(args...);
}
__inline__ __attribute__((always_inline)) int read_str(char *s) {
  register char ch(getchar());
  while (ch == ' ' || ch == '\r' || ch == '\n') ch = getchar();
  register char *tar = s;
  *tar = ch, ch = getchar();
  while (ch != ' ' && ch != '\r' && ch != '\n' && ch != EOF)
    *(++tar) = ch, ch = getchar();
  return tar - s + 1;
}
const int N = 55;
int a[N];
std::bitset<1250005> f[53][27];
bool used[N];
void print(int n, int rest, int x) {
  if (n) {
    if (f[n - 1][rest].test(x)) {
      print(n - 1, rest, x);
    } else {
      print(n - 1, rest - 1, x - a[n]);
      used[n] = 1;
    }
  }
}
int main() {
  int n;
  read(n);
  for (int i = 1; i <= n << 1; ++i) read(a[i]);
  std::sort(a + 1, a + (n << 1) + 1);
  std::swap(a[1], a[n << 1]);
  std::swap(a[2], a[(n << 1) - 1]);
  int len = (n << 1) - 2;
  std::sort(a + 1, a + len + 1);
  int sum = 0;
  f[0][0].set(0);
  for (int i = 1; i <= len; ++i) {
    sum += a[i];
    for (int k = min(i, n - 1); k >= 1; --k) {
      f[i][k] = f[i - 1][k] | (f[i - 1][k - 1] << a[i]);
    }
    f[i][0].set(0);
  }
  int ans = inf;
  for (int i = sum >> 1; i >= 0; --i) {
    if (f[len][n - 1].test(i)) {
      ans = i;
      break;
    }
  }
  print(len, n - 1, ans);
  std::vector<int> v1, v2;
  for (int i = 1; i <= len; ++i) {
    if (used[i]) {
      v1.push_back(a[i]);
    } else {
      v2.push_back(a[i]);
    }
  }
  v1.push_back(a[n << 1]);
  v2.push_back(a[(n << 1) - 1]);
  std::sort(v1.begin(), v1.end());
  std::sort(v2.begin(), v2.end());
  for (std::vector<int>::iterator it = v1.begin(); it != v1.end(); ++it) {
    printf("%d ", *it);
  }
  printf("\n");
  for (std::vector<int>::reverse_iterator it = v2.rbegin(); it != v2.rend();
       ++it) {
    printf("%d ", *it);
  }
  printf("\n");
  return 0;
}
