#include<bits/stdc++.h>

#define REP(i,s,n) for(int i=s;i<n;i++)
#define rep(i,n) REP(i,0,n)
#define EPS (1e-8)
#define equals(a,b) (fabs((a)-(b))<EPS)

using namespace std;

typedef long long ll;
const ll LLINF = LLONG_MAX;
const double DINF = 1e30;


// -----------------------------------------
long long gcd(long long a, long long b) { return a > 0LL ? gcd(b % a, a) : b; }
struct Rational {
  long long p, q;
  void normalize() { // keep q positive
    if (q < 0) p *= -1LL, q *= -1LL;
    long long d = gcd(p < 0LL ? -p : p, q);
    if (d == 0) p  = 0LL,  q = 1LL;
    else        p /= d,    q /= d;
  }
  Rational(long long p, long long q = 1LL) : p(p), q(q) {
    normalize();
  }
  Rational &operator += (const Rational &a) {
    p = a.q * p + a.p * q; q = a.q * q; normalize();
    return *this;
  }
  Rational &operator -= (const Rational &a) {
    p = a.q * p - a.p * q; q = a.q * q; normalize();
    return *this;
  }
  Rational &operator *= (const Rational &a) {
    p *= a.p; q *= a.q; normalize();
    return *this;
  }
  Rational &operator /= (const Rational &a) {
    p *= a.q; q *= a.p; normalize();
    return *this;
  }
  Rational &operator - () {
    p *= -1LL;
    return *this;
  }
};
Rational operator + (const Rational &a, const Rational &b) {
  return Rational(a) += b;
}
Rational operator * (const Rational &a, const Rational &b) {
  return Rational(a) *= b;
}
Rational operator - (const Rational &a, const Rational &b) {
  return Rational(a) -= b;
}
Rational operator / (const Rational &a, const Rational &b) {
  return Rational(a) /= b;
}
bool operator < (const Rational &a, const Rational &b) { // avoid overflow
  return (long double) a.p * b.q < (long double) a.q * b.p;
}
bool operator <= (const Rational &a, const Rational &b) {
  return !(b < a);
}
bool operator > (const Rational &a, const Rational &b) {
  return b < a;
}
bool operator >= (const Rational &a, const Rational &b) {
  return !(a < b);
}
bool operator == (const Rational &a, const Rational &b) {
  return !(a < b) && !(b < a);
}
bool operator != (const Rational &a, const Rational &b) {
  return (a < b) || (b < a);
}
// -----------------------------------------

vector<Rational> jordan(vector<vector<Rational> > A){
  int h = A.size(), w = A[0].size();
  int mini = min(h,w);
  rep(i,mini) {
    for(int j=i+1;A[i][i].p==0&&j<h;j++) swap(A[i],A[j]);
    if(A[i][i].p==0) continue;
    Rational r = Rational(1)/A[i][i];
    REP(k,i,w) A[i][k] = A[i][k] * r;
    rep(j,h) {
      if( i == j ) continue;
      Rational t = A[j][i];
      REP(k,i,w) A[j][k] -= t * A[i][k];
    }
  }
  /*
  rep(i,A.size()) {
    rep(j,A[i].size()){
      cout << A[i][j] << " ";
    } puts("");
  }puts("-");

  rep(i,w) {
    cout << A[i][w-1] << "?" << endl;
  }
  */
  vector<Rational> ret;
  rep(i,w-1) ret.push_back(A[i][w-1]);
  
  return ret;
}

// -----------------------------------------

struct Molecule { // H
  int coef,id;
};
typedef vector<Molecule> MoleculeSeq; // H2O
int INDEX;
map<string,int> mp;

int ptr;
MoleculeSeq expr(string &context){
  MoleculeSeq seq;
  while( ptr < context.size() && ( isalpha(context[ptr]) || context[ptr] == '(' ) ) {
    if( isalpha(context[ptr]) ) {
      string unit = string(1,context[ptr++]);
      if( ptr < context.size() && islower(context[ptr]) ) {
        unit += context[ptr++];
      }
      int coef = 0;
      while( ptr < context.size() && isdigit(context[ptr]) ) {
        coef *= 10;
        coef += ( context[ptr++] - '0' );
      }
      if( coef == 0 ) coef = 1;
      if( !mp.count(unit) ) mp[unit] = INDEX++;
      int id = mp[unit];
      seq.push_back((Molecule){coef,id});
    } else {
      assert(context[ptr] == '(');
      ptr++;
      MoleculeSeq added_seq = expr(context);
      assert(context[ptr] == ')');
      ++ptr;
      int coef = 0;
      while( ptr < context.size() && isdigit(context[ptr]) ) {
        coef *= 10;
        coef += ( context[ptr++] - '0' );
      }
      if( coef == 0 ) coef = 1;
      rep(i,(int)added_seq.size()) {
        added_seq[i].coef *= coef;
        seq.push_back(added_seq[i]);
      }
    }
  }
  return seq;
}

