#[allow(dead_code)]
fn main() {
    let kk= i::i();
    let ss= i::s();

    let mut count=0;
    let mut first_set = HashMap::new();
    let mut last_set = HashMap::new();
    for xx in 0..10 {
        let mut first:Option<i64> =None;
        let mut last:Option<i64> =None;
        for num in 0..(kk) {
            if (first.is_none() && ss[num as usize].to_string()==(xx.to_string())){
                first=Some(num);
            }
            if (ss[num as usize].to_string()==(xx.to_string())){
                last=Some(num);
            }
        }
        if first.is_some(){
            first_set.insert(xx,first.unwrap());
        }
        if last.is_some(){
            last_set.insert(xx,last.unwrap());
        }
    }
    for xx in 0..10 {
        for zz in 0..10 {
            for yy in 0..10 {
                //xx最初
                let xxpos = first_set.get(&xx);
                let zzpos = last_set.get(&zz);
                let yyminpos = first_set.get(&yy);
                let yymaxpos = last_set.get(&yy);
                if (xxpos.is_some() && zzpos.is_some() && yyminpos.is_some()){
                    if (*xxpos.unwrap()+1<*zzpos.unwrap()){
                        for yypos2 in (*xxpos.unwrap()+1)..(*zzpos.unwrap()) {
                            if (ss[yypos2 as usize].to_string() == yy.to_string()){
                                count=count+1;
                                break;
                            }
                        }
                    }
                }
            }
        }
    }
    println!("{}", count);
}

#[allow(unused_imports)]
use std::cmp::*;
#[allow(unused_imports)]
use std::collections::{HashMap, HashSet, VecDeque};
#[allow(unused_imports)]
use std::io::*;
#[allow(unused_imports)]
use std::num::*;
#[allow(unused_imports)]
use std::str::*;

#[allow(dead_code)]
mod i {
    use super::*;

    pub fn read<T: FromStr>() -> T {
        stdin()
            .bytes()
            .map(|c| c.unwrap() as char)
            .skip_while(|c| c.is_whitespace())
            .take_while(|c| !c.is_whitespace())
            .collect::<String>()
            .parse::<T>()
            .ok()
            .unwrap()
    }

    pub fn str() -> String {
        read()
    }

    pub fn s() -> Vec<char> {
        str().chars().collect()
    }

    pub fn i32() -> i32 {
        read()
    }

    pub fn i() -> i64 {
        read()
    }

    pub fn u() -> usize {
        read()
    }

    pub fn u2() -> (usize, usize) {
        (read(), read())
    }

    pub fn u3() -> (usize, usize, usize) {
        (read(), read(), read())
    }

    pub fn f() -> f64 {
        read()
    }

    pub fn c() -> char {
        read::<String>().pop().unwrap()
    }

    pub fn iv(n: usize) -> Vec<i64> {
        (0..n).map(|_| i()).collect()
    }

    pub fn iv2(n: usize) -> Vec<(i64, i64)> {
        (0..n).map(|_| iv(2)).map(|a| (a[0], a[1])).collect()
    }

    pub fn uv(n: usize) -> Vec<usize> {
        (0..n).map(|_| u()).collect()
    }

    pub fn uv2(n: usize) -> Vec<(usize, usize)> {
        (0..n).map(|_| uv(2)).map(|a| (a[0], a[1])).collect()
    }

    pub fn uv3(n: usize) -> Vec<(usize, usize, usize)> {
        (0..n).map(|_| uv(3)).map(|a| (a[0], a[1], a[2])).collect()
    }

    pub fn fv(n: usize) -> Vec<f64> {
        (0..n).map(|_| f()).collect()
    }

    pub fn cmap(h: usize) -> Vec<Vec<char>> {
        (0..h).map(|_| s()).collect()
    }
}

Measured memory_bytes: 4476