Problem:
Problem F:
Dr. Podboq or: How We Became Asymmetric
After long studying how embryos of organisms become asymmetric during
their development, Dr. Podboq, a famous biologist, has reached his new
hypothesis.  Dr. Podboq is now preparing a poster for the coming
academic conference, which shows a tree representing the development
process of an embryo through repeated cell divisions starting from one
cell.  Your job is to write a program that transforms given trees into
forms satisfying some conditions so that it is easier for the audience
to get the idea.
A tree representing the process of cell divisions has a form described
below.
The starting cell is represented by a circle placed at the top.
Each cell either terminates the division activity or divides into
two cells.  Therefore, from each circle representing a cell, there are
either no branch downward, or two branches down to its
two child cells.
Below is an example of such a tree.
Figure F-1: A tree representing a process of cell divisions
According to Dr. Podboq's hypothesis, we can determine which cells
have stronger or weaker asymmetricity by looking at the structure of
this tree representation.  First, his hypothesis defines "left-right
similarity" of cells as follows:
The left-right similarity of a cell that did not divide further is
0.
For a cell that did divide further, we collect the partial
trees starting from its child or descendant cells, and count how
many kinds of structures they have.  Then, the left-right similarity of
the cell is defined to be the ratio of the number of structures
that appear both in
the right child side and the left child side.  We regard two trees
have the same structure if we can make them have exactly the same shape by
interchanging two child cells of arbitrary cells.
For example, suppose we have a tree shown below:
Figure F-2: An example tree
The left-right similarity of the cell A is computed as follows.
First, within the descendants of the cell B, which is the left child
cell of A, the following three kinds of structures appear.  Notice that
the rightmost structure appears three times, but when we count the number
of structures, we count it only once.
Figure F-3: Structures appearing within the descendants of the cell B
On the other hand, within the descendants of the cell C, which is the
right child cell of A, the following four kinds of structures appear.
Figure F-4: Structures appearing within the descendants of the cell C
Among them, the first, second, and third ones within the B side are
regarded as the same structure as the second, third, and fourth ones
within the C side, respectively.  Therefore, there are four structures
in total, and three among them are common to the left side and the
right side, which means the left-right similarity of A is 3/4.
Given the left-right similarity of each cell, Dr. Podboq's hypothesis
says we can determine which of the cells
X
and
Y
has
stronger asymmetricity by the following rules.
If
X
and
Y
have different left-righ
...(truncated)

Submitted solutions:

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<ll,ll> pi;
typedef vector<ll> vi;
#define FOR(i,l,r) for(ll i=l;i<r;i++)
#define REP(i,n) FOR(i,0,n)
#define ALL(A) A.begin(),A.end()
template<typename T>bool chmin(T&a,T b){if(a>b){a=b;return 1;}return 0;}
template<typename T>using min_priority_queue=priority_queue<T,vector<T>,greater<T>>;
int main(){
    while(1){
        string S;
        getline(cin,S);
        if(S[0]=='0')return 0;
        ll N=S.size();
        vi par(N);
        {
            stack<ll>st;
            REP(i,N){
                if(S[i]=='(')st.emplace(i);
                if(S[i]==')')par[st.top()]=i,st.pop();
            }
        }
        map<string,vector<ld>>memo;
        memo["x"]={0};
        function<vector<string>(ll,ll)>dfs=[&](ll l,ll r){
            if(r-l==1){
                assert(S[l]=='x');
                return vector<string>{"x"};
            }
            assert(par[l]==r-1);
            ll t=l+2;
            if(S[l+1]=='(')t=par[l+1]+1;
            assert(S[t]==' ');
            auto left=dfs(l+1,t),right=dfs(t+1,r-1);
            auto all=left;
            all.insert(all.end(),ALL(right));
            sort(ALL(all));
            all.erase(unique(ALL(all)),all.end());
            ll cnt=0;
            for(auto s:all)if(binary_search(ALL(left),s)&&binary_search(ALL(right),s))cnt++;
            auto L=memo[S.substr(l+1,t-l-1)],R=memo[S.substr(t+1,r-t-2)];
            if(L>R){
                swap(L,R);
                S=S.substr(0,l)+"("+S.substr(t+1,r-t-2)+" "+S.substr(l+1,t-l-1)+")"+S.substr(r,N-r+1);
                t=l+r-t-1;
            }
            memo[S.substr(l,r-l)]={(ld)cnt/all.size()};
            memo[S.substr(l,r-l)].insert(memo[S.substr(l,r-l)].end(),ALL(L));
            memo[S.substr(l,r-l)].insert(memo[S.substr(l,r-l)].end(),ALL(R));
            all.emplace_back(S.substr(l,r-l));
            sort(ALL(all));
            return all;
        };
        dfs(0,N);
        {
            stack<ll>st;
            REP(i,N){
                if(S[i]=='(')st.emplace(i);
                if(S[i]==')')par[st.top()]=i,st.pop();
            }
        }
        bool left=1;
        function<void(ll,ll)>dfs2=[&](ll l,ll r){
            if(r-l==1)return;
            //cout<<l<<" "<<r<<endl;
            //cout<<S.substr(l,r-l)<<endl;
            assert(par[l]==r-1);
            ll t=l+2;
            if(S[l+1]=='(')t=par[l+1]+1;
            assert(S[t]==' ');
            if(left){
                left=1;
                dfs2(l+1,t);
                left=0;
                dfs2(t+1,r-1);
            }
            else{
                left=0;
                dfs2(l+1,t);
                left=1;
                dfs2(t+1,r-1);
                S=S.substr(0,l)+"("+S.substr(t+1,r-t-2)+" "+S.substr(l+1,t-l-1)+")"+S.substr(r,N-r+1);
            }
        };
        dfs2(0,N);
        cout<<S<<endl;
    }
}
accuracy: 1
time_ms: 10
memory_kb: 3584
final_rank: 10

code_snippet: #line 2 "cp-library/src/cp-template.hpp"
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using uint = unsigned int;
using ull  = unsigned long long;
using i32 = int;
using u32 = unsigned int;
using i64 = long long;
using u64 = unsigned long long;
using i128 = __int128_t;
template < class T > bool chmin(T& a, T b) { if(a > b) { a = b; return true; } return false; }
template < class T > bool chmax(T& a, T b) { if(a < b) { a = b; return true; } return false; }
template < class T, class U > T ceil (T x, U y) { return (x > 0 ? (x + y - 1) / y :           x / y); }
template < class T, class U > T floor(T x, U y) { return (x > 0 ?           x / y : (x - y + 1) / y); }
int popcnt(i32 x) { return __builtin_popcount(x); }
int popcnt(u32 x) { return __builtin_popcount(x); }
int popcnt(i64 x) { return __builtin_popcountll(x); }
int popcnt(u64 x) { return __builtin_popcountll(x); }

#line 2 "cp-library/src/utility/rep_itr.hpp"
template < class T > struct itr_rep {
    T i, d;
    constexpr itr_rep(const T i) noexcept : i(i), d(1) {}
    constexpr itr_rep(const T i, const T d) noexcept : i(i), d(d) {}
    void operator++() noexcept { i += d; }
    constexpr int operator*() const noexcept { return i; }
    constexpr bool operator!=(const itr_rep x) const noexcept { return d > 0 ? i < x.i : i > x.i; }
};

template < class T > struct rep {
    const itr_rep< T > s, t;
    constexpr rep(const T t) noexcept : s(0), t(t) {}
    constexpr rep(const T s, const T t) noexcept : s(s), t(t) {}
    constexpr rep(const T s, const T t, const T d) noexcept : s(s, d), t(t, d) {}
    constexpr auto begin() const noexcept { return s; }
    constexpr auto end  () const noexcept { return t; }
};

template < class T > struct revrep {
    const itr_rep < T > s, t;
    constexpr revrep(const T t) noexcept : s(t - 1, -1), t(-1, -1) {}
    constexpr revrep(const T s, const T t) noexcept : s(t - 1, -1), t(s - 1, -1) {}
    constexpr revrep(const T s, const T t, const T d) noexcept : s(t - 1, -d), t(s - 1, -d) {}
    constexpr auto begin() const noexcept { return s; }
    constexpr auto end  () const noexcept { return t; }
};
#line 3 "cp-library/src/utility/io.hpp"

/* 128bit integer */
istream& operator>>(istream& is, i128& x) {
    std::string s; is >> s;
    int pm = (s[0] == '-');
    x = 0;
    for(int i : rep(pm, int(s.size()))) x = x * 10 + (s[i] - '0');
    if(pm) x *= -1;
    return is;
}
ostream& operator<<(ostream& os, const i128& x) {
    if(x == 0) return os << '0';
    i128 y = x;
    if(y < 0) { os << '-'; y *= -1; }
    std::vector<int> ny;
    while(y > 0) { ny.push_back(y % 10); y /= 10; }
    for(int i : revrep(ny.size())) os << ny[i];
    return os;
}

template < class S, class T > istream& operator>>(istream& is,       std::pair< S, T >& x) { is >> x.first        >> x.second; return is; }
template < class S, class T > ostream& operator<<(ostream& os, const std::pair< S, T >& x) { os << x.first << " " << x.second; return os; }

namespace scanner {
    struct sca {
        template < class T > operator T() {
            T s; std::cin >> s; return s;
        }
    };
    struct vec {
        int n;
        vec(int n) : n(n) {}
        template < class T > operator std::vector< T >() {
            std::vector< T > v(n);
            for(T& x : v) std::cin >> x;
            return v;
        }
    };
    struct mat {
        int h, w;
        mat(int h, int w) : h(h), w(w) {}
        template < class T > operator std::vector< std::vector< T > >() {
            std::vector m(h, std::vector< T >(w));
            for(std::vector< T >& v : m) for(T& x : v) std::cin >> x;
            return m;
        }
    };
    struct speedup {
        speedup() {
            std::cin.tie(0);
            std::ios::sync_with_stdio(0);
        }
    } speedup_instance;
}
scanner::sca in() { return scanner::sca(); }
scanner::vec in(int n) { return scanner::vec(n); }
scanner::mat in(int h, int w) { return scanner::mat(h, w); }

namespace printer {
    void precision(int d) { std::cout << std::fixed << std::setprecision(d); }
    void flush() { std::cout.flush(); }
}

template < class T >
ostream& operator<<(ostream& os, const std::vector< T > a) {
    int n = a.size();
    for(int i : rep(n)) { os << a[i]; if(i != n - 1) os << ' '; }
    return os;
}

int print() { std::cout << '\n'; return 0; }
template < class head, class... tail > int print(head&& h, tail&&... t) {
    std::cout << h; if(sizeof...(tail)) std::cout << ' ';
    return print(std::forward<tail>(t)...);
}
template < class T > int print_n(const std::vector< T > a) {
    int n = a.size();
    for(int i : rep(n)) std::cout << a[i] << "\n";
    return 0;
}


#line 2 "cp-library/src/utility/key_val.hpp"

template < class K, class V >
struct key_val {
    K key; V val;
    key_val() {}
    key_val(K key, V val) : key(key), val(val) {}
    template < std::size_t Index >
    std::tuple_element_t< Index, key_val >& get() {
        if constexpr (Index == 0) return key;
        if constexpr (Index == 1) return val;
    }
};

namespace std {

template < class K, class V > struct tuple_size < key_val< K, V > > : integral_constant< size_t, 2 > {};
template < class K, class V > struct tuple_element < 0, key_val< K, V > > { using type = K; };
template < class K, class V > struct tuple_element < 1, key_val< K, V > > { using type = V; };

}
#line 2 "cp-library/src/utility/vec_op.hpp"
template < class T > key_val< int, T > max_of(const vector< T >& a) {
    int i = std::max_element(a.begin(), a.end()) - a.begin();
    return {i, a[i]};
}
template < class T > key_val< int, T > min_of(const vector< T >& a) {
    int i = std::min_element(a.begin(), a.end()) - a.begin();
    return {i, a[i]};
}
template < class S, class T > S sum_of(const vector< T >& a) {
    S sum = 0;
    for(const T x : a) sum += x;
    return sum;
}
template < class S, class T > vector< S > freq_of(const vector< T >& a, T L, T R) {
    vector< S > res(R - L, S(0));
    for(const T x : a) res[x - L] += 1;
    return res;
}
template < class S, class T > struct prefix_sum {
    vector< S > s;
    prefix_sum(const vector< T >& a) : s(a) {
        s.insert(s.begin(), S(0));
        for(int i : rep(a.size())) s[i + 1] += s[i];
    }
    // [L, R)
    S sum(int L, int R) { return s[R] - s[L]; }
};
#line 3 "cp-library/src/utility/heap.hpp"

template < class T > using heap_min = std::priority_queue< T, std::vector< T >, std::greater< T > >;
template < class T > using heap_max = std::priority_queue< T, std::vector< T >, std::less< T > >;

#line 27 "cp-library/src/cp-template.hpp"

#line 1 "cp-library/src/algorithm/bin_search.hpp"
template < class T, class F >
T bin_search(T ok, T ng, F f) {
    while(abs(ng - ok) > 1) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}

template < class T, class F >
T bin_search_real(T ok, T ng, F f, int step = 80) {
    while(step--) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}
#line 2 "cp-library/src/algorithm/argsort.hpp"

