Problem:
Score: 400 points

Problem Statement

AtCoder Inc. has decided to lock the door of its office with a 3-digit PIN code.

The company has an N-digit lucky number, S. Takahashi, the president, will erase N-3 digits from S and concatenate the remaining 3 digits without changing the order to set the PIN code.

How many different PIN codes can he set this way?

Both the lucky number and the PIN code may begin with a 0.

Constraints

4 \leq N \leq 30000

S is a string of length N consisting of digits.

Input

Input is given from Standard Input in the following format:

N
S

Output

Print the number of different PIN codes Takahashi can set.

Sample Input 1

4
0224

Sample Output 1

3

Takahashi has the following options:

Erase the first digit of S and set 224.

Erase the second digit of S and set 024.

Erase the third digit of S and set 024.

Erase the fourth digit of S and set 022.

Thus, he can set three different PIN codes: 022, 024, and 224.

Sample Input 2

6
123123

Sample Output 2

17

Sample Input 3

19
3141592653589793238

Sample Output 3

329

Solution in C++14 (GCC 5.4.1) (judge verdict: Accepted)

#include <bits/stdc++.h>
using namespace std;

#define MAX(a,b) ((a)>(b)?(a):(b))
#define MIN(a,b) ((a)<(b)?(a):(b))
#define ABS(a) ((a)>(0)?(a):-(a))
#define rep(i,a,b) for(int (i)=int(a);(i)<int(b);(i)++)
#define rrep(i,a,b) for(int (i)=int(a);(i)>=int(b);(i)--)

#define put(a) cout << (a) << endl
#define puts(a) cout << (a) << " "

#define llint long long int

#define INF (long long)(1e9+1)
#define MOD (long long)(1e9+7)
#define INF64 (long long)(1e18+1)

#define F first
#define S second

#define Pii  pair<int,int>
#define Pll  pair<long long,long long>
#define Piii pair<int,pair<int,int>>
#define Plll pair<long long,pair<long long,long long>>

#define Vll(a,b,c)    vector<vector<long long>> (a)((b),vector<long long>((c))
#define Vlll(a,b,c,d) vector<vector<vector<long long>>> (a)((b),vector<vector<long long>>((c),vector<long long>((d)))

#define MAX_N 1000000

llint my_binary_search(llint ary[], llint key, llint left, llint right) {
	llint middle;
	if (right < left) {
		return -(INF64);
	} else {
		middle = left + (right - left) / 2;
		if (ary[middle] > key) {
			return my_binary_search(ary, key, left, middle - 1);
		} else if (ary[middle] < key) {
			return my_binary_search(ary, key, middle + 1, right);
		} else {
			return middle;
		}
	}
}

struct UnionFind {
	vector<int> par; // par[i]:iの親の番号　(例) par[3] = 2 : 3の親が2
	
	UnionFind(int N) : par(N) { //最初は全てが根であるとして初期化
		for(int i = 0; i < N; i++) par[i] = i;
	}
	
	int root(int x) { // データxが属する木の根を再帰で得る：root(x) = {xの木の根}
		if (par[x] == x) return x;
		return par[x] = root(par[x]);
	}
	
	void unite(int x, int y) { // xとyの木を併合
		int rx = root(x); //xの根をrx
		int ry = root(y); //yの根をry
		if (rx == ry) return; //xとyの根が同じ(=同じ木にある)時はそのまま
		par[rx] = ry; //xとyの根が同じでない(=同じ木にない)時：xの根rxをyの根ryにつける
	}
	
	bool same(int x, int y) { // 2つのデータx, yが属する木が同じならtrueを返す
		int rx = root(x);
		int ry = root(y);
		return rx == ry;
	}
};

int main (void)
{
	//INPUT
	llint N;
	cin >> N;
	char S[N];
	cin >> S;
	
	
	//SOLVE
	llint ans = 0;
	llint buf;
	llint i,j,k,l;
	
	for(i = 0; i<=999; i++ ) {
		//100
		buf = i/100;
		for(j = 0; j<=N-3; j++ ) {
			if (buf == (llint)(S[j]-'0')) {
				break;
			}
		}
		if (j == N-2) {
			i+=99;
			continue;
		} 
		
		//10
		buf = (i % 100)/10;
		for(k = j+1 ; k<=N-2; k++) {
			if (buf == (llint)(S[k]-'0')) {
				break;
			}
		}
		if (k == N-1) {
			i+= 9;
			continue;
		}
		
		//1
		buf = i % 10;
		for(l = k+1 ; l<=N-1; l++) {
			if (buf == (llint)(S[l]-'0')) {
				ans++;
				break;
			}
		}
		
	}
	
	
	//OUTPUT
	cout << ans << endl;
	
	
	// llint ans=0;
	// 
	// set<llint> pass;
	// 
	// llint pasno;
	// 
	// for(llint i=0;i<
	// 
	// pasno = ((llint)(S[0] - '0') *100) + ((llint)(S[1] - '0') * 10) + (llint)(S[2] - '0');
	// 
	// if (pass.count(pasno) == 0) {
	// 
	// } else {
	// 	pass.emplace(pasno);
	// }
	// 
	// //OUTPUT
	// cout << pass.size() << endl;
	
	return 0;
}