#include <iostream>
#include <fstream>
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <iomanip>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <sstream>
#include <string>
#include <vector>
using namespace std;

#pragma comment(linker, "/STACK:400000000")

#define EPS 1e-9
#define INF MOD
#define MOD 1000000007LL
#define fir first
#define foreach(it,X) for(it=X.begin();it!=X.end();it++)
#define iss istringstream
#define ite iterator
#define ll long long
#define mp make_pair
#define rep(i,n) rep2(i,0,n)
#define rep2(i,m,n) for(int i=m;i<n;i++)
#define pi pair<int,int>
#define pb push_back
#define sec second
#define sh(i) (1LL<<i)
#define sst stringstream
#define sz size()
#define vi vector<int>
#define vc vector
#define vl vector<ll>
#define vs vector<string>

string s;
int cur,id;
int memo1[130][130],memo2[130][130];

struct tree{
	tree *l,*r;
	int id,size;
	double sim;
	tree(int x):id(x){size=1,l=NULL,r=NULL;}
};

bool operator !=(const tree &t,const tree &u);

bool operator <(const tree &t,const tree &u){
	int& res=memo1[t.id][u.id];
	if(res!=-1)return res;
	if(t.size != u.size)
		return res=t.size < u.size;
	if(t.l==NULL) return res=0;
	if(*t.l != *u.l){
		return res=*t.l < *u.l;
	}
	if(*t.r != *u.r){
		return res=*t.r < *u.r;
	}
	return res=0;
}

bool operator !=(const tree &t,const tree &u){
	return t<u || u<t;
}

bool diff(const tree &t, const tree &u);

bool stronger(const tree &t, const tree &u){
	int& res=memo2[t.id][u.id];
	if(res!=-1)return res;
	if(t.sim != u.sim)
		return res=t.sim < u.sim;
	if(t.l==NULL) return res=0;
	tree *t1,*t2,*u1,*u2;
	if(stronger(*t.l,*t.r))t1=t.l,t2=t.r;
	else t1=t.r,t2=t.l;
	if(stronger(*u.l,*u.r))u1=u.l,u2=u.r;
	else u1=u.r,u2=u.l;
	if(diff(*t1,*u1)){
		return res=stronger(*t1,*u1);
	}
	if(diff(*t2,*u2)){
		return res=stronger(*t2,*u2);
	}
	return res=0;
}

bool diff(const tree &t,const tree &u){
	return stronger(t,u) || stronger(u,t);
}
tree* parse(){
	tree* res=new tree(id++);
	if(s[cur]=='x'){
		cur++;
		return res;
	}
	cur++;
	res->l=parse();
	res->size+=res->l->size;
	cur++;
	res->r=parse();
	res->size+=res->r->size;
	cur++;
	if(*res->r < *res->l)
		swap(res->l,res->r);
	return res;
}

set<tree> calc(tree* t){
	set<tree> res;
	res.insert(*t);
	if(t->l==NULL){
		t->sim=0;
		return res;
	}
	set<tree> L=calc(t->l),R=calc(t->r);
	set<tree>::ite it;
	int common=0,total=0;
	foreach(it,L){
		total++;
		res.insert(*it);
	}
	foreach(it,R){
		if(L.count(*it))common++;
		else total++,res.insert(*it);
	}
	t->sim=1.*common/total;
	return res;
}

void arrange(tree *t,bool left){
	if(t->l==NULL)return;
	if(left && !stronger(*t->l,*t->r) ||
		!left && stronger(*t->l,*t->r))
		swap(t->l,t->r);
	arrange(t->l,1);
	arrange(t->r,0);
}

void show(tree *t){
	if(t==NULL)return;
	if(t->l==NULL){
		cout<<"x";return;
	}
	cout<<"(";
	show(t->l);
	cout<<" ";
	show(t->r);
	cout<<")";
}

int main(){
	while(getline(cin,s) && s[0]!='0'){
		memset(memo1,-1,sizeof(memo1));
		memset(memo2,-1,sizeof(memo2));
		tree *t;
		cur=id=0;
		t=parse();
		calc(t);
		arrange(t,1);
		show(t);
		cout<<endl;
	}
}

Measured memory_bytes: 0