template < class T > std::vector< int > argsort(const std::vector< T > &a) {
    std::vector< int > ids((int)a.size());
    std::iota(ids.begin(), ids.end(), 0);
    std::sort(ids.begin(), ids.end(), [&](int i, int j) {
        return a[i] < a[j] || (a[i] == a[j] && i < j);
    });
    return ids;
}
#line 1 "macro.hpp"
namespace macro {

using size_type = int;
template < class container > void  sort(container& a) { std::sort(std:: begin(a), std:: end(a)); }
template < class container > void rsort(container& a) { std::sort(std::rbegin(a), std::rend(a)); }
template < class container > void reverse(container& a) { std::reverse(std::begin(a), std::end(a)); }
template < class container > void unique(container& a) {
    std::sort(std::begin(a), std::end(a));
    a.erase(std::unique(std::begin(a), std::end(a)), std::end(a));
}
template < class container > container  sorted(const container& a) { container b = a;  sort(b); return std::move(b); }
template < class container > container rsorted(const container& a) { container b = a; rsort(b); return std::move(b); }
template < class container, class compare > void sort(container& a, const compare& cmp) { std::sort(std::begin(a), std::end(a), cmp); }
template < class container, class compare > container sorted(const container& a, const compare& cmp) { container b = a; sort(b, cmp); return std::move(b); }
template < class container, class value > size_type lower_bound(const container& a, const value& x) { return std::lower_bound(std::begin(a), std::end(a), x) - std::begin(a); }
template < class container, class value > size_type upper_bound(const container& a, const value& x) { return std::upper_bound(std::begin(a), std::end(a), x) - std::begin(a); }

const std::vector<std::pair<size_type, size_type>> dir4 = { {+1,  0}, {-1,  0}, { 0, +1}, { 0, -1} };
const std::vector<std::pair<size_type, size_type>> dir8 = { {-1, -1}, {-1,  0}, {-1, +1}, { 0, -1}, { 0, +1}, {+1, -1}, {+1,  0}, {+1, +1} };

#ifdef _DEBUG
#define debug(x) std::cout << "[" << __LINE__ << "] " << #x << ": " << x << std::endl
#else
#define debug(x)
#endif

template < class container > void concat(container& a, const container& b) {
    a.insert(std::end(a), std::begin(b), std::end(b));
}
std::vector<size_type> iota(const size_type n) {
    std::vector<size_type> I(n);
    std::iota(std::begin(I), std::end(I), 0);
    return I;
}
template < class container > std::vector<size_type> sort_idx(const container& a) {
    const size_type n = a.size();
    std::vector<size_type> I = iota(n);
    std::sort(std::begin(I), std::end(I), [&](size_type i, size_type j) { return a[i] < a[j] or (a[i] == a[j] and i < j); });
    return I;
}
template < class container, class compare > std::vector<size_type> sort_idx(const container& a, const compare& cmp) {
    const size_type n = a.size();
    std::vector<size_type> I = iota(n);
    std::sort(std::begin(I), std::end(I), [&](size_type i, size_type j) { return cmp(a[i], a[j]) or (a[i] == a[j] and i < j); });
    return std::move(I);
}

struct grid {
    using size_type = int;
    size_type H, W;
    grid(const size_type H, const size_type W) : H(H), W(W) {}
    bool contains(const size_type i, const size_type j) {
        return 0 <= i and i < H and 0 <= j and j < W;
    }
};

using f64 = long double;

template < class T > vector< T >& operator++(vector< T >& a) { for(T& x : a) x++; return a; }
template < class T > vector< T >& operator--(vector< T >& a) { for(T& x : a) x--; return a; }
template < class T > vector< T >  operator++(vector< T >& a, signed) { vector< T > res = a; for(T& x : a) x++; return res; }
template < class T > vector< T >  operator--(vector< T >& a, signed) { vector< T > res = a; for(T& x : a) x--; return res; }

} // namespace macro

using namespace macro;
#line 3 "A.cpp"

string solve(string s) {
    vector<vector<int>> tree;
    auto expr = [&](auto self, int& i, int p) -> void {
        const int v = tree.size();
        tree.push_back({});
        if(p != -1) tree[p].push_back(v);
        if(s[i] == 'x') {
            i++;
        } else {
            assert(s[i] == '(');
            i++;
            self(self, i, v);
            assert(s[i] == ' ');
            i++;
            self(self, i, v);
            assert(s[i] == ')');
            i++;
        }
    }; { int i = 0; expr(expr, i, -1); }
    
    const int n = tree.size();
    vector<set<string>> hash(n);
    auto get_hash = [&](auto self, int v) -> string {
        if(tree[v].size() == 0) {
            hash[v].insert("()");
            return "()";
        } else {
            const int L = tree[v][0];
            const int R = tree[v][1];
            string HL = self(self, L); for(string h : hash[L]) hash[v].insert(h);
            string HR = self(self, R); for(string h : hash[R]) hash[v].insert(h);
            string Hv = "(" + min(HL, HR) + max(HL, HR) + ")";
            hash[v].insert(Hv);
            return Hv;
        }
    }; get_hash(get_hash, 0);

    auto sgn = [&](pair<int,int> a, pair<int,int> b) {
        int L = a.first * b.second;
        int R = b.first * a.second;
        if(L == R) return 0;
        return L < R ? -1 : +1;
    };

    vector<pair<int,int>> sim(n);
    for(int v : rep(n)) {
        if(tree[v].size() == 0) {
            sim[v] = {0, 1};
        } else {
            const int L = tree[v][0];
            const int R = tree[v][1];
            set<string> M;
            for(string h : hash[L]) M.insert(h);
            for(string h : hash[R]) M.insert(h);
            sim[v] = {hash[L].size() + hash[R].size() - M.size(), M.size()};
        }
    }

    vector memo(n, vector(n, -1));
    auto get_strong = [&](auto self, int L, int R) -> int {
        if(memo[L][R] != -1) return memo[L][R];
        if(sgn(sim[L], sim[R]) != 0) {
            return memo[L][R] = sgn(sim[L], sim[R]) == -1 ? L : R;
        } else if(not(tree[L].size() == 2 and tree[R].size() == 2)) {
            return memo[L][R] = L;
        } else {
            const int Ls = self(self, tree[L][0], tree[L][1]);
            const int Rs = self(self, tree[R][0], tree[R][1]);
            if(self(self, Ls, Rs) == self(self, Rs, Ls)) {
                return memo[L][R] = self(self, Ls, Rs) == Ls ? L : R;
            } else {
                const int Lw = (tree[L][0] + tree[L][1]) - Ls;
                const int Rw = (tree[R][0] + tree[R][1]) - Rs;
                if(self(self, Lw, Rw) == self(self, Rw, Lw)) {
                    return memo[L][R] = self(self, Lw, Rw) == Lw ? L : R;
                } else {
                    return memo[L][R] = L;
                }
            }
        }
    };

    auto trans = [&](auto self, int v, int s) -> void {
        if(tree[v].size() == 0) return;
        const int L = tree[v][0];
        const int R = tree[v][1];
        const int res = get_strong(get_strong, L, R);
        if((s == -1 and res == R) or (s == +1 and res == L)) {
            swap(sim[tree[v][0]], sim[tree[v][1]]);
            swap(tree[v][0], tree[v][1]);
        }
        self(self, tree[v][0], -1);
        self(self, tree[v][1], +1);
    }; trans(trans, 0, -1);

    auto ans = [&](auto self, int v) -> string {
        if(tree[v].size() == 0) {
            return "x";
        } else {
            return "(" + self(self, tree[v][0]) + " " + self(self, tree[v][1]) + ")";
        }
    };
    return ans(ans, 0);
}

int main() {
    while(true) {
        string s;
        getline(cin, s);
        if(s[0] == '0') return 0;
        print(solve(s));
    }
}
accuracy: 1
time_ms: 10
memory_kb: 3948
final_rank: 16

code_snippet: #line 2 "cp-library/src/cp-template.hpp"
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using uint = unsigned int;
using ull  = unsigned long long;
using i32 = int;
using u32 = unsigned int;
using i64 = long long;
using u64 = unsigned long long;
using i128 = __int128_t;
template < class T > bool chmin(T& a, T b) { if(a > b) { a = b; return true; } return false; }
template < class T > bool chmax(T& a, T b) { if(a < b) { a = b; return true; } return false; }
template < class T, class U > T ceil (T x, U y) { return (x > 0 ? (x + y - 1) / y :           x / y); }
template < class T, class U > T floor(T x, U y) { return (x > 0 ?           x / y : (x - y + 1) / y); }
int popcnt(i32 x) { return __builtin_popcount(x); }
int popcnt(u32 x) { return __builtin_popcount(x); }
int popcnt(i64 x) { return __builtin_popcountll(x); }
int popcnt(u64 x) { return __builtin_popcountll(x); }

#line 2 "cp-library/src/utility/rep_itr.hpp"
template < class T > struct itr_rep {
    T i, d;
    constexpr itr_rep(const T i) noexcept : i(i), d(1) {}
    constexpr itr_rep(const T i, const T d) noexcept : i(i), d(d) {}
    void operator++() noexcept { i += d; }
    constexpr int operator*() const noexcept { return i; }
    constexpr bool operator!=(const itr_rep x) const noexcept { return d > 0 ? i < x.i : i > x.i; }
};

template < class T > struct rep {
    const itr_rep< T > s, t;
    constexpr rep(const T t) noexcept : s(0), t(t) {}
    constexpr rep(const T s, const T t) noexcept : s(s), t(t) {}
    constexpr rep(const T s, const T t, const T d) noexcept : s(s, d), t(t, d) {}
    constexpr auto begin() const noexcept { return s; }
    constexpr auto end  () const noexcept { return t; }
};

template < class T > struct revrep {
    const itr_rep < T > s, t;
    constexpr revrep(const T t) noexcept : s(t - 1, -1), t(-1, -1) {}
    constexpr revrep(const T s, const T t) noexcept : s(t - 1, -1), t(s - 1, -1) {}
    constexpr revrep(const T s, const T t, const T d) noexcept : s(t - 1, -d), t(s - 1, -d) {}
    constexpr auto begin() const noexcept { return s; }
    constexpr auto end  () const noexcept { return t; }
};
#line 3 "cp-library/src/utility/io.hpp"

/* 128bit integer */
istream& operator>>(istream& is, i128& x) {
    std::string s; is >> s;
    int pm = (s[0] == '-');
    x = 0;
    for(int i : rep(pm, int(s.size()))) x = x * 10 + (s[i] - '0');
    if(pm) x *= -1;
    return is;
}
ostream& operator<<(ostream& os, const i128& x) {
    if(x == 0) return os << '0';
    i128 y = x;
    if(y < 0) { os << '-'; y *= -1; }
    std::vector<int> ny;
    while(y > 0) { ny.push_back(y % 10); y /= 10; }
    for(int i : revrep(ny.size())) os << ny[i];
    return os;
}

template < class S, class T > istream& operator>>(istream& is,       std::pair< S, T >& x) { is >> x.first        >> x.second; return is; }
template < class S, class T > ostream& operator<<(ostream& os, const std::pair< S, T >& x) { os << x.first << " " << x.second; return os; }

namespace scanner {
    struct sca {
        template < class T > operator T() {
            T s; std::cin >> s; return s;
        }
    };
    struct vec {
        int n;
        vec(int n) : n(n) {}
        template < class T > operator std::vector< T >() {
            std::vector< T > v(n);
            for(T& x : v) std::cin >> x;
            return v;
        }
    };
    struct mat {
        int h, w;
        mat(int h, int w) : h(h), w(w) {}
        template < class T > operator std::vector< std::vector< T > >() {
            std::vector m(h, std::vector< T >(w));
            for(std::vector< T >& v : m) for(T& x : v) std::cin >> x;
            return m;
        }
    };
    struct speedup {
        speedup() {
            std::cin.tie(0);
            std::ios::sync_with_stdio(0);
        }
    } speedup_instance;
}
scanner::sca in() { return scanner::sca(); }
scanner::vec in(int n) { return scanner::vec(n); }
scanner::mat in(int h, int w) { return scanner::mat(h, w); }

namespace printer {
    void precision(int d) { std::cout << std::fixed << std::setprecision(d); }
    void flush() { std::cout.flush(); }
}

template < class T >
ostream& operator<<(ostream& os, const std::vector< T > a) {
    int n = a.size();
    for(int i : rep(n)) { os << a[i]; if(i != n - 1) os << ' '; }
    return os;
}

int print() { std::cout << '\n'; return 0; }
template < class head, class... tail > int print(head&& h, tail&&... t) {
    std::cout << h; if(sizeof...(tail)) std::cout << ' ';
    return print(std::forward<tail>(t)...);
}
template < class T > int print_n(const std::vector< T > a) {
    int n = a.size();
    for(int i : rep(n)) std::cout << a[i] << "\n";
    return 0;
}


#line 2 "cp-library/src/utility/key_val.hpp"

template < class K, class V >
struct key_val {
    K key; V val;
    key_val() {}
    key_val(K key, V val) : key(key), val(val) {}
    template < std::size_t Index >
    std::tuple_element_t< Index, key_val >& get() {
        if constexpr (Index == 0) return key;
        if constexpr (Index == 1) return val;
    }
};

namespace std {

template < class K, class V > struct tuple_size < key_val< K, V > > : integral_constant< size_t, 2 > {};
template < class K, class V > struct tuple_element < 0, key_val< K, V > > { using type = K; };
template < class K, class V > struct tuple_element < 1, key_val< K, V > > { using type = V; };

}
#line 2 "cp-library/src/utility/vec_op.hpp"
template < class T > key_val< int, T > max_of(const vector< T >& a) {
    int i = std::max_element(a.begin(), a.end()) - a.begin();
    return {i, a[i]};
}
template < class T > key_val< int, T > min_of(const vector< T >& a) {
    int i = std::min_element(a.begin(), a.end()) - a.begin();
    return {i, a[i]};
}
template < class S, class T > S sum_of(const vector< T >& a) {
    S sum = 0;
    for(const T x : a) sum += x;
    return sum;
}
template < class S, class T > vector< S > freq_of(const vector< T >& a, T L, T R) {
    vector< S > res(R - L, S(0));
    for(const T x : a) res[x - L] += 1;
    return res;
}
template < class S, class T > struct prefix_sum {
    vector< S > s;
    prefix_sum(const vector< T >& a) : s(a) {
        s.insert(s.begin(), S(0));
        for(int i : rep(a.size())) s[i + 1] += s[i];
    }
    // [L, R)
    S sum(int L, int R) { return s[R] - s[L]; }
};
#line 3 "cp-library/src/utility/heap.hpp"

template < class T > using heap_min = std::priority_queue< T, std::vector< T >, std::greater< T > >;
template < class T > using heap_max = std::priority_queue< T, std::vector< T >, std::less< T > >;

#line 27 "cp-library/src/cp-template.hpp"

#line 1 "cp-library/src/algorithm/bin_search.hpp"
template < class T, class F >
T bin_search(T ok, T ng, F f) {
    while(abs(ng - ok) > 1) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}

template < class T, class F >
T bin_search_real(T ok, T ng, F f, int step = 80) {
    while(step--) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}
#line 2 "cp-library/src/algorithm/argsort.hpp"

template < class T > std::vector< int > argsort(const std::vector< T > &a) {
    std::vector< int > ids((int)a.size());
    std::iota(ids.begin(), ids.end(), 0);
    std::sort(ids.begin(), ids.end(), [&](int i, int j) {
        return a[i] < a[j] || (a[i] == a[j] && i < j);
    });
    return ids;
}
#line 1 "macro.hpp"
namespace macro {

using size_type = int;
template < class container > void  sort(container& a) { std::sort(std:: begin(a), std:: end(a)); }
template < class container > void rsort(container& a) { std::sort(std::rbegin(a), std::rend(a)); }
template < class container > void reverse(container& a) { std::reverse(std::begin(a), std::end(a)); }
template < class container > void unique(container& a) {
    std::sort(std::begin(a), std::end(a));
    a.erase(std::unique(std::begin(a), std::end(a)), std::end(a));
}
template < class container > container  sorted(const container& a) { container b = a;  sort(b); return std::move(b); }
template < class container > container rsorted(const container& a) { container b = a; rsort(b); return std::move(b); }
template < class container, class compare > void sort(container& a, const compare& cmp) { std::sort(std::begin(a), std::end(a), cmp); }
template < class container, class compare > container sorted(const container& a, const compare& cmp) { container b = a; sort(b, cmp); return std::move(b); }
template < class container, class value > size_type lower_bound(const container& a, const value& x) { return std::lower_bound(std::begin(a), std::end(a), x) - std::begin(a); }
template < class container, class value > size_type upper_bound(const container& a, const value& x) { return std::upper_bound(std::begin(a), std::end(a), x) - std::begin(a); }

const std::vector<std::pair<size_type, size_type>> dir4 = { {+1,  0}, {-1,  0}, { 0, +1}, { 0, -1} };
const std::vector<std::pair<size_type, size_type>> dir8 = { {-1, -1}, {-1,  0}, {-1, +1}, { 0, -1}, { 0, +1}, {+1, -1}, {+1,  0}, {+1, +1} };

#ifdef _DEBUG
#define debug(x) std::cout << "[" << __LINE__ << "] " << #x << ": " << x << std::endl
#else
#define debug(x)
#endif

template < class container > void concat(container& a, const container& b) {
    a.insert(std::end(a), std::begin(b), std::end(b));
}
std::vector<size_type> iota(const size_type n) {
    std::vector<size_type> I(n);
    std::iota(std::begin(I), std::end(I), 0);
    return I;
}
template < class container > std::vector<size_type> sort_idx(const container& a) {
    const size_type n = a.size();
    std::vector<size_type> I = iota(n);
    std::sort(std::begin(I), std::end(I), [&](size_type i, size_type j) { return a[i] < a[j] or (a[i] == a[j] and i < j); });
    return I;
}
template < class container, class compare > std::vector<size_type> sort_idx(const container& a, const compare& cmp) {
    const size_type n = a.size();
    std::vector<size_type> I = iota(n);
    std::sort(std::begin(I), std::end(I), [&](size_type i, size_type j) { return cmp(a[i], a[j]) or (a[i] == a[j] and i < j); });
    return std::move(I);
}

struct grid {
    using size_type = int;
    size_type H, W;
    grid(const size_type H, const size_type W) : H(H), W(W) {}
    bool contains(const size_type i, const size_type j) {
        return 0 <= i and i < H and 0 <= j and j < W;
    }
};

using f64 = long double;

template < class T > vector< T >& operator++(vector< T >& a) { for(T& x : a) x++; return a; }
template < class T > vector< T >& operator--(vector< T >& a) { for(T& x : a) x--; return a; }
template < class T > vector< T >  operator++(vector< T >& a, signed) { vector< T > res = a; for(T& x : a) x++; return res; }
template < class T > vector< T >  operator--(vector< T >& a, signed) { vector< T > res = a; for(T& x : a) x--; return res; }

} // namespace macro

using namespace macro;
#line 3 "A.cpp"

string solve(string s) {
    vector<vector<int>> tree;
    auto expr = [&](auto self, int& i, int p) -> void {
        const int v = tree.size();
        tree.push_back({});
        if(p != -1) tree[p].push_back(v);
        if(s[i] == 'x') {
            i++;
        } else {
            assert(s[i] == '(');
            i++;
            self(self, i, v);
            assert(s[i] == ' ');
            i++;
            self(self, i, v);
            assert(s[i] == ')');
            i++;
        }
    }; { int i = 0; expr(expr, i, -1); }
    
    const int n = tree.size();
    vector<set<string>> hash(n);
    auto get_hash = [&](auto self, int v) -> string {
        if(tree[v].size() == 0) {
            hash[v].insert("()");
            return "()";
        } else {
            const int L = tree[v][0];
            const int R = tree[v][1];
            string HL = self(self, L); for(string h : hash[L]) hash[v].insert(h);
            string HR = self(self, R); for(string h : hash[R]) hash[v].insert(h);
            string Hv = "(" + min(HL, HR) + max(HL, HR) + ")";
            hash[v].insert(Hv);
            return Hv;
        }
    }; get_hash(get_hash, 0);

    auto sgn = [&](pair<int,int> a, pair<int,int> b) {
        int L = a.first * b.second;
        int R = b.first * a.second;
        if(L == R) return 0;
        return L < R ? -1 : +1;
    };

    vector<pair<int,int>> sim(n);
    for(int v : rep(n)) {
        if(tree[v].size() == 0) {
            sim[v] = {0, 1};
        } else {
            const int L = tree[v][0];
            const int R = tree[v][1];
            set<string> M;
            for(string h : hash[L]) M.insert(h);
            for(string h : hash[R]) M.insert(h);
            sim[v] = {hash[L].size() + hash[R].size() - M.size(), M.size()};
        }
    }

    map<pair<int,int>, int> memo;
    auto get_strong = [&](auto self, int L, int R) -> int {
        if(memo.count({L, R})) return memo[{L, R}];
        if(sgn(sim[L], sim[R]) != 0) {
            return memo[{L, R}] = sgn(sim[L], sim[R]) == -1 ? L : R;
        } else if(not(tree[L].size() == 2 and tree[R].size() == 2)) {
            return memo[{L, R}] = L;
        } else {
            const int Ls = self(self, tree[L][0], tree[L][1]);
            const int Rs = self(self, tree[R][0], tree[R][1]);
            if(self(self, Ls, Rs) == self(self, Rs, Ls)) {
                return memo[{L, R}] = self(self, Ls, Rs) == Ls ? L : R;
            } else {
                const int Lw = (tree[L][0] + tree[L][1]) - Ls;
                const int Rw = (tree[R][0] + tree[R][1]) - Rs;
                if(self(self, Lw, Rw) == self(self, Rw, Lw)) {
                    return memo[{L, R}] = self(self, Lw, Rw) == Lw ? L : R;
                } else {
                    return memo[{L, R}] = L;
                }
            }
        }
    };

    auto trans = [&](auto self, int v, int s) -> void {
        if(tree[v].size() == 0) return;
        const int L = tree[v][0];
        const int R = tree[v][1];
        const int res = get_strong(get_strong, L, R);
        if((s == -1 and res == R) or (s == +1 and res == L)) {
            swap(sim[tree[v][0]], sim[tree[v][1]]);
            swap(tree[v][0], tree[v][1]);
        }
        self(self, tree[v][0], -1);
        self(self, tree[v][1], +1);
    }; trans(trans, 0, -1);

    auto ans = [&](auto self, int v) -> string {
        if(tree[v].size() == 0) {
            return "x";
        } else {
            return "(" + self(self, tree[v][0]) + " " + self(self, tree[v][1]) + ")";
        }
    };
    return ans(ans, 0);
}

int main() {
    while(true) {
        string s;
        getline(cin, s);
        if(s[0] == '0') return 0;
        print(solve(s));
    }
}
accuracy: 1
time_ms: 10
memory_kb: 3856
final_rank: 15

code_snippet: #include <bits/stdc++.h>
using namespace std;

bool is_end = false;

void parse_input(string S, int &v, vector<int> &par, vector<array<int, 2>> &children)
{
  int p = v;
  
  if (S == "x") return;
  
  // cout << S << " " << v << endl;
  assert(S[0] == '(');
  
  int mid = 0, sum = 0;
  for (int i = 1; i < S.length(); ++i)
  {
    if (S[i] == '(') sum++;
    else if (S[i] == ')') sum--;
    
    if (sum == 0) {mid = i + 1; break;}
  }
  
  string left = S.substr(1, mid - 1), right = S.substr(mid + 1);
  assert(right.back() == ')');
  right.pop_back();
  
  {
    v++;
    par[v] = p;
    children[p][0] = v;
    parse_input(left, v, par, children);
    
    v++;
    par[v] = p;
    children[p][1] = v;
    parse_input(right, v, par, children);
  }
  
  return;
}

using ll = long long;
const ll MOD = 1e9 + 7;

mt19937_64 engine(42);

ll calc_hash(int v, vector<int> &par, vector<array<int, 2>> &children, vector<ll> &height, vector<ll> &R, vector<ll> &hash)
{
  ll mult = 1, mx = 0;
  for (auto nv : children[v])
  {
    if (nv == -1) continue;
    mult *= calc_hash(nv, par, children, height, R, hash);
    mult %= MOD;
    mx = max(mx, height[nv] + 1);
  }
  height[v] = mx;
  
  return hash[v] = (R[height[v]] + mult) % MOD;
}

using ld = long double;
const ld EPS = 1e-9;

inline bool eq(ld a, ld b)
{
  return abs(a - b) < EPS;
}

string make_output(int v, vector<array<int, 2>> &children)
{
  if (children[v][0] == -1) return "x";
  
  auto [l, r] = children[v];
  string ret = "";
  ret += '(';
  ret += make_output(l, children);
  ret += ' ';
  ret += make_output(r, children);
  ret += ')';
  
  return ret;
}

void solve()
{
  string S; getline(cin, S);
  if (S == "0")
  {
    is_end = true;
    return;
  }
  
  int N = 0;
  for (auto c : S)
  {
    if (c == 'x') N++;
  }
  
  N = 2 * N - 1;
  vector<int> par(N, -1);
  vector<array<int, 2>> children(N, {-1, -1});
  
  int r = 0;
  parse_input(S, r, par, children);
  
  vector<ll> R(N), hash(N, -1), height(N, -1);
  for (auto &r : R) r = engine() % MOD;
  calc_hash(0, par, children, height, R, hash);
  
  vector< set<ll> > des(N);
  for (int i = N - 1; i >= 0; --i)
  {
    des[i].insert(hash[i]);
    for (auto ni : children[i])
    {
      if (ni == -1) continue;
      des[i].insert(des[ni].begin(), des[ni].end());
    }
  }
  
  vector<ld> LRsame(N, 0.0);
  for (int i = 0; i < N; ++i)
  {
    if (children[i][0] == -1)
    {
      LRsame[i] = 0.0;
      continue;
    }
    
    int left = children[i][0], right = children[i][1];
    set<ll> stand, stor;
    stor = des[left];
    for (auto s : des[right])
    {
      if (stor.find(s) != stor.end()) stand.insert(s);
      stor.insert(s);
    }
    
    LRsame[i] = (ld)stand.size() / stor.size();
  }
  
  vector<vector<int>> lt(N, vector<int>(N, 0));
  for (int i = N - 1; i >= 0; --i)
  {
    for (int j = N - 1; j >= 0; --j)
    {
      if (hash[i] == hash[j])
      {
        lt[i][j] = 0;
        continue;
      }
      
      if (LRsame[i] - LRsame[j] < -EPS)
      {
        lt[i][j] = -1;
      }
      else if (LRsame[j] - LRsame[i] < -EPS)
      {
        lt[i][j] = 1;
      }
      else
      {
        auto [li, ri] = children[i];
        auto [lj, rj] = children[j];
        
        // cout << i << " " << li << " " << ri << endl;
        // cout << j << " " << lj << " " << rj << endl;
        assert(li != -1 && ri != -1 && lj != -1 && rj != -1);
        
        if (lt[li][ri] == -1) swap(li, ri);
        if (lt[lj][rj] == -1) swap(lj, rj);
        
        if (lt[ri][rj] != 0) lt[i][j] = lt[ri][rj];
        else if (lt[li][lj] != 0) lt[i][j] = lt[li][lj];
        else lt[i][j] = 0; 
      }
      
    }
  }
  
  // change children
  vector<bool> isright(N, false);
  for (int i = 0; i < N; ++i)
  {
    if (children[i][0] == -1) continue;
    
    auto &[li, ri] = children[i];
    
    if (lt[li][ri] == -1) swap(li, ri); // here li < ri
    if (!isright[i]) swap(li, ri);
    
    isright[ri] = true;
  }
  
  string res = make_output(0, children);
  cout << res << endl;
  
  return;
}

