#include<iostream>
#include<cassert>
#include<map>
#include<cmath>
#include<vector>
#include<algorithm>
using namespace std;
#define REP(i,b,n) for(int i=b;i<n;i++)
#define rep(i,n)   REP(i,0,n)
#define mp         make_pair
#define pb         push_back

typedef long long ll;
typedef pair<int,int> pii;

const double eps = 1e-10;

ll gcd(ll a,ll b){
  return b ==0?a:gcd(b,a%b);
}

class Q{
public:
  ll u,v;// u/v
  Q():u(0),v(1){}
  Q(ll tu,ll tv):u(tu),v(tv){
    if (tu == 0){
      v=1;
      return;
    }
    if (v < 0){
      v*=-1;
      u*=-1;
    }
    ll g = gcd(u>0?u:-u,v);
    u/=g;
    v/=g;
  };
  Q operator+(const Q a)const{
    ll tu,tv;
    tv=v*a.v;
    tu=u*a.v + a.u*v;
    return Q(tu,tv);
  }
  Q operator-(const Q a)const{
    ll tu,tv;
    tv=v*a.v;
    tu=u*a.v-a.u*v;
    return Q(tu,tv);
  }
  Q operator*(const Q a)const{
    ll tu,tv;
    tv=v*a.v;
    tu=u*a.u;
    return Q(tu,tv);
  }
  Q operator/(const Q a)const{
    ll tu,tv;
    tv=v*a.u;
    tu=u*a.v;
    return Q(tu,tv);
  }
  ll myabs(){
    return u>0?u:-u;
  }
};

const int N = 200;
bool select_pivot(int r,int c,int k,Q mat[N][N]){
  int s=k;
  ll val=mat[k][k].myabs();
  REP(i,k+1,r){
    if (mat[i][k].myabs()>val)val=mat[i][k].myabs(),s=i;
  }
  if (val ==0)return false;

  REP(i,k,c+1)swap(mat[k][i],mat[s][i]);
  return true;
}

bool gauss(int r,int c,Q mat[N][N]){
  rep(k,c){
    if (!select_pivot(r,c,k,mat)){
      return false;
    }
    REP(i,k+1,c+1)mat[k][i]=mat[k][i]/mat[k][k];
    mat[k][k]=Q(1,1);
    REP(i,k+1,r){
      REP(j,k+1,c+1)mat[i][j]=mat[i][j]-(mat[i][k]*mat[k][j]);
      mat[i][k]=Q(0,1);
    }
  }
  for(int i=r-1;i>=0;i--){
    REP(j,i+1,c){
      mat[i][c]=mat[i][c]-(mat[i][j]*mat[j][c]);
    }
  }
  return true;
}

int getnum(string &in,map<string,int> &M){
  int index = M.size();
  if (M.find(in)  == M.end())M[in]=index;
  return M[in];
}

int digit(string &in,int &p){
  int ret=0;
  while(isdigit(in[p])){
    ret=ret*10 + (in[p++]-'0');
  }
  return ret;
}

int element(string &in,int &p,map<string,int>&M){
  string a="";
  a=a+in[p];
  p++;
  if (islower(in[p]))a=a+in[p++];
  return getnum(a,M);
}

vector<pii> group(string &in,int &p,map<string,int> &M){
  vector<pii> ret;
  while(true){
    if (in[p] == '+'||in[p]=='-'||in[p]==')'||in[p]=='.')break;
    if (in[p] == '('){
      p++;
      vector<pii> tmp=group(in,p,M);
      p++;//in[p]=')'
      int quan=1;
      if (isdigit(in[p])){
	quan=digit(in,p);
      }
      rep(i,tmp.size()){
	ret.pb(mp(tmp[i].first,tmp[i].second*quan));
      }
    }else {
      int mole=element(in,p,M);
      int quan=1;
      if (isdigit(in[p])){
	quan=digit(in,p);
      }
      ret.pb(mp(mole,quan));
    }
  }
  return ret;
}

void molecule(string &in,int &p,vector<pii>&a,map<string,int> &M){
  while(true){
    if (in[p] == '+'||in[p]=='.'||
	in[p] == '-')return;
    vector<pii> tmp = group(in,p,M);
    rep(i,tmp.size())a.pb(tmp[i]);
  }
}

bool solve(string &in){
  static Q mat[N][N];
  rep(i,N)rep(j,N)mat[i][j]=Q(0,1);
  int m=0;//x0,x1,,,xwhat

  //parsing
  int p=0;
  if (in.size()==1)return false;
  int sign=1;
  map<string,int> M;//molecu -> number
  while(p < in.size()){
    if (in[p] == '.')break;
    if (in[p] == '-'){
      sign=-1;
      p+=2;
    }
    if (in[p] == '+')p++;
    vector<pii> a;//molecular number, quantity
    molecule(in,p,a,M);
    
    rep(i,a.size()){
      mat[a[i].first][m].u+=sign*a[i].second;
    }
    m++;
  }
  m--;
  
  int n=M.size();
  rep(i,n){
    mat[i][m].u*=-1;
  }
 
  if (!gauss(n,m,mat));//assert(false);

  ll lcm=1;
  rep(i,m){
    ll g = gcd(lcm,mat[i][m].v);
    lcm=lcm/g*mat[i][m].v;
  }

  rep(i,m){
    cout << mat[i][m].u*(lcm/mat[i][m].v)<<' ';
  }
  cout << lcm << endl;
}

main(){
  string in;
  while(getline(cin,in) && in != "."){
    solve(in);
  }
}

Measured memory_bytes: 0