#include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <iostream>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;

ll table_5[120][5],index_10,leftTable[120],rightTable[120],m_data[10] = {0,1,2,3,4,5,6,7,8,9},divide[11] = {0,362880,40320,5040,720,120,24,6,2,1,1};
ll* table_10;
ll map[11];
int N,loc[128];
bool isHead[11];

void calc10(){

	int select_num = 5,num,loc_left[5],loc_right[5],left_index,right_index,index,calc[5],value;

	index_10 = 0;

	for(int i = 0; i < 1024;i++){
		num = 0;
		for(int k = 0; k < 10; k++){
			if(i & (1 << k))num++;
		}
		if(num != select_num)continue;

		left_index = right_index = 0;

		for(int k = 0; k < 10; k++){
			if(i & (1 << k)){
				loc_left[left_index++] = k;
			}else{
				loc_right[right_index++] = k;
			}
		}

		left_index = right_index = 0;

		calc[0] = m_data[loc_left[0]],calc[1] = m_data[loc_left[1]],calc[2] = m_data[loc_left[2]],calc[3] = m_data[loc_left[3]],calc[4] = m_data[loc_left[4]];

		for(index = 0;index < 120; index++){
			value = 0;
			for(int p = 0; p < 5;p++){
				value = 10*value + calc[table_5[index][p]];
			}
			leftTable[left_index++] = value;
		}

		calc[0] = m_data[loc_right[0]],calc[1] = m_data[loc_right[1]],calc[2] = m_data[loc_right[2]],calc[3] = m_data[loc_right[3]],calc[4] = m_data[loc_right[4]];

		for(index = 0;index < 120; index++){
			value = 0;
			for(int p = 0; p < 5;p++){
				value = 10*value + calc[table_5[index][p]];
			}
			rightTable[right_index++] = value;
		}

		for(int k = 0; k < 120; k++){
			for(int p = 0; p < 120; p++){
				table_10[index_10++] = 100000*leftTable[k] + rightTable[p];
			}
		}
	}
}

void func(){

	for(int i = 0; i < 128; i++)loc[i] = -1;
	for(int i = 0; i < 11; i++)isHead[i] = false;

	char eq[N][9];

	int ans = 0,map_index = 0;

	for(int i = 0; i < N; i++){
		scanf("%s",eq[i]);
		for(int k = 0; eq[i][k] != '\0'; k++){
			if(loc[eq[i][k]-'0'] == -1){
				loc[eq[i][k]-'0'] = map_index++;
			}
		}
		if(eq[i][1] != '\0'){
			isHead[loc[eq[i][0]-'0']] = true;
		}
	}

	ll tmp;
	int work_num;
	bool FLG;

	for(int i = 0; i < 3628800; i++){

		tmp = table_10[i];

		for(int k = 0; k < 10; k++){
			map[k] = tmp%10;
			tmp /= 10;
		}
		FLG = true;
		for(int k = 0; k < map_index; k++){
			if(isHead[k] == true && map[k] == 0){
				FLG = false;
				break;
			}
		}
		if(!FLG)continue;

		int left = 0,right = 0;
		for(int a = 0; a < N-1; a++){
			work_num = 0;
			for(int b = 0; eq[a][b] != '\0';b++){
				work_num = 10*work_num + map[loc[eq[a][b]-'0']];
			}
			left += work_num;
		}

		for(int b = 0; eq[N-1][b] != '\0';b++){
			right = 10*right + map[loc[eq[N-1][b]-'0']];
		}

		if(left == right)ans++;
	}

	ans /= divide[map_index];

	printf("%d\n",ans);
}


int main(){

	table_10 = new ll[3628800];

	int index_5 = 0;

	for(int a = 0; a < 5; a++){
		for(int b = 0; b < 5; b++){
			for(int c = 0; c < 5; c++){
				for(int d = 0; d < 5; d++){
					for(int e = 0; e < 5; e++){
						if(a != b && a != c && a != d && a != e && b != c && b != d && b != e && c != d && c != e && d != e){
							table_5[index_5][0] = a,table_5[index_5][1] = b,table_5[index_5][2] = c,table_5[index_5][3] = d,table_5[index_5][4] = e;
							index_5++;
						}
					}
				}
			}
		}
	}

	calc10();

	while(true){
		scanf("%d",&N);
		if(N == 0)break;

		func();
	}

	return 0;
}

Measured memory_bytes: 31548