int main()
{
  while (!is_end)
  {
    solve();
  }
  
  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3608
final_rank: 11

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i, s, t) for (int i = (int)(s); i < (int)(t); ++i)

template <typename T>
ostream& operator<<(ostream& os, const vector<T>& v) {
    for (int i = 0; i < (int) v.size(); ++i) cout << v[i] << " ";
    return os;
}

vector<vector<int>> parse(string& s) {
    // build tree from s
    // returns the tree and the root

    vector<vector<int>> G;
    int k = 0;
    stack<int> st;
    for (char c : s) {
        if (c == ' ') continue;
        if (c == '(' || c == 'x') {
            st.push(k++);
            G.emplace_back();
        } else {
            int r = st.top(); st.pop();
            int l = st.top(); st.pop();
            int v = st.top();
            G[v] = {l, r};
        }
    }
    return G;
}

void output(vector<vector<int>>& G) {
    string s = "";
    auto dfs = [&](auto& dfs, int v) -> void {
        if (G[v].size() == 0) {
            s += 'x';
        } else {
            s += '(';
            dfs(dfs, G[v][0]);
            s += ' ';
            dfs(dfs, G[v][1]);
            s += ')';
        }
    };
    dfs(dfs, 0);
    cout << s << "\n";
}

vector<vector<bool>> calc_isomorphism(vector<vector<int>>& G) {
    // check if subtree i and j are isomorphic

    int n = G.size();
    vector<vector<bool>> isomorphic(n, vector<bool>(n));
    vector<vector<bool>> checked(n, vector<bool>(n));
    auto dfs = [&](auto& dfs, int a, int b) -> void {
        if (checked[a][b]) return;
        checked[a][b] = checked[b][a] = true;
        if (G[a].empty() && G[b].empty()) {
            isomorphic[a][b] = isomorphic[b][a] = true;
        } else if (G[a].empty() || G[b].empty()) {
            isomorphic[a][b] = isomorphic[b][a] = false;
        } else {
            int al = G[a][0], ar = G[a][1];
            int bl = G[b][0], br = G[b][1];
            dfs(dfs, al, bl);
            dfs(dfs, al, br);
            dfs(dfs, ar, bl);
            dfs(dfs, ar, br);
            if ((isomorphic[al][bl] && isomorphic[ar][br]) || (isomorphic[al][br] && isomorphic[ar][bl])) {
                isomorphic[a][b] = isomorphic[b][a] = true;
            } else {
                isomorphic[a][b] = isomorphic[b][a] = false;
            }
        }
    };
    rep(i,0,n-1) rep(j,i+1,n) dfs(dfs, i, j);
    return isomorphic;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout << fixed << setprecision(15);

    while (1) {
        string s;
        getline(cin, s);
        if (s == "0") break;

        auto G = parse(s);
        int n = G.size();

        auto isomorphic = calc_isomorphism(G);

        // get all subtrees for each node
        vector<vector<int>> subtrees(n);
        vector<int> par(n, -1);
        auto dfs = [&](auto& dfs, int v, vector<int> ancestor) -> void {
            for (int a : ancestor) {
                subtrees[a].push_back(v);
            }
            subtrees[v].push_back(v);
            for (int c : G[v]) {
                par[c] = v;
                ancestor.push_back(v);
                dfs(dfs, c, ancestor);
                ancestor.pop_back();
            }
        };
        dfs(dfs, 0, {});

        // calculate ruijido
        vector<double> ruijido(n);
        rep(i,0,n) {
            if (G[i].size() == 0) continue;
            int l = G[i][0], r = G[i][1];
            vector<int> left, right;
            // get all left shapes
            for (int v : subtrees[l]) {
                bool ok = true;
                for (int u : left) {
                    if (isomorphic[v][u]) {
                        ok = false;
                        break;
                    }
                }
                if (ok) left.push_back(v);
            }
            // get all right shapes
            for (int v : subtrees[r]) {
                bool ok = true;
                for (int u : right) {
                    if (isomorphic[u][v]) {
                        ok = false;
                        break;
                    }
                }
                if (ok) right.push_back(v);
            }
            // calc ruijido
            int cnt = left.size(), same = 0;
            for (int v : right) {
                bool ok = false;
                for (int u : left) {
                    if (isomorphic[u][v]) {
                        ok = true;
                        break;
                    }
                }
                if (ok) {
                    ++same;
                } else {
                    ++cnt;
                }
            }
            ruijido[i] = 1.0*same/cnt;
        }

        // calc hitaishosei
        vector<vector<int>> hitaishou(n, vector<int>(n,-1));  // -1: not calculated, 0: same, 1: i>j, 2: i<j
        auto dfs2 = [&](auto& dfs2, int a, int b) -> void {
            if (hitaishou[a][b] != -1) return;
            if (abs(ruijido[a] - ruijido[b]) > 1e-8) {
                // 1
                if (ruijido[a] < ruijido[b]) {
                    hitaishou[a][b] = 1;
                    hitaishou[b][a] = 2;
                } else {
                    hitaishou[a][b] = 2;
                    hitaishou[b][a] = 1;
                }
            } else if (G[a].size() == 0 && G[b].size() == 0) {
                // 2
                hitaishou[a][b] = hitaishou[b][a] = 0;
            } else {
                int as, aw, bs, bw;
                {
                    int l = G[a][0], r = G[a][1];
                    dfs2(dfs2, l, r);
                    if (hitaishou[l][r] == 1) {
                        as = l, aw = r;
                    } else {
                        as = r, aw = l;
                    }
                }
                {
                    int l = G[b][0], r = G[b][1];
                    dfs2(dfs2, l, r);
                    if (hitaishou[l][r] == 1) {
                        bs = l, bw = r;
                    } else {
                        bs = r, bw = l;
                    }
                }
                dfs2(dfs2, as, bs);
                if (hitaishou[as][bs] != 0)  {
                    // 3
                    if (hitaishou[as][bs] == 1) {
                        hitaishou[a][b] = 1;
                        hitaishou[b][a] = 2;
                    } else {
                        hitaishou[a][b] = 2;
                        hitaishou[b][a] = 1;
                    }
                } else {
                    dfs2(dfs2, aw, bw);
                    // 4, 5
                    if (hitaishou[aw][bw] == 1) {
                        hitaishou[a][b] = 1;
                        hitaishou[b][a] = 2;
                    } else if (hitaishou[aw][bw] == 2) {
                        hitaishou[a][b] = 2;
                        hitaishou[b][a] = 1;
                    } else {
                        hitaishou[a][b] = hitaishou[b][a] = 0;
                    }
                }
            }
        };
        rep(i,0,n) {
            if (G[i].size() != 0) {
                dfs2(dfs2, G[i][0], G[i][1]);
            }
        }

        // solve
        auto rec = [&](auto& rec, int v) -> void {
            if (G[v].size() == 0) return;
            int l = G[v][0], r = G[v][1];
            if ((v == 0 || G[par[v]][0] == v) ^ (hitaishou[l][r] == 1)) {
                swap(G[v][0], G[v][1]);
            }
            for (int c : G[v]) rec(rec, c);
        };
        rec(rec, 0);

        output(G);
    }
}
accuracy: 1
time_ms: 10
memory_kb: 3700
final_rank: 14

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
template<class T>bool chmax(T &a, const T &b) { if (a<b) { a=b; return true; } return false; }
template<class T>bool chmin(T &a, const T &b) { if (b<a) { a=b; return true; } return false; }
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define mp make_pair
#define si(x) int(x.size())
const int mod=998244353,MAX=205,INF=1<<30;

#define ld long double

int N;
vector<int> G[MAX];
string T[MAX];
set<string> SE[MAX];
bool leaf[MAX];
ld ruizi[MAX];
int strong[MAX][MAX];

string makeT(int u){
    if(leaf[u]){
        return T[u]="()";
    }else{
        vector<string> U;
        for(int to:G[u]){
            U.push_back(makeT(to));
        }
        sort(all(U));
        string res;
        res+='(';
        res+=U[0];
        res+=U[1];
        res+=')';
        return T[u]=res;
    }
}

void calc(int u){
    SE[u].insert(T[u]);
    if(leaf[u]){
        ruizi[u]=0;
        return;
    }else{
        map<string,int> MA;
        for(int i=1;i<=si(G[u]);i++){
            int to=G[u][i-1];
            calc(to);
            for(auto a:SE[to]){
                MA[a]|=i;
            }
        }
        for(auto a:MA) SE[u].insert(a.fi);
        int ok=0;
        for(auto a:MA) if(a.se==3) ok++;
        ruizi[u]=(ld)ok/(ld)si(MA);
    }
}

void makerank(){
    for(int i=N-1;i>=0;i--){
        for(int j=i+1;j<N;j++){
            if(ruizi[i]!=ruizi[j]){
                if(ruizi[i]<ruizi[j]){
                    strong[i][j]=1;
                    strong[j][i]=-1;
                }else{
                    strong[j][i]=1;
                    strong[i][j]=-1;
                }
            }else{
                if(leaf[i]&&leaf[j]){
                    strong[i][j]=strong[j][i]=0;
                }else{
                    int a,b;
                    if(strong[G[i][0]][G[i][1]]>=0) a=G[i][0];
                    else a=G[i][1];
                    
                    if(strong[G[j][0]][G[j][1]]>=0) b=G[j][0];
                    else b=G[j][1];
                    
                    if(strong[a][b]==1){
                        strong[i][j]=1;
                        strong[j][i]=-1;
                        continue;
                    }
                    if(strong[b][a]==1){
                        strong[j][i]=1;
                        strong[i][j]=-1;
                        continue;
                    }
                    
                    a=G[i][0]+G[i][1]-a;
                    b=G[j][0]+G[j][1]-b;
                    
                    if(strong[a][b]==1){
                        strong[i][j]=1;
                        strong[j][i]=-1;
                        continue;
                    }
                    if(strong[b][a]==1){
                        strong[j][i]=1;
                        strong[i][j]=-1;
                        continue;
                    }
                    
                    strong[i][j]=strong[j][i]=0;
                }
            }
        }
    }
}

void sorting(int u,bool mirror){
    if(leaf[u]) return;
    if(!mirror){
        int a=G[u][0],b=G[u][1];
        if(strong[a][b]>=0){
            sorting(a,0);
            sorting(b,1);
        }else{
            swap(G[u][0],G[u][1]);
            sorting(b,0);
            sorting(a,1);
        }
    }else{
        int a=G[u][0],b=G[u][1];
        if(strong[a][b]>=0){
            swap(G[u][0],G[u][1]);
            sorting(a,1);
            sorting(b,0);
        }else{
            sorting(a,0);
            sorting(b,1);
        }
    }
}

void output(int u){
    if(leaf[u]){
        cout<<'x';
        return;
    }
    cout<<'(';
    output(G[u][0]);
    cout<<' ';
    output(G[u][1]);
    cout<<')';
}

string S;

void expr(int &i){
    if(S[i]=='x'){
        leaf[N]=true;
        N++;
        i++;
    }else{
        assert(S[i]=='(');
        int u=N;
        N++;
        i++;
        G[u].push_back(N);
        //cout<<u<<" "<<N<<endl;
        expr(i);
        assert(S[i]==' ');
        i++;
        G[u].push_back(N);
        //cout<<u<<" "<<N<<endl;
        expr(i);
        assert(S[i]==')');
        i++;
    }
}

void init(){
    N=0;
    for(int i=0;i<MAX;i++){
        G[i].clear();
        T[i]="";
        SE[i].clear();
        leaf[i]=0;
        ruizi[i]=0;
        for(int j=0;j<MAX;j++) strong[i][j]=0;
    }
}

int main() {
    
    std::ifstream in("text.txt");
    std::cin.rdbuf(in.rdbuf());
    cin.tie(0);
    ios::sync_with_stdio(false);
    
    while(1){
        getline(cin,S);
        if(S=="0") return 0;
        init();
        int i=0;
        expr(i);
        makeT(0);
        calc(0);
        makerank();
        sorting(0,0);
        output(0);
        cout<<"\n";
    }
    
}
accuracy: 1
time_ms: 10
memory_kb: 3976
final_rank: 17

code_snippet: #include <bits/stdc++.h>
using namespace std;
 
using ll = long long int;
using ull = unsigned long long int;
using P = pair<int, int>;
 
#define ALL(v) (v).begin(),(v).end()
#define REP(i,n) for(int i=0,i_len=n; i<i_len; ++i)

struct Tree{
    Tree *left = nullptr, *right = nullptr;
    set<string> S;
    P sim;
    Tree(){}
};

bool operator<(const P& lhs, const P& rhs) {return lhs.first*rhs.second > rhs.first*lhs.second;}
bool operator>(const P& lhs, const P& rhs) {return rhs < lhs;}
bool operator==(const P& lhs, const P& rhs) {return lhs.first*rhs.second == rhs.first*lhs.second;}
bool operator!=(const P& lhs, const P& rhs) {return !(lhs==rhs);}

vector<Tree> trees(256);

using State = std::string::const_iterator;

void decode(State &itr, int &idx){
    trees[idx] = Tree();
    int k = idx++;

    if(*itr == '('){
        itr++;
        trees[k].left = &trees[idx];
        decode(itr,idx);
        itr++; // blank
        trees[k].right = &trees[idx];
        decode(itr,idx);
        itr++; // ')'
    }
    else if(*itr == 'x'){
        itr++;
    }
    else{
        cerr << "invalid" << endl;
    }
}

