//include
//------------------------------------------
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <ctime>
#include <climits>
#include <queue>

using namespace std;

//typedef
//------------------------------------------
typedef vector<int> VI;
typedef vector<VI> VVI;
typedef vector<string> VS;
typedef pair<int, int> PII;
typedef long long LL;

//container util
//------------------------------------------
#define ALL(a)  (a).begin(),(a).end()
#define RALL(a) (a).rbegin(), (a).rend()
#define PB push_back
#define MP make_pair
#define SZ(a) int((a).size())
#define EACH(i,c) for(typeof((c).begin()) i=(c).begin(); i!=(c).end(); ++i)
#define EXIST(s,e) ((s).find(e)!=(s).end())
#define SORT(c) sort((c).begin(),(c).end())

//repetition
//------------------------------------------
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,n)  FOR(i,0,n)

//constant
//--------------------------------------------
const double EPS = 1e-10;
const double PI  = acos(-1.0);

int N, kind, len;
int pw[9];
VI ng;
VI add;
int dfs(int idx, queue<int>& q, int diff){
  if(idx == kind){
	if(diff == 0) return 1;
	return 0;
  }
  if(idx >= len && diff > 0){
	return 0;
  }
  
  int ret = 0;
  vector<bool> used(10, false);
  while(!used[q.front()]){
	int i = q.front(); q.pop();
	used[i] = true;
	if(i == 0 && ng[idx]){
	  q.push(i);
	  continue;
	}
	
	ret += dfs(idx+1, q, diff + i * add[idx]);
	q.push(i);
  }
  return ret;
}

vector<bool> used;
int f(int idx, int rest){
  if(rest == 0){
	VI vi;
	int res = 0;
	REP(i,10) if(used[i]) vi.PB(i);

	do{
	  int diff = 0;
	  REP(i,kind){
		if(vi[i] == 0 && ng[i]){
		  diff = -1; break;
		}
		diff += vi[i] * add[i];
	  }
	  if(diff == 0) ++res;
	}while(next_permutation(ALL(vi)));

	return res;
  }
  if(idx == 10) return 0;
  used[idx] = true;
  int res = f(idx+1, rest-1);
  used[idx] = false;
  res += f(idx+1, rest);

  return res;
}

int main(){
  cin.tie(0);
  ios_base::sync_with_stdio(false);

  pw[0] = 1;
  FOR(i,1,9)
	pw[i] = pw[i-1] * 10;

  while(cin>>N, N){
	vector<string> vs(N);
	VI sz(N);
	set<char> left, right;
	REP(i,N-1){
	  cin >> vs[i];
	  sz[i] = SZ(vs[i]);
	}
	cin >> vs[N-1];
	sz[N-1] = SZ(vs[N-1]);
	
	REP(i,SZ(vs[N-1])) right.insert(vs[N-1][i]);
	REP(i,N-1) REP(j,SZ(vs[i]))
	  if(right.find(vs[i][j]) == right.end())
		left.insert(vs[i][j]);

	string uniq = "";
	for(char ch:right)
	  uniq += string(1, ch);
	for(char ch:left)
	  uniq += string(1, ch);
	kind = SZ(uniq);
	len = SZ(right);

	ng.assign(kind, 0);
	REP(i,N)
	  if(SZ(vs[i]) > 1){
		REP(j,SZ(uniq))
		  if(vs[i][0] == uniq[j])
			ng[j] = 1;
	  }

	add.assign(kind, 0);
	REP(i,kind) REP(j,N) REP(k,SZ(vs[j]))
	  if(vs[j][k] == uniq[i]){
		if(j<N-1)
		  add[i] += pw[sz[j]-k-1];
		else
		  add[i] -= pw[sz[j]-k-1];
	  }

	queue<int> q;
	REP(i,10) q.push(i);
	int ans = dfs(0, q, 0);
	cout << ans << endl;
  }
  
  return 0;
}

Measured memory_bytes: 1228