#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
void generate(int n, int open1, int close1, int open2, int close2, string &curr, vector<string> &result) {
if (curr.size() == n) {
result.push_back(curr);
return;
}
// Try adding '(' if there are available open brackets
if (open1 > 0) {
curr.push_back('(');
generate(n, open1 - 1, close1, open2, close2, curr, result);
curr.pop_back();
}
// Try adding ')' if it forms a valid pair
if (close1 > open1) {
curr.push_back(')');
generate(n, open1, close1 - 1, open2, close2, curr, result);
curr.pop_back();
}
// Try adding '[' if there are available open brackets
if (open2 > 0) {
curr.push_back('[');
generate(n, open1, close1, open2 - 1, close2, curr, result);
curr.pop_back();
}
// Try adding ']' if it forms a valid pair
if (close2 > open2) {
curr.push_back(']');
generate(n, open1, close1, open2, close2 - 1, curr, result);
curr.pop_back();
}
}
int main() {
int N;
cin >> N;
if (N % 2 != 0) return 0; // Odd length can't have valid bracket sequence
vector<string> result;
string curr;
generate(N, N / 2, N / 2, N / 2, N / 2, curr, result);
sort(result.begin(), result.end()); // Ensure lexicographical order
for (const string &s : result) {
cout << s << endl;
}
return 0;
}