bool is_leaf(Tree &tree){
    return tree.left == nullptr && tree.right == nullptr;
}

void encode(Tree &tree, string &str){
    if(is_leaf(tree)){
        str.push_back('x');
    }else{
        str.push_back('(');
        if(tree.left != nullptr){
            encode(*tree.left, str);
        }
        str.push_back(' ');
        if(tree.right != nullptr){
            encode(*tree.right, str);
        }
        str.push_back(')');
    }
}

P similarity(Tree &tree){
    if(is_leaf(tree)){
        return P(0,1);
    }else{
        set<string> lhs = tree.left->S, rhs = tree.right->S, U;
        U.insert(ALL(lhs));
        U.insert(ALL(rhs));
        return P(lhs.size()+rhs.size()-U.size(), U.size());
    }
}

int compare(Tree &lhs, Tree &rhs){
    if(lhs.sim != rhs.sim){
        return lhs.sim < rhs.sim;
    }else if(is_leaf(lhs) && is_leaf(rhs)){
        return 2;
    }else{
        int res = compare(*lhs.left, *rhs.left);
        if(res != 2) return res;
        else return compare(*lhs.right, *rhs.right);
    }
}


// 全ての頂点で similarity が left < right となるように変換する
void normalize(Tree &tree){
    if(is_leaf(tree)){
        tree.S.insert("x");
        return;
    }else{
        // recursive
        normalize(*tree.left);
        normalize(*tree.right);
        // compare
        tree.left->sim = similarity(*tree.left);
        tree.right->sim = similarity(*tree.right);
        if(compare(*tree.left, *tree.right)%2 == 1){
            swap(tree.left, tree.right);
        }
        // construct tree.S
        tree.S.clear();
        string str = "";
        encode(tree, str);
        tree.S.insert(str);
        tree.S.insert(ALL(tree.left->S));
        tree.S.insert(ALL(tree.right->S));
        return;
    }
}

void transform(Tree &tree, bool rev){
    if(is_leaf(tree)) return;
    
    if(rev) swap(tree.left, tree.right);

    transform(*tree.left, false);
    transform(*tree.right, true);

}

int solve(){
    string s;
    getline(cin, s);
    if(s == "0") return 1;

    State itr = s.begin();
    int idx = 0;
    decode(itr, idx);
    Tree &root = trees[0];

    normalize(root);
    transform(root, false);

    string ans = "";
    encode(root, ans);
    cout << ans << endl;

    return 0;
}

