#include <cstdio>
#include <cassert>
#include <queue>
#include <vector>
#include <set>
#include <map>
#include <string>
#include <algorithm>
using namespace std;


struct Node {
	Node* lch;
	Node* rch;
	pair<int,int> score;
	bool left;
	Node() : lch(nullptr), rch(nullptr), score(-1, -1), left(false) {}
};

Node* to_tree_rec(const char* s, int &it)
{
	if(s[it] == 'x') {
		it += 1;
		Node* node = new Node();
		return node;
	}

	assert(s[it] == '('); it += 1;
	Node* lch = to_tree_rec(s, it);
	assert(s[it] == ' '); it += 1;
	Node* rch = to_tree_rec(s, it);
	assert(s[it] == ')'); it += 1;

	Node* node = new Node();
	node->lch = lch;
	node->rch = rch;
	lch->left = true;

	return node;
}

Node* to_tree(const char* s)
{
	int it = 0;
	Node* node = to_tree_rec(s, it);
	node->left = true;
	return node;
}

string to_str(const Node* node)
{
	if(node->lch == nullptr && node->rch == nullptr)
		return "x";

	assert(node->lch != nullptr);
	assert(node->rch != nullptr);

	string lstr = to_str(node->lch);
	string rstr = to_str(node->rch);

	return "(" + lstr + " " + rstr + ")";
}

pair<set<string>, string> enumerate_subtrees(Node* node)
{
	if(!node->lch && !node->rch) {
		set<string> s;
		s.insert("x");
		return {s, "x"};
	}

	auto l_res = enumerate_subtrees(node->lch);
	auto r_res = enumerate_subtrees(node->rch);

	string tree_str;
	if(l_res.second < r_res.second)
		tree_str = "(" + l_res.second + " " + r_res.second + ")";
	else
		tree_str = "(" + r_res.second + " " + l_res.second + ")";

	set<string> subtrees;

	subtrees.insert(l_res.first.begin(), l_res.first.end());
	subtrees.insert(r_res.first.begin(), r_res.first.end());
	subtrees.insert(tree_str);

	return {subtrees, tree_str};
}

void calc_score(Node* node)
{
	if(!node->lch && !node->rch) {
		node->score = {0, 1};
		return;
	}

	calc_score(node->lch);
	calc_score(node->rch);

	set<string> l_subtree = enumerate_subtrees(node->lch).first;
	set<string> r_subtree = enumerate_subtrees(node->rch).first;

	int total = l_subtree.size();
	int same = 0;

	for(auto it : r_subtree) {
		bool exist = l_subtree.find(it) != l_subtree.end();
		if(exist)
			same += 1;
		else
			total += 1;
	}

	node->score = {same, total};
}

int cmp_score(const pair<int, int> &a, const pair<int, int> &b)
{
	const int p = a.first;
	const int q = a.second;
	const int r = b.first;
	const int s = b.second;

	assert(p != -1);
	assert(r != -1);

	if(p * s == q * r)
		return 0;
	if(p * s < q * r)
		return 1;
	return -1;
}

int cmp_node(Node* a, Node* b, map<pair<Node*, Node*>, int> &memo)
{
	pair<Node*, Node*> idx = {a, b};
	if(a > b)
		swap(idx.first, idx.second);
	if(memo.find(idx) != memo.end())
		return memo[idx];

	if(cmp_score(a->score, b->score) != 0)
		return memo[idx] = -cmp_score(a->score, b->score);

	if(!a->lch && !b->lch)
		return memo[idx] = 0;

	Node* a1 = a->lch;
	Node* a2 = a->rch;
	Node* b1 = b->lch;
	Node* b2 = b->rch;

	if(cmp_node(a1, a2, memo) == 1)
		swap(a1, a2);
	if(cmp_node(b1, b2, memo) == 1)
		swap(b1, b2);

	if(cmp_node(a1, b1, memo) != 0)
		return memo[idx] = cmp_node(a1, b1, memo);
	return memo[idx] = cmp_node(a2, b2, memo);
}

void modify_tree(Node* tree)
{
	queue<Node*> q;
	map<pair<Node*, Node*>, int> memo;

	q.push(tree);

	while(!q.empty()) {

		Node* node = q.front();
		q.pop();

		//string hoge = to_str(node);
		//printf("in: %s\n", hoge.c_str());

		Node* lch = node->lch;
		Node* rch = node->rch;
		const bool left = node->left;

		if(!lch && !rch)
			continue;
		q.push(lch);
		q.push(rch);

		const bool state = cmp_node(lch, rch, memo) == -1;
		if(left != state) {
			swap(node->lch, node->rch);
			swap(lch->left, rch->left);
		}
	}
}

int main()
{
	while(true) {

		char buf[1024];

		scanf("%[^\n]", buf);
		if(buf[0] == '0')
			break;
		scanf("\n");

		Node* tree = to_tree(buf);
		calc_score(tree);
		modify_tree(tree);
		string s = to_str(tree);

		const pair<int, int> prev_total_score = tree->score;
		calc_score(tree);
		assert(cmp_score(prev_total_score, tree->score) == 0);

		printf("%s\n", s.c_str());
	}

	return 0;
}

Measured memory_bytes: 1904