#include "bits/stdc++.h"
#include<unordered_map>
#include<unordered_set>
#pragma warning(disable:4996)
using namespace std;

string st;
int a;

int get_num() {
	int num=0;
	while (a != st.size() && isdigit(st[a])) {
		num*=10;
		num+=st[a]-'0';
		a++;
	}
	return num;
}
map<string ,int>mole();
map<string, int>uni_group() {
	if (st[a] == '(') {
		a++;
		auto mp=mole();
		assert(st[a]==')');
		a++;
		return mp;
	}
	else {
		string name=string(1,st[a]);
		a++;
		if (a != st.size() && 'a' <= st[a] && st[a] <= 'z') {
			name.push_back(st[a]);
			a++;
		}
		map<string ,int>amp;
		amp[name]=1;
		return amp;
	}
}
map<string ,int>group() {
	auto mp(uni_group());
	int num=1;
	if (a != st.size() && isdigit(st[a])) {
		num=get_num();
	}
	for (auto& m : mp) {
		m.second*=num;
	}
	return mp;

}
map<string, int>mole() {
	auto mp(group());
	while (true) {
		if (a == st.size()||st[a]=='+'||st[a]==')') {
			break;
		}
		else {
			auto n_mp(group());
			for (auto n_m : n_mp) {
				mp[n_m.first] += n_m.second;
			}
		}
	}
	return mp;
}

/* verified AOJ1327 One-Dimensional Cellular Automaton
~Matrix~
行列の簡単な計算ができる
vector iostream cmath cassert 必須
Matrix a(VV), b(VV);
行列式:a*b
スカラ積:l*a
和:a+b
差:a-b
転置:a.transport()
余因子:a.cofactor()
行列式:a.det()
aのi行j列目:a.get(i,j)　
aのi行目j列目にkを代入:set(i,j,k)
もしくはa[i][j] (a[i][j]=k)
aのx乗:a.pow(x)
n*n基本行列E:Matrix(n)
m*n 0行列:Matrix(m,n)
m*n 全要素がpの行列:Matrix(m,n,p)
Row型rowでの初期化(m*1行列):Matrix(row)
**(整数不可)**
三角化:a.triangulate()
ランク:a.rank()
逆行列:a.inverse()
//(逆行列のa.det()倍ならa.pre_inverse()で求まる 整数可)
ガウスの消去法:a.rowReduction()
//連立一次方程式が解ける
***
*/

#include <vector>
#include <iostream>
#include <cmath>
#include <cassert>
using namespace std;

typedef double Elem;
typedef vector<Elem> Row;
typedef vector<Row> VV;

typedef long double ld;
const ld EPS = 1e-11;

const bool isZero(const Elem e) {
	return abs(e) < EPS;
}

struct Matrix {
	VV matrix;
	int n, m;

	Matrix(const VV &matrix_);
	explicit Matrix(int n_);
	explicit Matrix(const Row &row);
	Matrix(int m_, int n_);
	Matrix(int m_, int n_, Elem e);

	const Elem get(const int i, const int j) const;
	void set(const int x, const int y, const Elem k);

	const Matrix operator + (const Matrix &rhs) const;
	const Matrix operator * (const Matrix &rhs) const;
	const Matrix operator - (const Matrix &rhs) const;
	Matrix &operator += (const Matrix &rhs);
	Matrix &operator *= (const Matrix &rhs);
	Matrix &operator -= (const Matrix &rhs);

	Row &operator[](const int x);

	const Matrix transport() const;
	const Matrix pow(int x) const;
	const Matrix cofactor(int x, int y) const;
	const Elem det() const;

	const Matrix triangulate() const;
	const int rank() const;

	//逆行列が存在すれば、(行列式)*(逆行列)を返す
	//A:matrix,return det A * A^-1
	const Matrix pre_inverse() const;
	const Matrix inverse() const;
	const Matrix rowReduction() const;
};

const Matrix operator * (const Elem lambda, const Matrix &rhs) {
	Matrix tmp(rhs);
	for (int i = 0; i < rhs.m; i++)
		for (int j = 0; j < rhs.n; j++)
			tmp.set(i, j, tmp.get(i, j) * lambda);
	return tmp;
}

Matrix::Matrix(const VV &matrix_) : matrix(matrix_) {
	m = matrix_.size();
	if (m == 0) n = 0;
	else n = matrix_[0].size();
}
Matrix::Matrix(int n_) : m(n_), n(n_) {
	matrix = VV(n, Row(n, 0));
	for (int i = 0; i < n; ++i)
		set(i, i, 1);
}
Matrix::Matrix(const Row &row) : m(1), n(row.size()), matrix(VV(1, row)) {
	//sizeがmのvector<Elem>からmx1行列の生成
	(*this) = transport();
}
Matrix::Matrix(int m_, int n_) : m(m_), n(n_) {
	matrix = VV(m, Row(n, 0));
}
Matrix::Matrix(int m_, int n_, Elem e) : m(m_), n(n_) {
	matrix = VV(m, Row(n, e));
}