int main(){
    while(!solve());
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3696
final_rank: 13

code_snippet: #include <bits/stdc++.h>
using namespace std;
const long long MOD = 1000000007;
void parse(string &S, int &p, vector<vector<int>> &c, int v){
  if (S[p] == '('){
    p++;
    int sz1 = c.size();
    c[v].push_back(sz1);
    c.push_back(vector<int>());
    parse(S, p, c, sz1);
    p++;
    int sz2 = c.size();
    c[v].push_back(sz2);
    c.push_back(vector<int>());
    parse(S, p, c, sz2);
    p++;
  } else {
    p++;
  }
}
int main(){
  random_device rnd;
  mt19937 mt(rnd());
  while (true){
    string S;
    getline(cin, S);
    if (S == "0"){
      break;
    }
    vector<vector<int>> c;
    c.push_back(vector<int>());
    int pos = 0;
    parse(S, pos, c, 0);
    int N = c.size();
    vector<int> p(N, -1);
    for (int i = 0; i < N; i++){
      for (int j : c[i]){
        p[j] = i;
      }
    }
    vector<long long> base(N);
    for (int i = 0; i < N; i++){
      base[i] = mt() % MOD;
    }
    vector<int> d(N, 0);
    vector<int> bfs;
    queue<int> Q;
    Q.push(0);
    while (!Q.empty()){
      int v = Q.front();
      Q.pop();
      bfs.push_back(v);
      for (int w : c[v]){
        d[w] = d[v] + 1;
        Q.push(w);
      }
    }
    reverse(bfs.begin(), bfs.end());
    vector<long long> hash(N);
    for (int i = 0; i < N; i++){
      vector<long long> dp(N, 1);
      for (int v : bfs){
        for (int w : c[v]){
          dp[v] *= base[d[v] - d[i]] + dp[w];
          dp[v] %= MOD;
        }
        if (v == i){
          break;
        }
      }
      hash[i] = dp[i];
    }
    vector<set<long long>> st(N);
    for (int i = 0; i < N; i++){
      int v = i;
      while (true){
        st[v].insert(hash[i]);
        if (v == 0){
          break;
        }
        v = p[v];
      }
    }
    vector<int> num(N), den(N);
    for (int i = 0; i < N; i++){
      if (c[i].empty()){
        num[i] = 0;
        den[i] = 1;
      } else {
        int l = c[i][0];
        int r = c[i][1];
        set<int> st1, st2;
        for (long long x : st[l]){
          st1.insert(x);
        }
        for (long long x : st[r]){
          st1.insert(x);
          if (st[l].count(x)){
            st2.insert(x);
          }
        }
        num[i] = st2.size();
        den[i] = st1.size();
      }
    }
    vector<vector<int>> comp(N, vector<int>(N));
    for (int v : bfs){
      for (int w : bfs){
        if (d[v] == d[w]){
          if (num[v] * den[w] < num[w] * den[v]){
            comp[v][w] = 1;
          } else if (num[v] * den[w] > num[w] * den[v]){
            comp[v][w] = -1;
          } else if (c[v].empty() && c[w].empty()){
            comp[v][w] = 0;
          } else {
            int l1 = c[v][0];
            int r1 = c[v][1];
            int l2 = c[w][0];
            int r2 = c[w][1];
            if (comp[r1][l1] == 1){
              swap(l1, r1);
            }
            if (comp[r2][l2] == 1){
              swap(l2, r2);
            }
            if (comp[l1][l2] == 1){
              comp[v][w] = 1;
            } else if (comp[l1][l2] == -1){
              comp[v][w] = -1;
            } else if (comp[r1][r2] == 1){
              comp[v][w] = 1;
            } else if (comp[r1][r2] == -1){
              comp[v][w] = -1;
            } else {
              comp[v][w] = 0;
            }
          }
        }
      }
    }
    reverse(bfs.begin(), bfs.end());
    for (int v : bfs){
      if (!c[v].empty()){
        bool R = false;
        if (v != 0){
          if (v == c[p[v]][1]){
            R = true;
          }
        }
        int l = c[v][0];
        int r = c[v][1];
        if (!R){
          if (comp[l][r] == -1){
            swap(c[v][0], c[v][1]);
          }
        } else {
          if (comp[l][r] == 1){
            swap(c[v][0], c[v][1]);
          }
        }
      }
    }
    vector<string> dp(N);
    reverse(bfs.begin(), bfs.end());
    for (int v : bfs){
      if (c[v].empty()){
        dp[v] = "x";
      } else {
        int l = c[v][0];
        int r = c[v][1];
        dp[v] = "(" + dp[l] + " " + dp[r] + ")";
      }
    }
    cout << dp[0] << endl;
  }
}
accuracy: 1
time_ms: 10
memory_kb: 3296
final_rank: 6

code_snippet: #include<iostream>
#include<string>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<queue>
#include<ciso646>
#include<random>
#include<map>
#include<set>
#include<bitset>
#include<stack>
#include<unordered_map>
#include<unordered_set>
#include<utility>
#include<cassert>
#include<complex>
#include<numeric>
#include<array>
using namespace std;

//#define int long long
typedef long long ll;

typedef unsigned long long ul;
typedef unsigned int ui;
constexpr ll mod = 1000000009;
const ll INF = mod * mod;
typedef pair<int, int>P;
#define stop char nyaa;cin>>nyaa;
#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define Rep(i,sta,n) for(int i=sta;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define per1(i,n) for(int i=n;i>=1;i--)
#define Rep1(i,sta,n) for(int i=sta;i<=n;i++)
#define all(v) (v).begin(),(v).end()
typedef pair<ll, ll> LP;
typedef long double ld;
typedef pair<ld, ld> LDP;
const ld eps = 1e-12;
const ld pi = acosl(-1.0);

ll mod_pow(ll x, ll n, ll m = mod) {
	if (n < 0) {
		ll res = mod_pow(x, -n, m);
		return mod_pow(res, m - 2, m);
	}
	if (abs(x) >= m)x %= m;
	if (x < 0)x += m;
	ll res = 1;
	while (n) {
		if (n & 1)res = res * x % m;
		x = x * x % m; n >>= 1;
	}
	return res;
}
struct modint {
	ll n;
	modint() :n(0) { ; }
	modint(ll m) :n(m) {
		if (n >= mod)n %= mod;
		else if (n < 0)n = (n % mod + mod) % mod;
	}
	operator int() { return n; }
};
bool operator==(modint a, modint b) { return a.n == b.n; }
modint operator+=(modint& a, modint b) { a.n += b.n; if (a.n >= mod)a.n -= mod; return a; }
modint operator-=(modint& a, modint b) { a.n -= b.n; if (a.n < 0)a.n += mod; return a; }
modint operator*=(modint& a, modint b) { a.n = ((ll)a.n * b.n) % mod; return a; }
modint operator+(modint a, modint b) { return a += b; }
modint operator-(modint a, modint b) { return a -= b; }
modint operator*(modint a, modint b) { return a *= b; }
modint operator^(modint a, ll n) {
	if (n == 0)return modint(1);
	modint res = (a * a) ^ (n / 2);
	if (n % 2)res = res * a;
	return res;
}

ll inv(ll a, ll p) {
	return (a == 1 ? 1 : (1 - p * inv(p % a, a)) / a + p);
}
modint operator/(modint a, modint b) { return a * modint(inv(b, mod)); }
modint operator/=(modint& a, modint b) { a = a / b; return a; }
const int max_n = 1 << 18;
modint fact[max_n], factinv[max_n];
void init_f() {
	fact[0] = modint(1);
	for (int i = 0; i < max_n - 1; i++) {
		fact[i + 1] = fact[i] * modint(i + 1);
	}
	factinv[max_n - 1] = modint(1) / fact[max_n - 1];
	for (int i = max_n - 2; i >= 0; i--) {
		factinv[i] = factinv[i + 1] * modint(i + 1);
	}
}
modint comb(int a, int b) {
	if (a < 0 || b < 0 || a < b)return 0;
	return fact[a] * factinv[b] * factinv[a - b];
}
modint combP(int a, int b) {
	if (a < 0 || b < 0 || a < b)return 0;
	return fact[a] * factinv[a - b];
}

int dx[4] = { 1,0,-1,0 };
int dy[4] = { 0,1,0,-1 };


string s;
vector<vector<int>> G(128);
int tmp = 0;
int expr(string& s, int& loc) {
	if (s[loc] == '(') {
		int mem = tmp;
		loc++; tmp++;
		int lch = expr(s, loc);
		loc++;
		int rch = expr(s, loc);
		loc++;
		G[mem].push_back(lch);
		G[mem].push_back(rch);
		return mem;
	}
	else {
		int res = tmp;
		tmp++; loc++;
		return res;
	}
}
void solve() {
	G.resize(128);
	rep(i, 128)G[i].clear();
	tmp = 0;
	int loc = 0;
	expr(s, loc);
	//cout << "! " << loc << " " << s.size() << "\n";
	assert(loc == s.size());
	//cout << "! " << tmp << "\n";
	G.resize(tmp);
	int root = 0;
	vector<string> vs(tmp);
	function<void(int)> dfs = [&](int id) {
		vector<string> nexs;
		for (int to : G[id]) {
			dfs(to);
			nexs.push_back(vs[to]);
		}
		sort(all(nexs));
		string res;
		rep(i, nexs.size())res += nexs[i];
		res = "(" + res + ")";
		vs[id] = res;
	};
	dfs(0);
	vector<ld> lr(tmp);
	function<vector<string>(int)> dfs2 = [&](int id)->vector<string> {
		if (G[id].empty()) {
			lr[id] = 0;
			return { vs[id] };
		}
		else {
			vector<string> al;
			vector<string> lch = dfs2(G[id][0]);
			vector<string> rch = dfs2(G[id][1]);
			for (string s : lch)al.push_back(s);
			for (string s : rch)al.push_back(s);
			sort(all(al));
			al.erase(unique(all(al)), al.end());
			int leid = 0, riid = 0;
			int c = 0;
			rep(i, al.size()) {
				bool lexi = false, rexi = false;
				while (leid < lch.size() && lch[leid] < al[i])leid++;
				while (riid < rch.size() && rch[riid] < al[i])riid++;
				if (leid < lch.size() && lch[leid] == al[i])lexi = true;
				if (riid < rch.size() && rch[riid] == al[i])rexi = true;
				if (lexi && rexi) {
					c++;
				}
			}
			lr[id] = c / (ld)(al.size());
			al.push_back(vs[id]);
			sort(all(al));
			return al;
		}
	};
	dfs2(0);
	//rep(i, tmp)cout << lr[i] << "\n";
	vector<vector<int>> isg(tmp, vector<int>(tmp));
	vector<vector<bool>> chked(tmp, vector<bool>(tmp));
	function<int(int, int)> iss=[&](int a, int b)->int {
		if (chked[a][b])return isg[a][b];
		chked[a][b] = true;
		int res;
		if (abs(lr[a] - lr[b]) > (1e-8)) {
			res= (lr[a] > lr[b]);
		}
		else {
			if (G[a].empty()) {
				res = 2;
			}
			else {
				int c = G[a][0];
				if (iss(G[a][0], G[a][1]))c = G[a][1];
				int d = G[b][0];
				if (iss(G[b][0], G[b][1]))d = G[b][1];
				if (iss(c, d) != 2) {
					res = iss(c, d);
				}
				else {
					c = G[a][0] ^ G[a][1] ^ c;
					d = G[b][0] ^ G[b][1] ^ d;
					if (iss(c, d) != 2) {
						res = iss(c, d);
					}
					else {
						res = 2;
					}
				}
			}
		}
		return isg[a][b] = res;
	};
	vector<vector<int>> fG(tmp);
	queue<P> q; q.push({ 0,1 });
	while (!q.empty()) {
		P p = q.front(); q.pop();
		int id = p.first;
		if (G[id].empty())continue;
		int le = G[id][0];
		if (iss(G[id][0], G[id][1]))le = G[id][1];
		int ri = G[id][0] ^ G[id][1] ^ le;
		if (!p.second)swap(le, ri);
		fG[id].push_back(le);
		fG[id].push_back(ri);
		q.push({ le,1 });
		q.push({ ri,0 });
	}
	string ans;
	function<void(int)> ansdfs = [&](int id) {
		if (fG[id].empty()) {
			ans.push_back('x'); 
		}
		else {
			ans.push_back('(');
			ansdfs(fG[id][0]);
			ans.push_back(' ');
			ansdfs(fG[id][1]);
			ans.push_back(')');
		}
	};
	ansdfs(0);
	//cout << "ans is ";
	cout << ans << "\n";
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	//cout << fixed << setprecision(10);
	//init_f();
	//init();
	//expr();
	//int t; cin >> t;rep(i,t)
	while (getline(cin, s)) {
		if (s[0] == '0')break;
		solve();
	}
	//solve();
	return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 7780
final_rank: 18

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll, ll> l_l;
typedef pair<int, int> i_i;

#define EPS (1e-7)
#define INF (1e9)
#define PI (acos(-1))
//const ll mod = 1000000007;
int num = 0;
vector<int> children[200];
int parent[200];
set<string> subtree[200];
string tree[200];
double val[200];
int win(int a, int b);
void dfs(int from) {
    //cerr << "DFS: " << from << endl;
    subtree[from].clear();
    tree[from].clear();
    val[from] = 0;
    if(children[from].empty()) {
        tree[from] = "()";
        subtree[from].insert("()");
        return;
    }
    vector<string> now;
    for(int i = 0; i < children[from].size(); i++) {
        int to = children[from][i];
        dfs(to);
        now.push_back(tree[to]);
        for(auto itr = subtree[to].begin(); itr != subtree[to].end(); itr++) {
            subtree[from].insert(*itr);
        }
    }
    sort(now.begin(), now.end());
    tree[from] = "(" + now[0] + now[1] + ")";
    subtree[from].insert(tree[from]);
    set<string> uni;
    set_intersection(subtree[children[from][0]].begin(), subtree[children[from][0]].end(), subtree[children[from][1]].begin(), subtree[children[from][1]].end(), inserter(uni, uni.end()));
    val[from] = (double)(uni.size()) / (double)(subtree[from].size() - 1);
    if(win(children[from][1], children[from][0]) == 1) swap(children[from][0], children[from][1]);
    //cerr << from << endl << tree[from] << endl << val[from] << endl;
}

void dfs2(int from, bool isleft) {
    if(children[from].empty()) return;
    if(!isleft) swap(children[from][0], children[from][1]);
    dfs2(children[from][0], true);
    dfs2(children[from][1], false);
}

int win(int a, int b) {
    if(val[a] + EPS < val[b]) return 1;
    if(val[a] > val[b] + EPS) return -1;
    if(children[a].empty()) return 0;
    int l = children[a][0];
    int r = children[b][0];
    int tmp = win(l, r);
    if(tmp != 0) return tmp;
    return win(children[a][1], children[b][1]);
}

void f(int from, string::iterator &itr) {
    num++;
    //cerr << num << " " << from << " " << *itr << endl;
    int now = num;
    children[now].clear();
    children[from].push_back(num);
    parent[num] = from;
    if(*itr == 'x') {
        itr++;
        return;
    }
    itr++;
    f(now, itr);
    itr++;
    f(now, itr);
    itr++;
    return;
}

void print(int from) {
    if(children[from].empty()) {
        cout << "x";
        return;
    }
    cout << "(";
    print(children[from][0]);
    cout << " ";
    print(children[from][1]);
    cout << ")";
}

int main() {
    //cout.precision(10);
    while(true) {
        string S;
        getline(cin, S);
        if(S == "0") break;
        num = 0;
        auto itr = S.begin();
        f(0, itr);
        dfs(1);
        dfs2(1, true);
        print(1);
        cout << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3332
final_rank: 8

code_snippet: #include <bits/stdc++.h>
#define MOD 1000000007LL
using namespace std;
typedef long long ll;
typedef pair<int,int> P;

vector<int> ch[301];
map<string,int> mp;
vector<int> G[301];
int siz=0;
int type[301];
int dp[301][301];
set<int> se[301];
int cnt[301],all[301];
bool flag[301][301];


typedef string::const_iterator State;
int expression(State &begin);

string tostring(int v){
	if(v==0)return "0";
	string s;
	while(v>0){
		s+=((v%10)+'0');
		v/=10;
	}
	reverse(s.begin(),s.end());
	return s;
}

int expression(State &begin){
	int cur=siz;
	if(*begin=='('){
		begin++;
		siz++;
		int ret=expression(begin);
		begin++;
		siz++;
		int ret2=expression(begin);
		G[cur].push_back(ret);
		G[cur].push_back(ret2);
		begin++;
		return cur;
	}else if(*begin=='x'){
		begin++;
		return siz;
	}else{
		assert(false);
	}
}

int check(int v1,int v2){
	if(v1==v2)return 0;
	if(v1==0)return -1;
	if(v2==0)return 1;
	if(cnt[v1]*all[v2]!=cnt[v2]*all[v1]){
		if(cnt[v1]*all[v2]<cnt[v2]*all[v1])return -1;
		return 1;
	}
	
	//printf("ch %d %d %d %d\n",v1,v2,ch[v1][0],ch[v2][0]);
	if(flag[v1][v2])return dp[v1][v2];
	flag[v1][v2]=true;
	int res=check(ch[v1][0],ch[v2][0]);
	//printf("ch %d %d %d %d %d\n",v1,v2,ch[v1][0],ch[v2][0],res);
	if(res==-1){
		dp[v1][v2]=-1;
		return res;
	}else if(res==1){
		dp[v1][v2]=1;
		return res;
	}
	res=check(ch[v1][1],ch[v2][1]);
	//printf("ch %d %d %d %d %d\n",v1,v2,ch[v1][1],ch[v2][1],res);
	dp[v1][v2]=res;
	return res;
}

int dfs(int v){
	if(G[v].size()==0){
		type[v]=mp["0"];
	}else{
		int v1=dfs(G[v][0]);
		int v2=dfs(G[v][1]);
		if(v1>v2)swap(v1,v2);
		string vs="("+tostring(v1)+","+tostring(v2)+")";
		if(mp.find(vs)==mp.end()){
			int id=mp.size();
			mp[vs]=id;
			ch[id].push_back(v1);
			ch[id].push_back(v2);
			if(check(ch[id][0],ch[id][1])==1){
				swap(ch[id][0],ch[id][1]);
			}
			se[id].insert(id);
			for(set<int>::iterator it=se[v1].begin();it!=se[v1].end();it++){
				se[id].insert(*it);
			}
			for(set<int>::iterator it=se[v2].begin();it!=se[v2].end();it++){
				se[id].insert(*it);
			}
			all[id]=se[id].size()-1;
			set<int> tmp;
			for(set<int>::iterator it=se[v1].begin();it!=se[v1].end();it++){
				tmp.insert(*it);
			}
			cnt[id]=0;
			for(set<int>::iterator it=se[v2].begin();it!=se[v2].end();it++){
				if(tmp.find(*it)!=tmp.end()){
					cnt[id]++;
				}
			}
		}
		type[v]=mp[vs];
	}
	return type[v];
}

void construct(int v){
	if(G[v].size()==2){
		construct(G[v][0]);
		construct(G[v][1]);
		int rec=check(type[G[v][0]],type[G[v][1]]);
		if(rec==1){
			swap(G[v][0],G[v][1]);
		}
	}
}

string get(int v,int f){
	if(G[v].size()==0){
		return "x";
	}
	if(f==-1){
		return "(" + get(G[v][0],-1) + " " +get(G[v][1],1) +")";
	}else{
		return "(" + get(G[v][1],-1) + " " +get(G[v][0],1) +")";
	}
}


int main(void){
	while(1){
		string str;
		getline(cin,str);
		if(str=="0")break;
		for(int i=0;i<300;i++){
			ch[i].clear();
			G[i].clear();
			se[i].clear();
		}
		memset(dp,0,sizeof(dp));
		memset(flag,false,sizeof(flag));
		siz=0;
		mp.clear();
		mp["0"]=0;
		all[0]=1;
		se[0].insert(0);
		State st=str.begin();
		expression(st);
		dfs(0);
		construct(0);
		cout << get(0,-1) << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3636
final_rank: 12

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i,n) for(int (i)=0;(i)<(int)(n);++(i))
#define all(x) (x).begin(),(x).end()
#define pb push_back
#define fi first
#define se second
#define dbg(x) cout<<#x" = "<<((x))<<endl
template<class T,class U> ostream& operator<<(ostream& o, const pair<T,U> &p){o<<"("<<p.fi<<","<<p.se<<")";return o;}
template<class T> ostream& operator<<(ostream& o, const vector<T> &v){o<<"[";for(T t:v){o<<t<<",";}o<<"]";return o;}

const int N = 200;
vector<int> G[N];

map<vector<int>,int> h2id;

int tree_hash(int v){
    vector<int> hs;
    for(int ch:G[v]){
        hs.pb(tree_hash(ch));
    }
    sort(all(hs));

    if(!h2id.count(hs)) h2id[hs] = h2id.size();
    return h2id[hs];
}

const int MX = 128;

string s;
int n;

int T;
int l[MX],r[MX];
int make_tree(int &idx){
    int ID = T;
    ++T;

    if(s[idx]=='('){
        ++idx;
        l[ID] = make_tree(idx);

        assert(s[idx]==' ');
        ++idx;

        r[ID] = make_tree(idx);
        assert(s[idx]==')');
        ++idx;
    }
    else{
        assert(s[idx]=='x');
        ++idx;
        l[ID] = -1;
        r[ID] = -1;
    }
    return ID;
}

int hs[MX];
int ch_hs[MX][MX];

void mergehs(int v){
    for(int ch:G[v]){
        mergehs(ch);
        rep(i,MX) ch_hs[v][i] += ch_hs[ch][i];
    }
    ++ch_hs[v][hs[v]];
}

using pi = pair<int,int>;
const pi INI(-1,1);
pi sim[MX];

bool small(pi p, pi q){
    return p.fi*q.se < q.fi*p.se;
}

pi calc_sim(int v){
    if(sim[v] != INI) return sim[v];

    pi ret;
    if(l[v] == -1) ret = {0,1};
    else{
        int p = 0, q = 0;
        rep(i,MX){
            int ct = 0;
            if(ch_hs[l[v]][i] > 0) ++ct;
            if(ch_hs[r[v]][i] > 0) ++ct;

            if(ct>0){
                ++q;
                if(ct==2) ++p;
            }
        }

        ret = {p,q};
    }
    return sim[v] = ret;
}

int memo[MX][MX];
int strong(int u, int v){
    if(memo[u][v]!=-1) return memo[u][v];

    // cond.1
    pi sim_u = calc_sim(u), sim_v = calc_sim(v);
    if(small(sim_u,sim_v)) return memo[u][v] = 1;
    if(small(sim_v,sim_u)) return memo[u][v] = 0;

    // cond.2
    if(l[u]==-1 && l[v]==-1) return memo[u][v] = 0;

    // cond.3
    int fu = l[u], su = r[u];
    if(strong(su,fu)) swap(fu,su);

    int fv = l[v], sv = r[v];
    if(strong(sv,fv)) swap(fv,sv);

    if(strong(fu,fv)) return memo[u][v] = 1;
    if(strong(fv,fu)) return memo[u][v] = 0;

    // cond.4
    if(strong(su,sv)) return memo[u][v] = 1;
    if(strong(sv,su)) return memo[u][v] = 0;

    // cond.5
    return memo[u][v] = 0;
}

void SWAP(int v, int flg){
    if(l[v]==-1) return;
    assert(r[v]!=-1);

    int L = l[v], R = r[v];

    int ct[MX]={};
    rep(i,MX){
        if(ch_hs[l[v]][i] > 0) ++ct[i];
        if(ch_hs[r[v]][i] > 0) ++ct[i];
    }

    if(flg == 0){
        if(strong(R,L)) swap(l[v],r[v]);
    }
    else{
        if(strong(L,R)) swap(l[v],r[v]);
    }

    SWAP(l[v],0);
    SWAP(r[v],1);
}

string tree2str(int v){
    if(l[v]==-1) return "x";

    string res = "";
    res += "(";
    res += tree2str(l[v]);
    res += " ";
    res += tree2str(r[v]);
    res += ")";

    return res;
}

int main(){
    while( getline(cin,s), (s!="0") ){
        rep(i,N) G[i].clear();
        h2id.clear();
        rep(i,MX)rep(j,MX) ch_hs[i][j] = 0;
        rep(i,MX) sim[i] = INI;
        memset(memo,-1,sizeof(memo));

        n = s.size();

        T = 0;
        int ttt = 0;
        make_tree(ttt);

        rep(i,T){
            if(l[i]!=-1) G[i].pb(l[i]);
            if(r[i]!=-1) G[i].pb(r[i]);
        }

        rep(i,T) hs[i] = tree_hash(i);

        mergehs(0);

        SWAP(0,0);

        cout << tree2str(0) << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3288
final_rank: 5

code_snippet: #include <bits/stdc++.h>
using namespace std;

constexpr double eps = 1e-8;

struct exp_tree;
using tree_ptr = shared_ptr<exp_tree>;

struct exp_tree {
    tree_ptr lch, rch;
    double asym;
    bool leaf;
    exp_tree() : lch(nullptr), rch(nullptr), asym(0), leaf(true) {}
    string to_string(bool is_sort) const {
        assert(leaf || (lch && rch));
        if(leaf) return "x";
        auto s1 = lch->to_string(is_sort), s2 = rch->to_string(is_sort);
        if(is_sort && s1 > s2) swap(s1, s2);
        return "(" + s1 + " " + s2 + ")";
    }
    double value() const {
        return asym;
    }
    bool operator<(exp_tree const& other) const { // lch.asym < rch.asym ?
        if(other.leaf) return false;
        if(leaf) return true;
        if(abs(value() - other.value()) < eps) {
            auto lmin = min(*lch, *rch);
            auto rmin = min(*other.lch, *other.rch);
            if(!(lmin < rmin) && !(rmin < lmin)) {
                auto lmax = max(*lch, *rch);
                auto rmax = max(*other.lch, *other.rch);
                return lmax < rmax;
            }
            return lmin < rmin;
        }
        return value() < other.value();
    }
    set<string> eval() {
        set<string> ss;
        if(leaf) {
            ss.insert(this->to_string(true));
            return ss;
        }
        auto ls = lch->eval(), rs = rch->eval();
        double same = 0;
        ss = move(rs);
        for(auto&& s : ls) {
            same += ss.count(s);
            ss.insert(s);
        }
        ss.insert(this->to_string(true));
        asym = same / (ss.size() - 1);
        return ss;
    }

    void swap_dfs(bool is_left) {
        if(leaf) return;
        if((*lch < *rch && !is_left) || (!(*lch < *rch) && is_left)) {
            swap(lch, rch);
        }
        lch->swap_dfs(true);
        rch->swap_dfs(false);
    }
};

tree_ptr expr(string const& s, int& p) {
    tree_ptr res = make_shared<exp_tree>();
    assert(p < (int)s.size());
    if(s[p] == 'x') {
        p += 1;
        return res;
    }
    res->leaf = false;
    res->lch = expr(s, ++p);
    res->rch = expr(s, ++p);
    p += 1;
    return res;
}

tree_ptr parse(string const& s) {
    int p = 0;
    return expr(s, p);
}

int main() {
    string s;
    while(getline(cin, s), s[0] != '0') {
        auto t = parse(s);
        t->eval();
        t->swap_dfs(true);
        cout << t->to_string(false) << endl;
    }
}
accuracy: 1
time_ms: 10
memory_kb: 3088
final_rank: 1

code_snippet: #include <bits/stdc++.h>
using namespace std;

constexpr double eps = 1e-8;

struct exp_tree;
using tree_ptr = shared_ptr<exp_tree>;

struct exp_tree {
    tree_ptr lch, rch;
    double asym;
    bool leaf;
    exp_tree() : lch(nullptr), rch(nullptr), asym(0), leaf(true) {}
    string to_string(bool is_sort) const {
        assert(leaf || (lch && rch));
        if(leaf) return "x";
        auto s1 = lch->to_string(is_sort), s2 = rch->to_string(is_sort);
        if(is_sort && s1 > s2) swap(s1, s2);
        return "(" + s1 + " " + s2 + ")";
    }
    double value() const {
        return asym;
    }
    bool operator<(exp_tree const& other) const { // lch.asym < rch.asym ?
        if(other.leaf) return false;
        if(leaf) return true;
        if(abs(value() - other.value()) < eps) {
            auto lmin = min(*lch, *rch);
            auto rmin = min(*other.lch, *other.rch);
            if(!(lmin < rmin) && !(rmin < lmin)) {
                auto lmax = max(*lch, *rch);
                auto rmax = max(*other.lch, *other.rch);
                return lmax < rmax;
            }
            return lmin < rmin;
        }
        return value() < other.value();
    }
    set<string> eval() {
        set<string> ss;
        if(leaf) {
            ss.insert(this->to_string(true));
            return ss;
        }
        auto ls = lch->eval(), rs = rch->eval();
        double same = 0;
        ss = move(rs);
        for(auto&& s : ls) {
            same += ss.count(s);
            ss.insert(s);
        }
        ss.insert(this->to_string(true));
        asym = same / (ss.size() - 1);
        //cout << "asym: " << asym << ' ' << " expr: " << to_string(true) << endl;
        return ss;
    }

    void swap_dfs(bool is_left) {
        if(leaf) return;
        if((*lch < *rch && !is_left) || (!(*lch < *rch) && is_left)) {
            swap(lch, rch);
        }
        lch->swap_dfs(true);
        rch->swap_dfs(false);
    }
};

using tree_ptr = shared_ptr<exp_tree>;

tree_ptr expr(string const& s, int& p) {
    tree_ptr res = make_shared<exp_tree>();
    assert(p < (int)s.size());
    if(s[p] == 'x') {
        p += 1;
        return res;
    }
    p += 1;
    res->leaf = false;
    res->lch = expr(s, p);
    res->rch = expr(s, ++p);
    p += 1;
    return res;
}

tree_ptr parse(string const& s) {
    int p = 0;
    return expr(s, p);
}

int main() {
    string s;
    while(getline(cin, s), s[0] != '0') {
        auto t = parse(s);
        t->eval();
        t->swap_dfs(true);
        cout << t->to_string(false) << endl;
    }
}
accuracy: 1
time_ms: 10
memory_kb: 3148
final_rank: 2

code_snippet: #include <bits/stdc++.h>

using namespace std;

const double eps = 1e-8;
#define eq(a, b) (fabs((a)-(b)) < eps)
#define lt(a, b) (((a)-(b)) < -eps)

struct node {
  string self;
  double sim;
  set<int> sub;
  int li, ri;
  node(){}
  node(string self, double sim, int li, int ri):self(self), sim(sim), li(li), ri(ri){}
};

string s;
int idx;
map<string, int> mp;
vector<node> vec;
int sz;

int insert(string tree, int li, int ri) {
  if(!mp.count(tree)) {
    node new_node(tree, 0.0, li, ri);
    if(li != -1) {
      set<int> A = vec[li].sub;
      set<int> B = vec[ri].sub;
      if(A.size() < B.size()) swap(A, B);
      int cnt = 0;
      for(int b : B) {
	cnt += A.count(b);
	A.insert(b);
      }
      new_node.sub = A;
      new_node.sim = (double)cnt/A.size();
    }
    mp[tree] = sz++;
    new_node.sub.insert(mp[tree]);
    vec.push_back(new_node);
  }
  return mp[tree];
}

int cmp(int i, int j) {
  node x = vec[i];
  node y = vec[j];
  if(!eq(x.sim, y.sim)) {
    if(lt(x.sim, y.sim)) return 1;
    else return -1;
  }
  if(x.li == -1) return 0;
  int res = cmp(x.li, y.li);
  if(res == 0) res = cmp(x.ri, y.ri);
  return res;
}

int solve() {
  int ch = s[idx++];
  if(ch == 'x') return insert("x", -1, -1);
  int li = solve(); idx++;
  int ri = solve(); idx++;
  //if(vec[li].sim > vec[ri].sim) swap(li, ri);
  if(cmp(li, ri) == -1) swap(li, ri);
  node lch = vec[li];
  node rch = vec[ri];
  string self = "(" + lch.self + " " + rch.self + ")";
  return insert(self, li, ri);
}


string output(int i, bool izryt) {
  //cout << i << endl;
  if(vec[i].self == "x") return "x";
  node v = vec[i];
  //if((cmp(v.li, v.ri)==-1)^izryt) swap(v.li, v.ri);
  if(izryt) swap(v.li, v.ri);
  return "(" + output(v.li, false) + " " + output(v.ri, true) + ")";
}

int main() {
  cout<<fixed<<setprecision(12);
  while(getline(cin, s), s != "0") {
    mp.clear();
    vec.clear();
    sz = 0;
    idx = 0;
    int ans = solve();
    cout << output(ans, false) << endl;
  }
  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3320
final_rank: 7

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef pair<set<string>,string>P;
set<string>::iterator it1,it2;
struct no{
  int id;
  int syurui;
  double p;
  int same;
  string s;
  set<string>st;
  no *left,*right;
  no(int ID){left=right=NULL;s="";st.clear();id=ID;p=0.0;}
};
int C=0;
typedef no* node;
node make_tree(int l,int r,const string &str){
  int cnt=0;
  node x=new no(C++);
  if(l==r)return x;
  for(int i=l+1;i<r;i++){
    if(str[i]=='(')cnt++;
    if(str[i]==')')cnt--;
    if(cnt==0&&str[i]==' '){
      if(l+1<=i-1)x->left=make_tree(l+1,i-1,str);
      if(i+1<=r-1)x->right=make_tree(i+1,r-1,str);
      break;
    }
  }
  return x;
}
void print_tree(node x){
  if(x->left==NULL && x->right==NULL){
    cout<<'x';
    return;
  }
  cout<<'(';
  if(x->left!=NULL)print_tree(x->left);
  cout<<' ';
  if(x->right!=NULL)print_tree(x->right);
  cout<<')';
}
void delete_tree(node x){
  if(x->left!=NULL)delete_tree(x->left);
  if(x->right!=NULL)delete_tree(x->right);
  delete(x);
}
P calc_tree(node x){
  int cnt=0;
  vector<string>v;
  set<string>sl,sr,st;
  string s1,s2,new_s;
  if(x->left==NULL && x->right==NULL){
    sl.insert("()");
    return P(sl,"()");
  }
  if(x->left!=NULL){
    P p=calc_tree(x->left);
    sl=p.first;
    s1=p.second;
    v.push_back(s1);
  }
  if(x->right!=NULL){
    P p=calc_tree(x->right);
    sr=p.first;
    s2=p.second;
    v.push_back(s2);
  }
  sort(v.begin(),v.end());
  for(it1=sl.begin();it1!=sl.end();it1++){
    st.insert((*it1));
    for(it2=sr.begin();it2!=sr.end();it2++){
      if((*it1)==(*it2))cnt++;
    }
  }
  for(it2=sr.begin();it2!=sr.end();it2++){
    st.insert((*it2));
  }
  for(int i=0;i<v.size();i++){
    new_s+=v[i];
  }
  x->syurui=st.size();
  x->same=cnt;
  x->p=(double)cnt/st.size();
  x->s="("+new_s+")";
  st.insert(x->s);
  x->st=st;
  return P(st,x->s);
}
//(((x ((x ((x x) x)) x)) (x x)) ((x x) x))
//(((x ((x ((x x) x)) x)) (x x)) ((x x) x))

int comp(node l,node r){
  double s1=l->p;
  double s2=r->p;
  if(abs(s1-s2)>1e-9) return s1<s2?1:-1;
  if(!l->left&&!r->left) return 0;
  node ll=l->left;
  node lr=l->right;
  node rl=r->left;
  node rr=r->right;
  if(comp(ll,lr)<0)swap(ll,lr);
  if(comp(rl,rr)<0)swap(rl,rr);
  int c=comp(ll,rl);
  if(!c)return comp(lr,rr);
  return c;
}

void swap_tree(int pre,node x){
  if(x->left==NULL)return;
  if((comp(x->left,x->right)<0)==!pre)swap(x->left,x->right);
  if(x->left!=NULL)swap_tree(0,x->left);
  if(x->right!=NULL)swap_tree(1,x->right);
}

string s;
signed main(){
  while(getline(cin,s),s!="0"){
    C=0;
    node root=make_tree(0,s.size()-1,s);
    calc_tree(root);
    swap_tree(0,root);
    print_tree(root);
    cout<<endl;
    delete_tree(root);
    s="";
  }
}
accuracy: 1
time_ms: 10
memory_kb: 3256
final_rank: 4

code_snippet: #include<bits/stdc++.h>
using namespace std;
using Int = long long;
signed main(){  
  cin.tie(0);
  ios::sync_with_stdio(0);
  string s;
  while(getline(cin,s),s!="0"){
    Int m=count(s.begin(),s.end(),'x')*2-1;
    if(m==1){
      cout<<s<<endl;
      continue;
    }
    
    Int cur=0;
    vector<Int> L(m,-1),R(m,-1);
    
    function<Int(string)> dfs=[&](string s){
      //cout<<s<<endl;
      Int v=cur++;
      if(s=="x"){
	return v;
      }
      Int op=0;
      for(Int i=0;i<(Int)s.size();i++){
	if(s[i]=='(') op++;
	if(s[i]==')') op--;
	if(op==1&&s[i]==' '){
	  string ls=s.substr(1,i-1);
	  string rs=s.substr(i+1,s.size()-(i+2));
	  L[v]=dfs(ls);
	  R[v]=dfs(rs);
	  return v;
	}
      }
    };
    dfs(s);

    vector<string> sh(m);
    vector<set<string> > dp(m);
    vector<Int> p(m),q(m);
    vector<Int> p1(m),q1(m);
    vector<Int> p2(m),q2(m);

    auto check=[&](Int a,Int b,Int c,Int d){
      return a*d>c*b;
    };
    
    function<void(Int)> dfs2=[&](Int v){
      if(L[v]<0){
	p[v]=0;q[v]=1;
	sh[v]="()";
	dp[v].emplace(sh[v]);
	return;
      }
      dfs2(L[v]);
      dfs2(R[v]);
      
      set<string> uni;
      dp[v]=dp[R[v]];
      for(auto ss:dp[L[v]]){
	dp[v].emplace(ss);
	if(dp[R[v]].count(ss))
	  uni.emplace(ss);
      }
      p[v]=uni.size();
      q[v]=dp[v].size();
      
      sh[v]="("+(sh[L[v]]<sh[R[v]]?sh[L[v]]+sh[R[v]]:sh[R[v]]+sh[L[v]])+")";      
      dp[v].emplace(sh[v]);

      p1[v]=L[v];p2[v]=R[v];
    };
    dfs2(0);

    function<void(Int, Int)> dfs4=[&](Int v,Int k){
      if(L[v]<0) return;
      function<Int(Int,Int)> ccc=[&](Int a,Int b)->Int{
	if(check(p[a],q[a],p[b],q[b])){
	  return 1;
	}
	
	if(check(p[b],q[b],p[a],q[a])){
	  return 0;
	}
	
	if(!p[a]&&!p[b]){
	  return 0;
	}

	if(ccc(p1[a],p2[a])){
	  swap(p1[a],p2[a]);
	}

	if(ccc(p1[b],p2[b])){
	  swap(p1[b],p2[b]);
	}
	
	if(ccc(p1[a],p1[b])){
	  return 1;
	}
	
	if(ccc(p1[b],p1[a])){
	  return 0;
	}
	
	if(ccc(p2[a],p2[b])){
	  return 1;
	}
	
	return 0;
      };
      if(k^ccc(L[v],R[v])) swap(L[v],R[v]);
      dfs4(L[v],0);
      dfs4(R[v],1);
    };
    dfs4(0,0);

    stringstream ss;
    function<void(Int)> dfs3=[&](Int v){
      if(L[v]<0){
	ss<<"x";
	return;
      }
      ss<<"(";
      dfs3(L[v]);
      ss<<" ";
      dfs3(R[v]);
      ss<<")";
    };
    dfs3(0);
    cout<<ss.str()<<endl;
  }
  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3340
final_rank: 9

code_snippet: #include<bits/stdc++.h>
using namespace std;
using Int = long long;
signed main(){  
  cin.tie(0);
  ios::sync_with_stdio(0);
  string s;
  while(getline(cin,s),s!="0"){
    Int m=count(s.begin(),s.end(),'x')*2-1;
    if(m==1){
      cout<<s<<endl;
      continue;
    }
    
    Int cur=0;
    vector<Int> L(m,-1),R(m,-1);
    
    function<Int(string)> dfs=[&](string s){
      //cout<<s<<endl;
      Int v=cur++;
      if(s=="x"){
	return v;
      }
      Int op=0;
      for(Int i=0;i<(Int)s.size();i++){
	if(s[i]=='(') op++;
	if(s[i]==')') op--;
	if(op==1&&s[i]==' '){
	  string ls=s.substr(1,i-1);
	  string rs=s.substr(i+1,s.size()-(i+2));
	  L[v]=dfs(ls);
	  R[v]=dfs(rs);
	  return v;
	}
      }
    };
    dfs(s);
    //for(Int i=0;i<m;i++) cout<<i<<":"<<L[i]<<" "<<R[i]<<endl; 

    vector<string> sh(m);
    vector<set<string> > dp(m);
    vector<Int> p(m),q(m);
    vector<Int> p1(m),q1(m);
    vector<Int> p2(m),q2(m);

    auto check=[&](Int a,Int b,Int c,Int d){
      return a*d>c*b;
    };
    
    function<void(Int)> dfs2=[&](Int v){
      if(L[v]<0){
	p[v]=0;q[v]=1;
	sh[v]="()";
	dp[v].emplace(sh[v]);
	return;
      }
      dfs2(L[v]);
      dfs2(R[v]);
      
      set<string> uni;
      dp[v]=dp[R[v]];
      for(auto ss:dp[L[v]]){
	dp[v].emplace(ss);
	if(dp[R[v]].count(ss))
	  uni.emplace(ss);
      }
      p[v]=uni.size();
      q[v]=dp[v].size();
      //cout<<v<<":"<<p[v]<<":"<<q[v]<<endl;
      //for(auto ss:dp[v]) cout<<v<<":"<<ss<<endl;
      
      sh[v]="("+(sh[L[v]]<sh[R[v]]?sh[L[v]]+sh[R[v]]:sh[R[v]]+sh[L[v]])+")";      
      dp[v].emplace(sh[v]);

      p1[v]=L[v];p2[v]=R[v];
    };
    dfs2(0);

    function<void(Int, Int)> dfs4=[&](Int v,Int k){
      if(L[v]<0) return;
      function<Int(int,Int)> ccc=[&](Int a,Int b)->Int{
	if(check(p[a],q[a],p[b],q[b])){
	  return 1;
	}
	
	if(check(p[b],q[b],p[a],q[a])){
	  return 0;
	}
	
	if(!p[a]&&!p[b]){
	  return 0;
	}

	if(ccc(p1[a],p2[a])){
	  swap(p1[a],p2[a]);
	}

	if(ccc(p1[b],p2[b])){
	  swap(p1[b],p2[b]);
	}
	
	if(ccc(p1[a],p1[b])){
	  return 1;
	}
	
	if(ccc(p1[b],p1[a])){
	  return 0;
	}
	
	if(ccc(p2[a],p2[b])){
	  return 1;
	}
	
	return 0;
      };
      //cout<<v<<" "<<k<<":"<<ccc(L[v],R[v])<<endl;
      if(k^ccc(L[v],R[v])) swap(L[v],R[v]);
      dfs4(L[v],0);
      dfs4(R[v],1);
    };
    dfs4(0,0);

    stringstream ss;
    function<void(Int)> dfs3=[&](Int v){
      if(L[v]<0){
	ss<<"x";
	return;
      }
      ss<<"(";
      dfs3(L[v]);
      ss<<" ";
      dfs3(R[v]);
      ss<<")";
    };
    dfs3(0);
    string ans=ss.str();
    if(0){
      reverse(ans.begin(),ans.end());
      for(auto &c:ans){
	if(c=='(') c=')';
	else if(c==')') c='(';
      }
    }
    cout<<ans<<endl;
  }
  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3168
final_rank: 3

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;

struct Node{
	Node* l;
	Node* r;
	double R;
	string s;
	set<string> se;
	Node() : l(nullptr), r(nullptr){}
};

int c;
int N;
string s;

map<pair<Node*, Node*>, int> compm;
// X????????????????§°??§????????? -1
// ?????? 0
// Y????????????????§°??§?????????  1
int comp(Node* X, Node* Y){
	if(compm.count({ X, Y })) return compm[{X, Y}];
	if(X->R != Y->R){
		if(X->R < Y->R) return compm[{X, Y}] = -1;
		return compm[{X, Y}] = 1;
	}
	if(X->s == "()" && Y->s == "()"){
		return compm[{X, Y}] = 0;
	}

	Node *xmin, *xmax;
	Node *ymin, *ymax;
	if(comp(X->l, X->r) < 0){
		xmax = X->l, xmin = X->r;
	}
	else{
		xmin = X->l, xmax = X->r;
	}
	if(comp(Y->l, Y->r) < 0){
		ymax = Y->l, ymin = Y->r;
	}
	else{
		ymin = Y->l, ymax = Y->r;
	}
	int res = comp(xmax, ymax);
	if(res != 0){
		if(res < 0) return compm[{X, Y}] = -1;
		return compm[{X, Y}] = 1;
	}
	return compm[{X, Y}] = comp(xmin, ymin);
}

Node* f(){
	Node* n = new Node();
	if(s[c] == 'x'){
		c++;
		n->s = "()";
		n->se.insert("()");
		n->R = 0;
		return n;
	}
	assert(s[c] == '(');
	c++;
	n->l = f();
	assert(s[c] == ' ');
	c++;
	n->r = f();
	int cnt = 0;
	for(auto v : n->l->se){
		n->se.insert(v);
		if(n->r->se.count(v)) cnt++;
	}
	for(auto v : n->r->se){
		n->se.insert(v);
	}
	n->R = double(cnt) / n->se.size();

	string ls = n->l->s, rs = n->r->s;
	if(ls > rs) swap(ls, rs);
	n->s = "(" + ls + rs + ")";
	n->se.insert(n->s);

	assert(s[c] == ')');
	c++;
	return n;
}

void g(Node* n, bool left){
	if(n->s == "()"){
		cout << "x";
		return;
	}
	if(left && comp(n->l, n->r) > 0){
		swap(n->l, n->r);
	}
	if(!left && comp(n->l, n->r) < 0){
		swap(n->l, n->r);
	}

	cout << "(";
	g(n->l, true);
	cout << " ";
	g(n->r, false);
	cout << ")";
}

int main(){
	cin.tie(0);
	ios::sync_with_stdio(false);
#ifdef LOCAL
	std::ifstream in("in");
	std::cin.rdbuf(in.rdbuf());
#endif

	while(getline(cin, s), s != "0"){
		compm.clear();
		N = s.size();
		c = 0;
		Node* r = f();
		//cout << s << endl;
		g(r, 1);
		cout << endl;
	}
}
accuracy: 1
time_ms: 10
memory_kb: 8988
final_rank: 19

code_snippet: #include <cassert>
#include <functional>
#include <iostream>
#include <memory>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
using ll = long long;
using namespace std;

struct tree_t {
    shared_ptr<tree_t> l, r;
};

shared_ptr<tree_t> parse_tree(string::const_iterator & first, string::const_iterator last) {
    assert (first != last);
    if (*first == 'x') {
        ++ first;
        return shared_ptr<tree_t>();
    } else {
        assert (*first == '(');
        ++ first;
        auto l = parse_tree(first, last);
        assert (*first == ' ');
        ++ first;
        auto r = parse_tree(first, last);
        assert (*first == ')');
        ++ first;
        return make_shared<tree_t>((tree_t) { l, r });
    }
}
shared_ptr<tree_t> parse_tree(string const & s) {
    auto it = s.begin();
    auto tree = parse_tree(it, s.end());
    assert (it == s.end());
    return tree;
}

struct rational {
    int num, den;
};
bool operator < (rational a, rational b) {
    return a.num *(ll) b.den < b.num *(ll) a.den;
}
bool operator > (rational a, rational b) {
    return a.num *(ll) b.den > b.num *(ll) a.den;
}

string signature(shared_ptr<tree_t> const & tree) {
    if (not tree) {
        return "x";
    } else {
        string l = signature(tree->l);
        string r = signature(tree->r);
        if (l > r) swap(l, r);
        return "(" + l + " " + r + ")";
    }
}

void normalize(shared_ptr<tree_t> root) {
    unordered_map<string, unordered_set<string> > subtrees; {
        function<void (shared_ptr<tree_t> const &)> go = [&](shared_ptr<tree_t> const & tree) {
            subtrees[signature(tree)].insert(signature(tree));
            if (tree) {
                go(tree->l);
                go(tree->r);
                for (auto it : subtrees[signature(tree->l)]) {
                    subtrees[signature(tree)].insert(it);
                }
                for (auto it : subtrees[signature(tree->r)]) {
                    subtrees[signature(tree)].insert(it);
                }
            }
        };
        go(root);
    }
    unordered_map<string, rational> sim; {
        function<void (shared_ptr<tree_t> const &)> go = [&](shared_ptr<tree_t> const & tree) {
            if (not tree) {
                sim[signature(tree)] = (rational) { 0, 1 };
            } else {
                auto l = subtrees[signature(tree->l)];
                auto r = subtrees[signature(tree->r)];
                int num = 0;
                for (auto it : l) {
                    num += r.count(it);
                }
                int den = l.size() + r.size() - num;
                sim[signature(tree)] = (rational) { num, den };
                go(tree->l);
                go(tree->r);
            }
        };
        go(root);
    }
    const int LT = -1;
    const int EQ =  0;
    const int GT = +1;
    function<int (shared_ptr<tree_t> const &, shared_ptr<tree_t> const &)> cmp = [&](shared_ptr<tree_t> const & a, shared_ptr<tree_t> const & b) {
            rational sim_a = sim[signature(a)];
            rational sim_b = sim[signature(b)];
            // 1.
            if (sim_a < sim_b) return GT;
            if (sim_a > sim_b) return LT;
            // 2.
            if (not a and not b) return EQ;
            // 3.
            auto al = a->l, ar = a->r;
            auto bl = b->l, br = b->r;
            if (cmp(al, ar) == GT) swap(al, ar);
            if (cmp(bl, br) == GT) swap(bl, br);
            int cmp_ar_br = cmp(ar, br);
            if (cmp_ar_br != EQ) return cmp_ar_br;
            // 4.
            int cmp_al_bl = cmp(al, bl);
            if (cmp_al_bl != EQ) return cmp_al_bl;
            // 5.
            return EQ;
    };
    function<void (shared_ptr<tree_t>, bool)> go = [&](shared_ptr<tree_t> tree, bool is_right) {
        if (not tree) {
            // nop
        } else {
            if (cmp(tree->l, tree->r) == (is_right ? GT : LT)) {
                swap(tree->l, tree->r);
            }
            go(tree->l, false);
            go(tree->r, true);
        }
    };
    go(root, false);
}

string format_tree(shared_ptr<tree_t> const & tree) {
    if (not tree) {
        return "x";
    } else {
        return "(" + format_tree(tree->l) + " " + format_tree(tree->r) + ")";
    }
}

int main() {
    while (true) {
        string s; getline(cin, s);
        if (s == "0") break;
        auto tree = parse_tree(s);
        normalize(tree);
        cout << format_tree(tree) << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 200
memory_kb: 3476
final_rank: 20