#include<iostream>
#include<string>
#include<algorithm>
#include<vector>
#include<iomanip>
#include<math.h>
#include<complex>
#include<queue>
#include<deque>
#include<stack>
#include<map>
#include<set>
#include<bitset>
#include<functional>
#include<assert.h>
#include<numeric>
using namespace std;
#define REP(i,m,n) for(int i=(int)(m) ; i < (int) (n) ; ++i )
#define rep(i,n) REP(i,0,n)
using ll = long long;
const int inf=1e9+7;
const ll longinf=1LL<<60 ;
const ll mod=1e9+7 ;

ll powmod(ll n,ll k){
    k%=mod-1;
    if(k<0)k+=mod-1;
    ll ret=1;
    while(k){
        if(k&1)ret=ret*n%mod;
        n=n*n%mod;
        k>>=1;
    }
    return ret;
}
template<class T> int GaussJordan(vector<vector<T>> &A, bool is_extended = false) {
    int m = A.size(), n = A[0].size();
    int rank = 0;
    for (int col = 0; col < n; ++col) {
        // 拡大係数行列の場合は最後の列は掃き出ししない
        if (is_extended && col == n-1) break;

        // ピボットを探す
        int pivot = -1;
        T ma = 0;
        for (int row = rank; row < m; ++row) {
            if (A[row][col]) {
                ma = A[row][col];
                pivot = row;
            }
        }
        // ピボットがなかったら次の列へ
        if (pivot == -1) continue;

        // まずは行を swap
        swap(A[pivot], A[rank]);

        // ピボットの値を 1 にする
        auto fac = A[rank][col];
        for (int col2 = 0; col2 < n; ++col2) (A[rank][col2] *= powmod(fac,mod-2))%=mod;

        // ピボットのある列の値がすべて 0 になるように掃き出す
        for (int row = 0; row < m; ++row) {
            if (row != rank && A[row][col]) {
                auto fac = A[row][col];
                for (int col2 = 0; col2 < n; ++col2) {
                    ( A[row][col2] += mod - A[rank][col2] * fac % mod) %= mod;
                }
            }
        }
        ++rank;
    }
    return rank;
}

template<class T> vector<T> linear_equation(vector<vector<T>> A, vector<T> b) {
    // extended
    int m = A.size(), n = A[0].size();
    vector<vector<T>> M(m, vector<T>(n + 1));
    for (int i = 0; i < m; ++i) {
        for (int j = 0; j < n; ++j) M[i][j] = A[i][j];
        M[i][n] = b[i];
    }
    int rank = GaussJordan(M, true);
    
    // check if it has no solution
    vector<T> res;
    for (int row = rank; row < m; ++row) if (M[row][n]) return res;

    // answer
    res.assign(n, 0);
    for (int i = 0; i < rank; ++i) res[i] = M[i][n];
    return res;
}

map<string, int> chems;

map<int,int> read(string& s,int& i, int coef = 1){
    if(i==s.size()||s[i]=='+'||s[i]=='>'||s[i]=='(')return {};
    if('a'<=s[i]&&s[i]<='z'){
        string name=s.substr(i,2);
        i+=2;
        auto ret = read(s,i);
        int idx = chems.size();
        if(chems.count(name))idx = chems[name];
        else chems[name] = idx;
        ret[idx] += coef;
        return ret;
    }
    else if('A'<=s[i]&&s[i]<='Z'){
        string name=s.substr(i,1);
        i+=1;
        auto ret = read(s,i);
        int idx = chems.size();
        if(chems.count(name))idx = chems[name];
        else chems[name] = idx;
        ret[idx] += coef;
        return ret;
    }
    else if(s[i]==')'){
        ++i;
        auto ret = read(s,i);
        ++i;
        auto res = read(s, i);
        for(auto p : ret){
            res[p.first] += coef * p.second;
        }
        return res;
    }
    else {
        int d = 1;
        int num = 0;
        while('0'<=s[i]&&s[i]<='9'){
            num+=d*(s[i]-'0');
            d*=10;
            ++i;
        }
        auto ret = read(s,i, num);
        return ret;
    }
}

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

void solve(string& s){
    chems.clear();
    reverse(s.begin(),s.end());
    int idx=1;
    vector<map<int,int>> a;
    bool sgn=false;
    while(idx<s.size()){
        a.push_back(read(s,idx));
        if(sgn){
            for(auto& p : a.back())p.second = mod - p.second;
        }
        ++idx;
        if(idx<s.size()&&s[idx]=='-'){
            ++idx;
            sgn=true;
        }
    }
    int n = chems.size();
    int m = a.size();
    vector<vector<ll>> mat(n+1,vector<ll>(m)) ;
    rep(i,n)rep(j,m){
        mat[i][j]=a[j][i];
    }
    rep(i,m){
        mat[n][i]=1;
    }
    vector<ll> res(n+1);
    res[n]=1;
    auto ans = linear_equation<ll>(mat,res);
    reverse(ans.begin(),ans.end());
    for(int i = 1 ; i <= 40000; ++i ){
        ll fn = i * powmod (ans[0], mod - 2) % mod;
        rep(j,m)ans[j] = ans[j] * fn % mod;
        ll g = 0;
        bool ok=true;
        rep(j,m){
            if(ans[j]>40000)ok=false;
            g = gcd(g, ans[j]);
        }
        if(ok&&g==1)break;
    }
    rep(i,m){
        cout<<ans[i];
        if(i==m-1)cout<<endl;
        else cout<<" ";
    }
}
int main(){
    string s;
    while(cin>>s,s!=".")solve(s);
    return 0;
}


Measured memory_bytes: 3036