// Original C++ solution (slower):
#include <iostream>

#include <algorithm>

#include <map>

#include <queue>

#include <set>

#include <stack>

#include <string>

#include <vector>

#include <queue>

#include <cmath>



// output

#define SPBR(w, n) std::cout<<(w + 1 == n ? '\n' : ' ');

#define YES cout << "YES" << endl

#define Yes cout << "Yes" << endl

#define NO cout << "NO" << endl

#define No cout << "No" << endl

// utility

#define ALL(i) (i).begin(), (i).end()

#define FOR(i, a, n) for(int i=(a);i<(n);++i)

#define RFOR(i, a, n) for(int i=(n)-1;i>=(a);--i)

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

#define RREP(i, n) for(int i=int(n)-1;i>=0;--i)

#define IN(a, x, b) (a<=x && x<b)

#define OUT(a, x, b) (x<a || b<=x)

template<class T> inline T chmax(T & a, const T b) { return a = (a < b) ? b : a; }

template<class T> inline T chmin(T& a, const T b) { return a = (a > b) ? b : a; }



// type/const

#define int ll

using ll = long long;

using ull = unsigned long long;

using ld = long double;

const int MOD = 1000000007;

const int INF = 1e18;



using namespace std;





signed main() {

  int N;

  string s;

  cin >> N >> s;



  int ans = 0;

  REP(i, 1000){

    int cnt = 0;

    string num = to_string(i);

    while(num.size() < 3) num = '0'+num;

    REP(j, s.size()){

      if(s[j] == num[cnt]){

        cnt++;

        if(cnt == 3){

          ans++;

          break;

        }

      }

    }

  }



  cout << ans << endl;



  return 0;

}

// Optimized solution to the same problem (faster):
#include <iostream>

#include <algorithm>

#include <map>

#include <queue>

#include <set>

#include <stack>

#include <string>

#include <string.h>

#include <vector>

#include <queue>

#include <cmath>

#include <bitset>

#include <complex>

#include <functional>

#include <numeric>

#include <iomanip>



// output

#define SPBR(w, n) std::cout<<(w + 1 == n ? '\n' : ' ');

#define YES cout << "YES" << endl

#define Yes cout << "Yes" << endl

#define NO cout << "NO" << endl

#define No cout << "No" << endl

// utility

#define ALL(i) (i).begin(), (i).end()

#define FOR(i, a, n) for(int i=(a);i<(n);++i)

#define RFOR(i, a, n) for(int i=(n)-1;i>=(a);--i)

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

#define RREP(i, n) for(int i=int(n)-1;i>=0;--i)

#define IN(a, x, b) (a<=x && x<b)

#define OUT(a, x, b) (x<a || b<=x)

template<class T> inline T chmax(T & a, const T b) { return a = (a < b) ? b : a; }

template<class T> inline T chmin(T& a, const T b) { return a = (a > b) ? b : a; }



// type/const

#define int ll

using ll = long long;

using ull = unsigned long long;

using ld = long double;

const int MOD = 1000000007;

/* const int MOD = 998244353; */

const int INF = 1e18;

const double PI = acos(-1);



using namespace std;

struct INIT { 

  INIT(){cin.tie(0); ios::sync_with_stdio(false);

  cout << fixed << setprecision(10);

}}INIT;



int N; 

int ans = 0;

vector<set<int>> vec(10);

void dfs(int n, int depth){

  if(depth == 3){

    ans++;

    return;

  }

  REP(i, 10){

    int it = *vec[i].upper_bound(n);

    if(it == INF) continue;

    dfs(it, depth+1);

  }

}





signed main() {

  cin >> N;



  string s;

  cin >> s;



  REP(i, N){

    vec[s[i]-'0'].insert(i);

  }

  REP(i, 10) vec[i].insert(INF);





  dfs(-1, 0);

  cout << ans << "\n";



  return 0;

}

// Fastest known solution for this problem: