#include <iostream>
#include <algorithm>
#include <string>
#include <set>
#include <vector>
using IntVec = std::vector<int>;
class Combination
{
public:
Combination(int n, int k) : n(n), k(k), data(k)
{ std::iota(begin(data), end(data), 0); }
bool next_combination()
{
if (n - k == data[0]) return false;
int i = k - 1;
while (i > 0 && data[i] == n-k+i) --i;
++data[i];
for (int j = i; j < k-1; ++j) data[j+1] = data[j] + 1;
return true;
}
const IntVec& array()const { return data; }
private:
int n, k;
IntVec data;
};
struct ArrayMap {
ArrayMap(const std::string* s) : id(26,-1), values(), nUnique(0)
{
for (int i = 0; i < 3; ++i) for (char c : s[i])
if (id[c-'A'] == -1) id[c-'A'] = nUnique++;
}
int operator[](char c)const { return values[id[c-'A']]; }
int operator()(const std::string* s, int k)const
{
int ret = 0, coef = 1;
for (int i = s[k].size(); i--; coef *= 10) ret += coef*(*this)[s[k][i]];
return ret;
}
IntVec id, values;
int nUnique;
};
void solve(const std::string* s, bool unique=true)
{
std::cout << s[0] << " + " << s[1] << " = " << s[2] << "\n";
// Prepare character map
ArrayMap p(s);
if (p.nUnique > 10)
{
std::cout << "Too many characters (" << p.nUnique << ")\n\n";
return;
}
// Solve
Combination comb(10, p.nUnique);
bool hasSolution = false;
do {
p.values = comb.array();
do {
if (p[s[0][0]]&&p[s[1][0]]&&p[s[2][0]] && p(s,0)+p(s,1)==p(s,2))
{
std::cout<<p(s,0)<<" + "<<p(s,1)<<" = "<<p(s,2)<<"\n";
hasSolution = true;
if (unique) break;////////////////
}
} while (std::next_permutation(begin(p.values), end(p.values)));
} while (comb.next_combination());
if (!hasSolution) std::cout << "No solution\n";
std::cout << "\n";
}
int main()
{
std::string s[3];
while(std::cin >> s[0] >> s[1] >> s[2]) solve(s, false);
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8YWxnb3JpdGhtPgojaW5jbHVkZSA8c3RyaW5nPgojaW5jbHVkZSA8c2V0PgojaW5jbHVkZSA8dmVjdG9yPgp1c2luZyBJbnRWZWMgPSBzdGQ6OnZlY3RvcjxpbnQ+OwoKY2xhc3MgQ29tYmluYXRpb24KewpwdWJsaWM6CiAgICBDb21iaW5hdGlvbihpbnQgbiwgaW50IGspIDogbihuKSwgayhrKSwgZGF0YShrKQogICAgeyBzdGQ6OmlvdGEoYmVnaW4oZGF0YSksIGVuZChkYXRhKSwgMCk7IH0KICAgIGJvb2wgbmV4dF9jb21iaW5hdGlvbigpCiAgICB7CgkgICAgaWYgKG4gLSBrID09IGRhdGFbMF0pIHJldHVybiBmYWxzZTsKCSAgICBpbnQgaSA9IGsgLSAxOwoJICAgIHdoaWxlIChpID4gMCAmJiBkYXRhW2ldID09IG4taytpKSAtLWk7CgkgICAgKytkYXRhW2ldOwoJICAgIGZvciAoaW50IGogPSBpOyBqIDwgay0xOyArK2opIGRhdGFbaisxXSA9IGRhdGFbal0gKyAxOwoJICAgIHJldHVybiB0cnVlOwoJfQogICAgY29uc3QgSW50VmVjJiBhcnJheSgpY29uc3QgeyByZXR1cm4gZGF0YTsgfQpwcml2YXRlOgogICAgaW50IG4sIGs7CiAgICBJbnRWZWMgZGF0YTsKfTsKCnN0cnVjdCBBcnJheU1hcCB7CglBcnJheU1hcChjb25zdCBzdGQ6OnN0cmluZyogcykgOiBpZCgyNiwtMSksIHZhbHVlcygpLCBuVW5pcXVlKDApCgl7CgkJZm9yIChpbnQgaSA9IDA7IGkgPCAzOyArK2kpIGZvciAoY2hhciBjIDogc1tpXSkKCQkJaWYgKGlkW2MtJ0EnXSA9PSAtMSkgaWRbYy0nQSddID0gblVuaXF1ZSsrOwoJfQoJaW50IG9wZXJhdG9yW10oY2hhciBjKWNvbnN0IHsgcmV0dXJuIHZhbHVlc1tpZFtjLSdBJ11dOyB9CglpbnQgb3BlcmF0b3IoKShjb25zdCBzdGQ6OnN0cmluZyogcywgaW50IGspY29uc3QKCXsKCQlpbnQgcmV0ID0gMCwgY29lZiA9IDE7CgkJZm9yIChpbnQgaSA9IHNba10uc2l6ZSgpOyBpLS07IGNvZWYgKj0gMTApIHJldCArPSBjb2VmKigqdGhpcylbc1trXVtpXV07CgkJcmV0dXJuIHJldDsKCX0KCUludFZlYyBpZCwgdmFsdWVzOwoJaW50IG5VbmlxdWU7Cn07Cgp2b2lkIHNvbHZlKGNvbnN0IHN0ZDo6c3RyaW5nKiBzLCBib29sIHVuaXF1ZT10cnVlKQp7CglzdGQ6OmNvdXQgPDwgc1swXSA8PCAiICsgIiA8PCBzWzFdIDw8ICIgPSAiIDw8IHNbMl0gPDwgIlxuIjsKCS8vIFByZXBhcmUgY2hhcmFjdGVyIG1hcAoJQXJyYXlNYXAgcChzKTsKCWlmIChwLm5VbmlxdWUgPiAxMCkKCXsKCQlzdGQ6OmNvdXQgPDwgIlRvbyBtYW55IGNoYXJhY3RlcnMgKCIgPDwgcC5uVW5pcXVlIDw8ICIpXG5cbiI7CgkJcmV0dXJuOwoJfQoJLy8gU29sdmUKCUNvbWJpbmF0aW9uIGNvbWIoMTAsIHAublVuaXF1ZSk7Cglib29sIGhhc1NvbHV0aW9uID0gZmFsc2U7CglkbyB7CgkJcC52YWx1ZXMgPSBjb21iLmFycmF5KCk7CgkJZG8gewoJCQlpZiAocFtzWzBdWzBdXSYmcFtzWzFdWzBdXSYmcFtzWzJdWzBdXSAmJiBwKHMsMCkrcChzLDEpPT1wKHMsMikpCgkJCXsKCQkJCXN0ZDo6Y291dDw8cChzLDApPDwiICsgIjw8cChzLDEpPDwiID0gIjw8cChzLDIpPDwiXG4iOwoJCQkJaGFzU29sdXRpb24gPSB0cnVlOwoJCQkJaWYgKHVuaXF1ZSkgYnJlYWs7Ly8vLy8vLy8vLy8vLy8vLwoJCQl9CgkJfSB3aGlsZSAoc3RkOjpuZXh0X3Blcm11dGF0aW9uKGJlZ2luKHAudmFsdWVzKSwgZW5kKHAudmFsdWVzKSkpOwoJfSB3aGlsZSAoY29tYi5uZXh0X2NvbWJpbmF0aW9uKCkpOwoJaWYgKCFoYXNTb2x1dGlvbikgc3RkOjpjb3V0IDw8ICJObyBzb2x1dGlvblxuIjsKCXN0ZDo6Y291dCA8PCAiXG4iOwp9CgppbnQgbWFpbigpCnsKCXN0ZDo6c3RyaW5nIHNbM107Cgl3aGlsZShzdGQ6OmNpbiA+PiBzWzBdID4+IHNbMV0gPj4gc1syXSkgc29sdmUocywgZmFsc2UpOwp9Cg==