vector<MoleculeSeq> calcFormula(string context) {
  vector<MoleculeSeq> seq;
  rep(i,(int)context.size()) if( context[i] == '+' ) {
    context[i] = ' ';
  }
  stringstream ss;
  ss << context;
  while( ss >> context ) {
    ptr = 0;
    seq.push_back(expr(context));
  }
  return seq;
}

void compute(string &context){
  mp.clear();
  INDEX = 0;
  string forward, backward;
  rep(i,(int)context.size()) if( context[i] == '-' ){
    forward  = context.substr(0,i);
    backward = context.substr(i+2);
    backward.erase((int)backward.size()-1);
    break;
  }
  vector<MoleculeSeq> forward_formula  = calcFormula(forward);  
  vector<MoleculeSeq> backward_formula = calcFormula(backward);  
  vector<MoleculeSeq> formula = forward_formula;
  rep(i,backward_formula.size()) {
    rep(j,backward_formula[i].size()) {
      backward_formula[i][j].coef *= -1;
    }
    formula.push_back(backward_formula[i]);
  }

  // for(map<string,int>::iterator it=mp.begin();it!=mp.end();it++){
  //   cout << "[" << (it->first) << "," << (it->second) << "] ";  
  // } puts("");
  // rep(i,formula.size()){
  //   cout << "{";
  //   rep(j,formula[i].size()){
  //     cout << formula[i][j].coef << "*[" << formula[i][j].id << "] ";
  //   }
  //   cout << "}, ";
  // } puts("");

  // ---------- Matrix phase ---------- //
  vector<vector<Rational> > A(INDEX,vector<Rational>(formula.size(),Rational(0)));
  rep(i,formula.size()) {
    rep(j,formula[i].size()) {
      A[formula[i][j].id][i] += Rational(formula[i][j].coef);
    }
  }
  /*
  rep(i,A.size()) {
    rep(j,A[i].size()){
      cout << A[i][j].p << "/" << A[i][j].q << " ";
    } puts("");
  }
*/
  vector<Rational> res = jordan(A);
  ll lcm = 1;
  rep(i,res.size()) lcm = lcm/__gcd(lcm,res[i].q)*res[i].q;
  rep(i,res.size()) {
    cout << abs(res[i].p*lcm/res[i].q) << ' ';
  } 
  cout << abs(lcm) << endl;

}

int main(){
  /*
  vector<vector<double> > A(5,vector<double>(3,0));
  A[0][0] = 1, A[0][2] = -1;
  A[1][0] = 2;
  A[2][1] = 1;
  A[3][1] = 1, A[3][2] = -2;
  A[4][1] = 3, A[4][2] = -6;
  vector<double> b(5,0);
  b[1] = 1, b[1] = 1;
  vector<double> res;
  rep(i,A.size()) {
    cout << "[";
    rep(j,A[i].size()){
      if( j ) cout << ", ";
      cout << A[i][j];
    }
    cout << "]" << endl;
  }
  cout << gauss_jordan(A,b,res) << endl;
  rep(i,(int)res.size()) {
    cout << res[i] << " ";
  } puts("");
  return 0;
  */
  /*
  vector<vector<Rational> > A(5,vector<Rational>(4,0));
  A[0][0] = Rational(1), A[0][2] = Rational(-1); 
  A[1][0] = Rational(2), A[1][3] = Rational(-1);
  A[2][1] = Rational(1), A[2][3] = Rational(-1);
  A[3][1] = Rational(1), A[3][2] = Rational(-2);
  A[4][1] = Rational(3), A[4][2] = Rational(-6);
  vector<Rational> res = jordan(A);
  rep(i,A.size()) {
    cout << "[";
    rep(j,A[i].size()){
      if( j ) cout << ", ";
      cout << A[i][j].p<<"/"<<A[i][j].q<<" ";
    }
    cout << "]" << endl;
  }
  rep(i,(int)res.size()) {
    cout << res[i].p<<"/"<<res[i].q << " ";
  } puts("");
  return 0;
  */
  string context;
  while( cin >> context, context[0] != '.'){
    compute(context);
  }
  return 0;
}

Measured memory_bytes: 1268