#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <utility>
#include <set>
#include <map>
#include <cmath>
#include <queue>
#include <cstdio>
#include <limits>
#include <stack>
#define rep(i,n) for(int i = 0; i < n; ++i)
#define rep1(i,n) for(int i = 1; i <= n; ++i)
using namespace std;
template<class T>bool chmax(T &a, const T &b) { if(a < b){ a = b; return 1; } return 0; }
template<class T>bool chmin(T &a, const T &b) { if(a > b){ a = b; return 1; } return 0; }
template<class T> inline int  sz(T &a) { return a.size(); }
using ll = long long; using ld = long double;
using pi = pair<int,int>; using pl = pair<ll,ll>;
using vi = vector<int>; using vvi = vector<vi>;
using vl = vector<ll>; using vvl = vector<vl>;
const int inf = numeric_limits<int>::max();
const ll infll = numeric_limits<ll>::max();
int main()
{
  int n; cin >> n;
  vi a(2*n);
  rep(i,2*n) cin >> a[i];
  vector<pi> p(2*n);
  rep(i,2*n) p[i] = {a[i], i};
  sort(p.begin(),p.end());
  vi b(2*n, 0);
  rep(i,n) {
    b[p[i].second] = 1;
  }
  vector<char> res(2*n);
  stack<pi> sta;
  rep(i,2*n) {
    if(!sta.empty()) {
      if(sta.top().first != b[i]) {
        res[sta.top().second] = '(';
        res[i] = ')';
        sta.pop();
      }
      else {
        sta.push({b[i], i});
      }
    }
    else {
      sta.push({b[i], i});
    }
  }
  rep(i,2*n) cout << res[i];
  cout << "\n";
  return 0;
}

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using P = pair<ll,ll>;
#define rep(i,n) for(int (i)=0;(i)<(n);(i)++)
#define rep2(i,m,n) for(int (i)=(m);(i)<(n);(i)++)
#define ALL(obj) (obj).begin(), (obj).end()
#define rALL(obj) (obj).rbegin(), (obj).rend()
const ll INF = 1LL<<60;//1152921504606846976
const int mod = 1000000007;

vector<vector<ll>> G;
vector<bool> vis;
vector<ll> dist;
ll dmax, farnode;
void dfs(ll r, ll d){
    vis[r]=true;
    dist[r]=d;
    if(d>dmax){
        dmax=d;
        farnode=r;
    }
    for(ll c:G[r])if(!vis[c])dfs(c,d+1);

}

ll u,v;
vector<bool> st_has_v;
void dfs_findv(ll r){
    vis[r]=true;
    if(r==v)st_has_v[r]=true;
    for(ll c:G[r])if(!vis[c]){
        dfs_findv(c);
        if(st_has_v[c])st_has_v[r]=true;
    }
}

ll now;
vector<ll> label;
void dfs_labelling(ll r){
    vis[r]=true;
    label[r]=now;
    ll hasv = -1;
    for(ll c:G[r])if(!vis[c]){
        if(st_has_v[c]){hasv=c;continue;}
        now++;
        dfs_labelling(c);
        now++;
    }
    if(hasv!=-1){
        now++;
        dfs_labelling(hasv);
        now++;
    }
    
}


int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    ll n; cin>>n;
    G.resize(n);
    
    rep(i,n-1){
        ll a,b;cin>>a>>b;
        a--;b--;
        G[a].push_back(b);
        G[b].push_back(a);
    }
    
    //直径と両端u,vを求める
    vis=vector<bool>(n,false);
    dist=vector<ll>(n,INF);
    dmax = 0;
    dfs(0,0);
    u = farnode;
    vis=vector<bool>(n,false);
    dist=vector<ll>(n,INF);
    dmax=0;
    dfs(u,0);
    v = farnode;
    ll R = dmax;
    //uからDFS、subtreeにvがあるか判定
    vis=vector<bool>(n,false);
    st_has_v = vector<bool>(n,false);
    dfs_findv(u);
    //uからDFS、vがあるsubtreeは最後に回す
    //貪欲にラベルをつけていく
    vis=vector<bool>(n,false);
    label=vector<ll>(n);
    now=1;
    dfs_labelling(u);

    for(ll x:label)cout<<x<<" ";

    return 0;
}