const Elem Matrix::get(const int i, const int j) const {
	if (0 <= i && i < m && 0 <= j && j < n)
		return matrix[i][j];

	cerr << "get(" << i << "," << j << ")is not exist." << endl;
	throw;
}
void Matrix::set(const int i, const int j, const Elem k) {
	if (0 <= i && i < m && 0 <= j && j < n) {
		*(matrix[i].begin() + j) = k;
		return;
	}
	cerr << "set(" << i << "," << j << ")is not exist." << endl;
	throw;
}

const Matrix Matrix::operator + (const Matrix &rhs) const {
	assert(m == rhs.m && n == rhs.n);

	Matrix tmp(m, n, 0);
	for (int i = 0; i < m; i++) {
		for (int j = 0; j < n; j++) {
			tmp.set(i, j, get(i, j) + rhs.get(i, j));
		}
	}
	return tmp;
}

const Matrix Matrix::operator * (const Matrix &rhs) const {
	assert(n == rhs.m);

	Matrix tmp(m, rhs.n, 0);
	Elem sum;
	for (int i = 0; i < m; i++)
		for (int j = 0; j < rhs.n; j++) {
			sum = 0;
			for (int k = 0; k < n; k++) {
				sum += get(i, k) * rhs.get(k, j);
			}
			tmp.set(i, j, sum);
		}
	return tmp;
}

const Matrix Matrix::operator - (const Matrix &rhs) const {
	return *this + ((Elem)-1 * rhs);
}

Matrix &Matrix::operator += (const Matrix &rhs) {
	return *this = *this + rhs;
}

Matrix &Matrix::operator *= (const Matrix &rhs) {
	return *this = *this * rhs;;
}

Matrix &Matrix::operator -= (const Matrix &rhs) {
	return *this = *this - rhs;
}

Row &Matrix::operator[](const int x) {
	return matrix[x];
}

const Matrix Matrix::transport() const {
	VV tmp;
	for (int i = 0; i < n; i++) {
		Row row;
		for (int j = 0; j < m; j++)
			row.push_back(get(j, i));
		tmp.push_back(row);
	}
	return tmp;
}

const Matrix Matrix::pow(int x) const {
	Matrix tmp(*this), e(m);
	for (int i = 1; i <= x; i <<= 1) {
		if ((x & i) > 0)
			e = e * tmp;
		tmp = tmp * tmp;
	}
	return e;
}

const Matrix Matrix::cofactor(int x, int y) const {
	VV tmp;
	for (int i = 0; i < m; i++) {
		if (x == i) continue;
		Row row;
		for (int j = 0; j < n; j++) {
			if (y == j) continue;
			row.push_back(get(i, j));
		}
		tmp.push_back(row);
	}
	return Matrix(tmp);
}

const Elem Matrix::det() const {
	assert(n == m);
Matrix tri = triangulate();
Elem ans = 1;
for (int i = 0; i < n; ++i) {
	ans *= tri[i][i];
}
return ans;

	if (m == 1)
		return get(0, 0);
	Elem sum = 0;
	for (int i = 0; i < m; i++) {
		sum += ((i % 2 == 0 ? 1 : -1) * get(i, 0)) * Matrix(cofactor(i, 0)).det();
	}
	return sum;
}

const Matrix Matrix::triangulate() const {
	Matrix tmp(*this);
	Elem e;
	int p = 0;
	for (int i = 0; i < m && p < n; i++, p++) {
		if (isZero(tmp.get(i, p))) {
			tmp.set(i, p, 0);
			bool flag = true;
			for (int j = i + 1; j < m; j++)
				if (!isZero(tmp.get(j, p))) {
					for (int k = 0; k < n; k++)
						tmp.set(i, k, tmp.get(i, k) + tmp.get(j, k));
					//tmp[i].swap(tmp[j]);
					flag = false;
					break;
				}
			if (flag) {
				i--;
				continue;
			}
		}
		for (int j = i + 1; j < m; j++) {
			e = tmp.get(j, p) / tmp.get(i, p);
			for (int k = 0; k < n; k++)
				tmp.set(j, k, tmp.get(j, k) - tmp.get(i, k) * e);
		}
	}
	return tmp;
}

const int Matrix::rank() const {
	Matrix tmp(triangulate());
	for (int i = min(tmp.m - 1, tmp.n - 1); i >= 0; i--) {
		for (int j = tmp.n - 1; j >= i; j--)
			if (isZero(tmp.get(i, j)))
				continue;
			else
				return i + 1;
	}
	return 0;
}

const Matrix Matrix::pre_inverse() const {
	assert(m == n);

	Matrix tmp(m, n, 0);
	for (int i = 0; i < m; i++)
		for (int j = 0; j < n; j++)
			tmp.set(i, j, ((i + j) % 2 == 0 ? 1 : -1)*cofactor(i, j).det());
	return tmp.transport();
}

/*O(n!)実装
const Matrix Matrix::inverse() const {
Matrix tmp(pre_inverse());
Elem e = det();
assert(!isZero(e));
tmp = 1 / e * tmp;
return tmp.transport();
}*/

