#include <bits/stdc++.h>
namespace std {
template <typename _Key, typename _Hash = std::hash<_Key>>
using hash_set = std::unordered_set<_Key, _Hash>;
template <typename _Key, typename _Hash = std::hash<_Key>>
using hash_mset = std::unordered_multiset<_Key, _Hash>;
template <typename _Key, typename _Val, typename _Hash = std::hash<_Key>>
using hash_map = std::unordered_map<_Key, _Val, _Hash>;
template <typename _Key, typename _Hash = std::hash<_Key>>
using hash_mmap = std::unordered_multimap<_Key, _Hash>;
template <typename _Key, typename _Cmp = std::less<_Key>>
using mset = std::multiset<_Key, _Cmp>;
template <typename _Key, typename _Val, typename _Cmp = std::less<_Key>>
using mmap = std::multimap<_Key, _Val, _Cmp>;
template <typename _Key>
using rset = std::set<_Key, std::greater<_Key>>;
template <typename _Key>
using rmset = std::multiset<_Key, std::greater<_Key>>;
template <typename _Key, typename _Val>
using rmap = std::map<_Key, std::greater<_Key>>;
template <typename _Key, typename _Val>
using rmmap = std::multimap<_Key, _Val, std::greater<_Key>>;
static std::ostream& fdeb = cerr;
struct NullOstream {};
template <typename T>
NullOstream& operator<<(NullOstream& out, const T&) {
  return out;
}
NullOstream& operator<<(NullOstream& out, std::ostream& (*)(std::ostream&)) {
  return out;
}
static NullOstream deb;
static NullOstream debl;
template <int _Ind, typename... _Args>
struct __TuplePrinter {
  static void print(ostream& out, const tuple<_Args...>& t) {
    __TuplePrinter<_Ind - 1, _Args...>::print(out, t);
    out << ' ' << get<_Ind>(t);
  }
};
template <typename... _Args>
struct __TuplePrinter<0, _Args...> {
  static void print(ostream& out, const tuple<_Args...>& t) {
    out << '(' << get<0>(t);
  }
};
template <typename... _Args>
ostream& operator<<(ostream& out, const tuple<_Args...>& t) {
  __TuplePrinter<sizeof...(_Args) - 1, _Args...>::print(out, t);
  out << ')';
  return out;
}
template <typename _T1, typename _T2>
ostream& operator<<(ostream& out, const pair<_T1, _T2>& p) {
  return out << '(' << p.first << ' ' << p.second << ')';
}
using uchar = unsigned char;
using ushort = unsigned short;
using uint = unsigned int;
using lld = long long;
using ulld = unsigned long long;
static const int MOD = 1e9 + 7;
static const int INF = MOD;
static const lld HASHP = 37;
}  // namespace std
using namespace std;
struct BraceInfo {
  char s;
  int x;
  int d = 0;
};
int main() {
  std::ios::sync_with_stdio(false);
  std::cin.tie(nullptr);
  int N;
  std::cin >> N;
  std::cin >> std::ws;
  std::vector<BraceInfo> braces(N);
  int maxDepth = 0;
  int currentDepth = 0;
  int currentX = 0;
  for (int i = 0; i < N; ++i) {
    auto& binfo = braces[i];
    binfo.s = std::cin.get();
    binfo.x = currentX++;
    if (binfo.s == ']') {
      if (braces[i - 1].s == '[') {
        binfo.x = (currentX += 2);
        ++currentX;
      }
      binfo.d = --currentDepth;
    } else {
      binfo.d = currentDepth++;
    }
    maxDepth = std::max(maxDepth, currentDepth);
  }
  for (const auto& v : braces) {
    deb << v.x;
  }
  debl;
  int maxH = (maxDepth - 1) * 2 + 3;
  debl << maxH;
  for (int ry = 0; ry < maxH; ++ry) {
    int y = std::min(ry, maxH - ry - 1);
    debl << ry << y;
    int bindex = 0;
    for (int x = 0; x <= braces.back().x; ++x) {
      const auto& cbrace = braces[bindex];
      deb << cbrace.x << x << y;
      if (cbrace.x != x || y < cbrace.d) {
        const BraceInfo* pbrace = (bindex > 0 ? &braces[bindex - 1] : nullptr);
        const BraceInfo* nbrace =
            (bindex + 1 < braces.size() ? &braces[bindex + 1] : nullptr);
        if (pbrace && pbrace->x == x - 1 && pbrace->d == y &&
            pbrace->s == '[') {
          std::cout.put('-');
        } else if (nbrace && nbrace->x == x + 1 && nbrace->d == y &&
                   nbrace->s == ']') {
          std::cout.put('-');
        } else if (pbrace && pbrace->s == '[' && cbrace.s == ']' &&
                   cbrace.d == y && cbrace.x == x + 1) {
          std::cout.put('-');
        } else {
          std::cout.put(' ');
        }
      } else if (y == cbrace.d) {
        std::cout.put('+');
      } else {
        std::cout.put('|');
      }
      if (cbrace.x == x) {
        ++bindex;
      }
    }
    std::cout << '\n';
  }
  std::cout << std::flush;
  return 0;
}
