#include <bits/stdc++.h>

#ifdef LOCAL
#include "dump.hpp"
#else
#define dump(...)
#endif

using namespace std;

struct fraction {
	typedef long long int_t;
	int_t nume, deno;

	static inline int_t gcd(int_t a, int_t b) {
		return __gcd(abs(a), abs(b));
	}

	void reduce() {
		const int_t g = gcd(nume, deno);
		nume /= g; deno /= g;
	}

	fraction(int_t nume_ = 0, int_t deno_ = 1):nume(nume_), deno(deno_) { reduce(); }
	fraction(const fraction &f):nume(f.nume), deno(f.deno) {}

	fraction &operator+=(const fraction &f) {
		const int_t r_deno = deno / gcd(deno, f.deno) * f.deno;
		nume = r_deno / deno * nume + r_deno / f.deno * f.nume;
		deno = r_deno;
		reduce();
		return *this;
	}

	fraction &operator-=(const fraction &f) {
		return *this += fraction(-f.nume, f.deno);
	}

	fraction &operator*=(const fraction &f) {
		const int_t g1 = gcd(nume, f.deno);
		const int_t g2 = gcd(f.nume, deno);
		nume = (nume / g1) * (f.nume / g2);
		deno = (deno / g2) * (f.deno / g1);
		return *this;
	}

	fraction &operator/=(const fraction &f) {
		return *this *= fraction(f.deno, f.nume);
	}

	fraction operator+(const fraction &f) const {
		return fraction(*this) += f;
	}

	fraction operator-(const fraction &f) const {
		return fraction(*this) -= f;
	}

	fraction operator*(const fraction &f) const {
		return fraction(*this) *= f;
	}

	fraction operator/(const fraction &f) const {
		return fraction(*this) /= f;
	}

	bool operator==(const fraction &f) const {
		return nume == f.nume && deno == f.deno;
	}

	bool operator<(const fraction &f) const {
		const int_t lcm_deno = deno / gcd(deno, f.deno) * f.deno;
		return lcm_deno / deno * nume < lcm_deno / f.deno * f.nume;
	}

	string to_string() const {
		return std::to_string(nume) + "/" + std::to_string(deno);
	}

	double to_double() const {
		return (double)nume / deno;
	}

	long double to_long_double() const {
		return (long double)nume / deno;
	}
};

inline ostream &operator<<(ostream &os, const fraction &f) {
	return os << f.to_string();
}

inline fraction abs(const fraction &f) {
	return fraction(abs(f.nume), abs(f.deno));
}

typedef vector<fraction> vec;
typedef vector<vec> mat;

// Ax = bを解く Aは正方行列
vec gauss_jordan(const mat& A, const vec& b) {
	const int n = A.size();
	mat B(n, vec(n + 1));

	for(int i = 0; i < n; ++i) {
		for(int j = 0; j < n; ++j) {
			B[i][j] = A[i][j];
		}
	}

	for(int i = 0; i < n; ++i) {
		B[i][n] = b[i];
	}

	for(int i = 0; i < n; ++i) {
		dump(i);
		int pivot = i;
		for(int j = i; j < n; ++j) {
			if(abs(B[pivot][i]) < abs(B[j][i])) pivot = j;
		}
		B[i].swap(B[pivot]);

		if(B[i][i].nume == 0) break;

		// 使わないところは計算しない
		for(int j = i + 1; j <= n; ++j) {
			B[i][j] /= B[i][i];
		}

		for(int j = 0; j < n; ++j) {
			if(i != j) {
				for(int k = i + 1; k <= n; ++k) {
					B[j][k] -= B[j][i] * B[i][k];
				}
			}
		}
	}

	vec x(n);
	for(int i = 0; i < n; ++i) {
		x[i] = B[i][n];
	}
	return x;
}

inline long long lcm(long long a, long long b) {
	return a / __gcd(a, b) * b;
}

int number(string::const_iterator &it);
unordered_map<int, int> unit(string::const_iterator &it);
unordered_map<int, int> molecule(string::const_iterator &it);

unordered_map<string, int> converter;

int number(string::const_iterator &it) {
	int res = 0;
	while(isdigit(*it)) {
		res = res * 10 + *it - '0';
		++it;
	}
	return res;
}

unordered_map<int, int> unit(string::const_iterator &it) {
	unordered_map<int, int> res;

	if(*it == '(') {
		++it;
		res = molecule(it);
		assert(*it == ')');
		++it;
	}
	else {
		string name(1, *it);
		++it;
		while(islower(*it)) {
			name += *it;
			++it;
		}

		if(!converter.count(name)) converter.insert({name, converter.size()});
		res[converter[name]] = 1;
	}

	if(isdigit(*it)) {
		const int num = number(it);
		for(auto &e : res) e.second *= num;
	}
	return res;
}

unordered_map<int, int> molecule(string::const_iterator &it) {
	unordered_map<int, int> res = unit(it);

	while(isupper(*it) || *it == '(') {
		for(const auto &e : unit(it)) {
			res[e.first] += e.second;
		}
	}
	return res;
}

vector<unordered_map<int, int>> parse(const string &s) {
	auto it = s.cbegin();
	vector<unordered_map<int, int>> res;
	res.emplace_back(molecule(it));

	while(*it == '+') {
		++it;
		res.emplace_back(molecule(it));
	}
	return res;
}

int main() {
	cin.tie(nullptr);
	ios::sync_with_stdio(false);

	for(string equation; cin >> equation && equation[0] != '.';) {
		converter.clear();
		const int pos = equation.find('>');

		auto left = parse(equation.substr(0, pos));
		auto right = parse(equation.substr(pos + 1));

		const int n = converter.size();
		const int l = left.size();
		const int r = right.size();
		const int m = l + r;

		const int size = max(n + 1, m);

		mat A(size, vec(size, 0));
		for(int i = 0; i < n; ++i) {
			for(int j = 0; j < l; ++j) {
				A[i][j] = left[j][i];
			}

			for(int j = 0; j < r; ++j) {
				A[i][j + l] = -right[j][i];
			}
		}
		A[n][0] = 1;

		vec b(n + 1);
		b[n] = 1;

		dump(equation);
		dump(converter);
		dump(left);
		dump(right);
		dump(A);
		dump(b);

		auto x = gauss_jordan(A, b);
		long long c = 1;
		for(const auto &e : x) {
			c = lcm(c, e.deno);
		}

		for(int i = 0; i < m; ++i) {
			cout << abs(c / x[i].deno * x[i].nume) << (i + 1 == m ? '\n' : ' ');
		}
	}

	return EXIT_SUCCESS;
}

Measured memory_bytes: 1272