const Matrix Matrix::inverse() const {
	assert(m == n);

	Matrix tmp(m, n * 2), tmp2(m, n);
	for (int i = 0; i < m; i++)
		for (int j = 0; j < n; j++)
			tmp.set(i, j, get(i, j));
	for (int i = 0; i < m; i++)
		tmp.set(i, i + n, 1);

	tmp = tmp.rowReduction();

	//逆行列が存在するかどうかのチェック
	for (int i = 0; i < m; i++)
		assert(isZero(tmp.get(i, i) - 1));

	for (int i = 0; i < m; i++)
		for (int j = 0; j < n; j++)
			tmp2.set(i, j, tmp.get(i, j + n));

	return tmp2;
}

/*
a b c j
d e f k
g h i l

ax+by+cz=j;
dx+ey+fz=k;
gx+hy+iz=l;

|
V

1 0 0 x
0 1 0 y
0 0 1 z
右端が答え
*/
const Matrix Matrix::rowReduction() const {
	Matrix tmp(*this);
	Elem e;
	int p = 0;
	for (int i = 0; i < m && p < n; i++, p++) {
		if (isZero(tmp.get(i, p))) {
			tmp.set(i, p, 0);
			bool flag = true;
			for (int j = i + 1; j < m; j++)
				if (!isZero(tmp.get(j, p))) {
					for (int k = 0; k < n; k++)
						tmp.set(i, k, tmp.get(i, k) + tmp.get(j, k));
					//tmp[i].swap(tmp[j]);
					flag = false;
					break;
				}
			if (flag) {
				i--;
				continue;
			}
		}
		e = 1 / tmp.get(i, p);
		tmp.set(i, p, 1);
		for (int k = i + 1; k < n; k++)
			tmp.set(i, k, tmp.get(i, k)*e);
		for (int j = 0; j < m; j++) {
			if (i == j) continue;
			e = tmp.get(j, p);
			for (int k = 0; k < n; k++)
				tmp.set(j, k, tmp.get(j, k) - tmp.get(i, k) * e);
		}
	}
	return tmp;
}
vector<map<string, int>>mole_seq() {
	vector<map<string,int>>v;
	auto mp(mole());
	v.push_back(mp);
	while (true) {
		if (a == st.size()||st[a]==')') {
			break;
		}
		else {
			assert(st[a] == '+' || st[a] == ')');
			a++;
			auto n_mp(mole());
			v.push_back(n_mp);
		}
	}
	return v;
}

Matrix get_mat(vector<map<string, int>>l, vector<map<string, int>>r) {
	vector<string>sts;
	for (auto m : l) {
		for (auto k : m) {
			sts.push_back(k.first);
		}
	}
	for (auto m : r) {
		for (auto k : m) {
			sts.push_back(k.first);
		}
	}
	sort(sts.begin(),sts.end());
	sts.erase(unique(sts.begin(),sts.end()),sts.end());
	Matrix mat(sts.size()+1,(l.size() + r.size()+1));
	for (int i = 0; i < l.size(); ++i) {
		for (auto k : l[i]) {
			int x=find(sts.begin(),sts.end(),k.first)-sts.begin();
			mat[x][i]=k.second;
		}
	}
	for (int i = 0; i < r.size(); ++i) {
		for (auto k : r[i]) {
			int x=find(sts.begin(),sts.end(),k.first)-sts.begin();
			mat[x][l.size()+i]=-k.second;
		}
	}
	{
		mat[sts.size()][0]=1;
		mat[sts.size()][l.size()+r.size()]=1;
		
	}
	return mat;
}

int main()
{
	string name;
	while (cin >> name,name != ".") {
		a=0;
		st=name;
		vector<map<string ,int>>l,r;
		string l_st=st.substr(0,st.find("->"));
		string r_st=st.substr(st.find("->")+2);
		r_st.pop_back();

		a=0;
		st=l_st;
		l=mole_seq();
		a=0;
		st=r_st;
		r=mole_seq();

		Matrix mat=get_mat(l,r);

		auto ans=mat.rowReduction();

		mat=ans;
		vector<int>anss(l.size()+r.size());
		int k=1;
		for ( k = 1; k < 1000000; ++k) {
			bool ok=true;
			for (int i = 0; i < l.size()+r.size(); ++i) {
				double num=k*mat[i][mat[i].size()-1];
				if(abs(num-round(num))>1e-5)ok=false;
			}
			if(ok)break;
		}
		for (int i = 0; i < l.size() + r.size(); ++i) {
			anss[i]=(k*mat[i][mat[i].size()-1]+1e-5);
		}
		for (int i = 0; i < anss.size(); ++i) {
			cout<<anss[i];
			if(i==anss.size()-1)cout<<endl;
			else cout<<" ";
		}

		/*
		a b c j
		d e f k
		g h i l

		ax+by+cz=j;
		dx+ey+fz=k;
		gx+hy+iz=l;

		|
		V

		1 0 0 x
		0 1 0 y
		0 0 1 z
		右端が答え
		*/
	}
	return 0;
}



Measured memory_bytes: 3152