#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <climits>
#include <cfloat>
#include <ctime>
#include <cassert>
#include <map>
#include <utility>
#include <set>
#include <iostream>
#include <memory>
#include <string>
#include <vector>
#include <algorithm>
#include <functional>
#include <sstream>
#include <complex>
#include <stack>
#include <queue>
#include <numeric>
#include <list>


using namespace std;

#ifdef _MSC_VER
#define __typeof__ decltype
template <class T> int __builtin_popcount(T n) { return n ? 1 + __builtin_popcount(n & (n - 1)) : 0; }
#endif

#define foreach(it, c) for (__typeof__((c).begin()) it=(c).begin(); it != (c).end(); ++it)
#define all(c) (c).begin(), (c).end()
#define rall(c) (c).rbegin(), (c).rend()
#define CLEAR(arr, val) memset(arr, val, sizeof(arr))

#define rep(i, n) for (int i = 0; i < n; ++i)

template <class T> void max_swap(T& a, const T& b) { a = max(a, b); }
template <class T> void min_swap(T& a, const T& b) { a = min(a, b); }

typedef long long ll;
typedef pair<int, int> pint;

const double EPS = 1e-8;
const double PI = acos(-1.0);
const int dx[] = { 0, 1, 0, -1 };
const int dy[] = { 1, 0, -1, 0 };


struct Digit
{
	char c;
	ll weight;
	bool forbid_zero, right_statement;
	Digit(char c, ll w, bool r)
		: c(c), weight(w), right_statement(r) { }

	ll comp_value() const
	{
		ll res = weight * 1000;
		if (right_statement)
			res += 100;
		return res;
	}
};
bool operator<(const Digit& a, const Digit& b)
{
	return a.comp_value() < b.comp_value();
}
vector<Digit> create_digits(string s, bool right)
{
	reverse(all(s));
	vector<Digit> res;
	for (int i = 0, w = 1; i < s.size(); ++i, w *= 10)
		res.push_back(Digit(s[i], w, right));
	return res;
}
vector<Digit> digits;
int res;
bool forbid_zero[256];
int map_to_num[256];
bool used[10];

void dfs(int k, ll left_sum, ll right_sum, bool check)
{
	if (k == digits.size())
	{
		if (left_sum == right_sum)
			++res;
		return;
	}
	else if (check)
	{
		ll mod = digits[k].weight;
		ll fix_l = left_sum % mod;
		ll fix_r = right_sum % mod;
		if (fix_l != fix_r)
			return;
	}

	Digit& d = digits[k];
	if (map_to_num[d.c] == -1)
	{
		for (int i = forbid_zero[d.c] ? 1 : 0; i < 10; ++i)
		{
			if (!used[i])
			{
				used[i] = true;
				map_to_num[d.c] = i;

				if (d.right_statement)
					dfs(k + 1, left_sum, right_sum + i * d.weight, true);
				else
					dfs(k + 1, left_sum + i * d.weight, right_sum, false);

				used[i] = false;
				map_to_num[d.c] = -1;
			}
		}
	}
	else
	{
		int num = map_to_num[d.c];

		if (d.right_statement)
			dfs(k + 1, left_sum, right_sum + num * d.weight, true);
		else
			dfs(k + 1, left_sum + num * d.weight, right_sum, false);
	}
}
int main()
{
	ios::sync_with_stdio(false);

	int n;
	while (cin >> n, n)
	{
		digits.clear();
		CLEAR(forbid_zero, 0);
		for (int i = 0; i < n; ++i)
		{
			string s;
			cin >> s;
			vector<Digit> d = create_digits(s, i + 1 == n);
			for (int j = 0; j < d.size(); ++j)
				digits.push_back(d[j]);
			if (s.size() > 1)
				forbid_zero[s[0]] = true;
		}
		sort(all(digits));

		CLEAR(map_to_num, -1);
		CLEAR(used, 0);
		res = 0;
		dfs(0, 0, 0, false);
		cout << res << endl;
	}
}

Measured memory_bytes: 932