use std::char;
use std::fs::File;
use std::io::Read;

// fn pow_speedt_with_mod(mut p: i64, mut q: i64, m: i64) -> i64 {
//     p %= m;
//     let mut r = p;
//     let mut ret: i64 = 1;
//     while q > 0 {
//         ret *= if q % 2 == 1 {r} else {1};
//         r *= r;
//         r %= m;
//         q /= 2;
//         ret %= m;
//     }
//     return ret;
// }

fn main() {
    let inputstatus = 1;

    let mut buf = String::new();
    let filename = "inputrust.txt";

    if inputstatus == 0 {
        let mut f = File::open(filename).expect("file not found");
        f.read_to_string(&mut buf)
            .expect("something went wrong reading the file");
    } else {
        std::io::stdin().read_to_string(&mut buf).unwrap();
    }

    let mut iter = buf.split_whitespace();
    let n: usize = iter.next().unwrap().parse().unwrap();
    let mut v = Vec::<i32>::new();
    let mut v_commpress = Vec::<i32>::new();

    for _ in 0..n {
        v.push(iter.next().unwrap().parse().unwrap());
    }
    v.sort();

    for (i, vi) in v.iter().enumerate() {
        if i == 0 {
            v_commpress.push(*vi);
        } else if v[i - 1] != v[i] {
            v_commpress.push(*vi);
        }
    }

    // println!("{:?}", v_commpress);

    let ans = if v_commpress.len() <= 1 {
        0
    } else if v_commpress.len() == 2 && (v_commpress[1] - v_commpress[0]) % 2 == 0 {
        (v_commpress[1] - v_commpress[0]) / 2
    } else if v_commpress.len() == 2 && (v_commpress[1] - v_commpress[0]) % 2 == 1 {
        v_commpress[1] - v_commpress[0]
    } else if v_commpress.len() == 3 && (v_commpress[2] + v_commpress[0]) == 2 * v_commpress[1] {
        v_commpress[1] - v_commpress[0]
    } else {
        -1
    };
    println!("{}", ans);

    // if p + 1 >= m

    // println!("{}", n);
    // println!("{}", k);
    // println!("{:?}", num);
    // println!("{:?}", cum_num);
}


#![allow(dead_code, unused_imports, unused_macros)]

use std::fmt::Debug;
use std::str::FromStr;

fn read_stdin() -> String {
    let mut s = String::new();
    std::io::stdin()
        .read_line(&mut s)
        .expect("cannot read stdin");
    s.trim().to_string()
}

fn read<T>() -> T
where
    T: FromStr,
    <T as FromStr>::Err: Debug,
{
    read_stdin().parse::<T>().unwrap()
}

fn read_usize() -> usize {
    read::<usize>()
}

fn read_2<A, B>() -> (A, B)
where
    A: FromStr,
    <A as FromStr>::Err: Debug,
    B: FromStr,
    <B as FromStr>::Err: Debug,
{
    let s = read_stdin();
    let mut s = s.split_whitespace();
    let a = s.next().unwrap().parse::<A>().unwrap();
    let b = s.next().unwrap().parse::<B>().unwrap();
    (a, b)
}

fn read_3<A, B, C>() -> (A, B, C)
where
    A: FromStr,
    <A as FromStr>::Err: Debug,
    B: FromStr,
    <B as FromStr>::Err: Debug,
    C: FromStr,
    <C as FromStr>::Err: Debug,
{
    let s = read_stdin();
    let mut s = s.split_whitespace();
    let a = s.next().unwrap().parse::<A>().unwrap();
    let b = s.next().unwrap().parse::<B>().unwrap();
    let c = s.next().unwrap().parse::<C>().unwrap();
    (a, b, c)
}

fn read_4<A, B, C, D>() -> (A, B, C, D)
where
    A: FromStr,
    <A as FromStr>::Err: Debug,
    B: FromStr,
    <B as FromStr>::Err: Debug,
    C: FromStr,
    <C as FromStr>::Err: Debug,
    D: FromStr,
    <D as FromStr>::Err: Debug,
{
    let s = read_stdin();
    let mut s = s.split_whitespace();
    let a = s.next().unwrap().parse::<A>().unwrap();
    let b = s.next().unwrap().parse::<B>().unwrap();
    let c = s.next().unwrap().parse::<C>().unwrap();
    let d = s.next().unwrap().parse::<D>().unwrap();
    (a, b, c, d)
}

fn read_multiple<T: FromStr>() -> Vec<T>
where
    <T as FromStr>::Err: Debug,
{
    read_stdin()
        .split_whitespace()
        .map(|x| x.parse::<T>().expect("cannot parse stdin"))
        .collect()
}

/// NOTE: sort iter beforehand if required
fn count<T>(iter: &mut impl Iterator<Item = T>) -> Vec<(T, usize)>
where
    T: std::cmp::Ord,
{
    let iter = iter.collect::<Vec<_>>();
    //iter.sort();
    let (mut v, o, c) =
        iter.into_iter()
            .fold((Vec::new(), None, 0), |(mut v, last, count), item| {
                if let Some(o) = last {
                    if item == o {
                        (v, Some(o), count + 1)
                    } else {
                        v.push((o, count));
                        (v, Some(item), 1)
                    }
                } else {
                    (v, Some(item), 1)
                }
            });
    if let Some(i) = o {
        v.push((i, c));
    }
    v
}

fn partial_sum<T>(v: impl Iterator<Item = T>) -> impl Iterator<Item = T>
where
    T: Default + std::ops::Add<Output = T> + Copy,
{
    v.scan(T::default(), |state, x| {
        *state = *state + x;
        Some(*state)
    })
}

fn partial_max<T>(v: impl Iterator<Item = T>) -> impl Iterator<Item = T>
where
    T: Default + Ord + Copy,
{
    v.scan(T::default(), |state, x| {
        *state = max(*state, x);
        Some(*state)
    })
}

fn partial_min(v: impl Iterator<Item = u64>) -> impl Iterator<Item = u64> {
    v.scan(std::u64::MAX, |state, x| {
        *state = min(*state, x);
        Some(*state)
    })
}

fn max_subarray(v: impl Iterator<Item = i64>) -> (i64, (usize, usize)) {
    //assert!(v.len() > 0);
    let mut best_sum = 0;
    let (mut best_start, mut best_end) = (0, 0);
    let mut current_sum = 0;
    let mut current_start = 0;
    for (end, val) in v.enumerate() {
        if current_sum <= 0 {
            current_start = end;
            current_sum = val;
        } else {
            current_sum += val;
        }
        if current_sum > best_sum {
            best_sum = current_sum;
            best_start = current_start;
            best_end = end + 1;
        }
    }
    (best_sum, (best_start, best_end))
}

fn gcd(mut a: u64, mut b: u64) -> u64 {
    while a != 0 {
        let old_m = a;
        a = b % a;
        b = old_m;
    }
    b
}

/// returns gcd, and pair (x, y), such that x * a + b * y == gcd
fn egcd(a: i64, b: i64) -> (i64, i64, i64) {
    if a == 0 {
        (b, 0, 1)
    } else {
        let (g, x, y) = egcd(b % a, a);
        (g, y - (b / a) * x, x)
    }
}

fn factorize(mut n: u64) -> Vec<u64> {
    if n <= 3 {
        return vec![n];
    }
    let mut v = Vec::new();
    while n % 2 == 0 {
        n /= 2;
        v.push(2);
    }
    while n % 3 == 0 {
        n /= 3;
        v.push(3);
    }
    let mut f = 6;
    while (f - 1) * (f - 1) <= n {
        while n % (f - 1) == 0 {
            n /= f - 1;
            v.push(f - 1);
        }
        while n % (f + 1) == 0 {
            n /= f + 1;
            v.push(f + 1);
        }
        f += 6;
    }
    if n > 1 {
        v.push(n);
    }
    v
}

fn compact_factors(n: u64) -> Vec<(u64, usize)> {
    count(&mut factorize(n).into_iter())
}

fn all_factors(n: u64) -> Vec<u64> {
    if n == 0 {
        return vec![0];
    } else if n == 1 {
        return vec![1];
    }
    let factors = compact_factors(n);
    let mut v = vec![1];
    for (fac, num) in factors {
        let ori = v.clone();
        for i in 1..num + 1 {
            v.append(
                &mut ori
                    .clone()
                    .into_iter()
                    .map(|f| f * fac.pow(i as u32))
                    .collect::<Vec<_>>(),
            )
        }
    }
    v.sort();
    v
}

fn abs_diff<T>(a: T, b: T) -> T
where
    T: PartialOrd + std::ops::Sub<Output = T>,
{
    if a > b {
        a - b
    } else {
        b - a
    }
}

struct Permutations<T> {
    inner: Vec<T>,
    state: Vec<usize>,
    i: usize,
    start: bool,
}

impl<T> Permutations<T> {
    fn new(inner: Vec<T>) -> Self {
        Self {
            state: vec![0; inner.len()],
            i: 0,
            start: true,
            inner,
        }
    }
}

/*impl<T, X> From<X> for Permutations<T>
where
    X: IntoIterator<Item = T>,
{
    fn from(f: X) -> Self {
        Self::new(f.into_iter().collect::<Vec<T>>())
    }
}*/

impl<T> Iterator for Permutations<T>
where
    T: Clone,
{
    type Item = Vec<T>;
    fn next(&mut self) -> Option<Self::Item> {
        if self.start {
            self.start = false;
            return Some(self.inner.clone());
        }
        while self.i < self.inner.len() {
            if self.state[self.i] < self.i {
                if self.i % 2 == 0 {
                    self.inner.swap(0, self.i)
                } else {
                    self.inner.swap(self.state[self.i], self.i)
                }
                self.state[self.i] += 1;
                self.i = 0;
                return Some(self.inner.clone());
            } else {
                self.state[self.i] = 0;
                self.i += 1;
            }
        }
        None
    }
}

use std::cmp::{max, min, Ord, Ordering};
use std::collections::{BinaryHeap, VecDeque};
use std::mem::swap;

macro_rules! max_with {
    ($x: expr, $y: expr) => {
        $x = max($x, $y)
    };
}

macro_rules! min_with {
    ($x: expr, $y: expr) => {
        $x = max($x, $y)
    };
}

fn is_prime(n: u64) -> bool {
    factorize(n).len() == 1
}

fn combination(n: u64, k: u64, m: u64) -> u64 {
    if n == 0 {
        return 1;
    }
    if k == 0 || k == n {
        return 1;
    }
    let new_k = if n - k < k { n - k } else { k };
    let mut res = 1;
    for i in ((n - new_k) + 1)..=n {
        res *= i;
        res %= m;
    }
    let mut den = 1;
    for i in 1..=(new_k) {
        den *= i;
        den %= m;
    }
    let (_one, inverse, _c) = egcd(den as i64, m as i64);
    let inverse = if inverse < 0 {
        m as i64 + inverse
    } else {
        inverse
    } as u64;
    //println!("inv: {} {}", den, inverse);
    res *= inverse;
    res %= m;
    res
}

use std::collections::HashSet;
use std::iter::FromIterator;

fn n_to_vec(n: u64, l: usize) -> Vec<u8> {
    let mut res = vec![0; l];
    let mut n = n;
    for i in (0..l).rev() {
        if n % 2 == 1 {
            res[i] = 1;
        }
        n /= 2;
    }
    res
}

fn vec_to_n(v: Vec<u8>) -> u64 {
    let mut res = 0;
    for i in 0..v.len() {
        res *= 2;
        if v[i] == 1 {
            res += 1;
        }
    }
    res
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let _n = read_usize();
    let a_vec = read_multiple::<u32>();
    let mut v = Vec::new();
    let mut flag = false;
    'f: for a in a_vec {
        if !v.contains(&a) {
            v.push(a)
        }
        if v.len() > 3 {
            flag = true;
            break 'f;
        }
    }
    if flag {
        println!("-1")
    } else {
        v.sort_unstable();
        if v.len() == 1 {
            println!("0")
        } else if v.len() == 2 {
            if (v[1] - v[0]) % 2 == 0 {
                println!("{}", (v[1] - v[0]) / 2)
            } else {
                println!("{}", v[1] - v[0])
            }
        } else {
            //v.len() == 3
            if v[2] - v[1] != v[1] - v[0] {
                println!("-1")
            } else {
                println!("{}", v[2] - v[1])
            }
        }
    }
    Ok(())
}


#![allow(unused_imports)]
#![allow(unused_macros)]
#![allow(dead_code)]
#![allow(unused_labels)]

use std::char::*;
use std::cmp::*;
use std::collections::*;
use std::io::*;
use std::str::FromStr;

macro_rules! debug {($($a:expr),*) => {println!(concat!($(stringify!($a), " = {:?}, "),*), $($a),*);}}
macro_rules! input { ( source = $ s : expr , $ ( $ r : tt ) * ) => { let mut iter = $ s . split_whitespace ( ) ; let mut next = || { iter . next ( ) . unwrap ( ) } ; input_inner ! { next , $ ( $ r ) * } } ; ( $ ( $ r : tt ) * ) => { let stdin = std :: io :: stdin ( ) ; let mut bytes = std :: io :: Read :: bytes ( std :: io :: BufReader :: new ( stdin . lock ( ) ) ) ; let mut next = move || -> String { bytes . by_ref ( ) . map ( | r | r . unwrap ( ) as char ) . skip_while ( | c | c . is_whitespace ( ) ) . take_while ( | c |! c . is_whitespace ( ) ) . collect ( ) } ; input_inner ! { next , $ ( $ r ) * } } ; }
macro_rules! input_inner { ( $ next : expr ) => { } ; ( $ next : expr , ) => { } ; ( $ next : expr , $ var : ident : $ t : tt $ ( $ r : tt ) * ) => { let $ var = read_value ! ( $ next , $ t ) ; input_inner ! { $ next $ ( $ r ) * } } ; }
macro_rules! read_value { ( $ next : expr , ( $ ( $ t : tt ) ,* ) ) => { ( $ ( read_value ! ( $ next , $ t ) ) ,* ) } ; ( $ next : expr , [ $ t : tt ; $ len : expr ] ) => { ( 0 ..$ len ) . map ( | _ | read_value ! ( $ next , $ t ) ) . collect ::< Vec < _ >> ( ) } ; ( $ next : expr , chars ) => { read_value ! ( $ next , String ) . chars ( ) . collect ::< Vec < char >> ( ) } ; ( $ next : expr , usize1 ) => { read_value ! ( $ next , usize ) - 1 } ; ( $ next : expr , $ t : ty ) => { $ next ( ) . parse ::<$ t > ( ) . expect ( "Parse error" ) } ; }

fn read<T: FromStr>() -> T {
    let stdin = stdin();
    let stdin = stdin.lock();
    let token: String = stdin
        .bytes()
        .map(|c| c.expect("failed to read char") as char)
        .skip_while(|c| c.is_whitespace())
        .take_while(|c| !c.is_whitespace())
        .collect();
    token.parse().ok().expect("failed to parse token")
}

use std::f64;

fn min<T: PartialOrd>(a:T, b:T) -> T {
    if a < b { a }
    else { b }
}

fn max<T: PartialOrd>(a:T, b:T) -> T {
    if a < b { b }
    else { a }
}

const MAX:usize = 30;
const INF:i64 = std::i64::MAX;
const MOD:i64 = 1e9 as i64 + 7;

fn main() {
    //let t:usize = read();

    //'outer: for _ in 0..t {
        let n:usize = read();
        let a:Vec<i64> = (0..n).map(|_| read()).collect();

        let mut ans = 10000;
        for e in -1000..1000 {
            let mut d = 0;
            for i in 0..n {
                if (a[i]-e).abs() != 0 { d = (a[i]-e).abs(); break; }
            }
            let mut f = true;
            for i in 0..n {
                if (a[i]-e).abs() == 0 { continue; }
                if d != (a[i]-e).abs() {
                    f = false;
                }
            }
            if f {
                ans = min(ans, d);
            }
        }
        println!("{}", if ans==10000 {-1} else {ans});
    //}
}

/*

*/


//https://qiita.com/tanakh/items/0ba42c7ca36cd29d0ac8 より
macro_rules! input {
    (source = $s:expr, $($r:tt)*) => {
        let mut iter = $s.split_whitespace();
        input_inner!{iter, $($r)*}
    };
    ($($r:tt)*) => {
        let s = {
            use std::io::Read;
            let mut s = String::new();
            std::io::stdin().read_to_string(&mut s).unwrap();
            s
        };
        let mut iter = s.split_whitespace();
        input_inner!{iter, $($r)*}
    };
}

macro_rules! input_inner {
    ($iter:expr) => {};
    ($iter:expr, ) => {};
    ($iter:expr, $var:ident : $t:tt $($r:tt)*) => {
        let $var = read_value!($iter, $t);
        input_inner!{$iter $($r)*}
    };
}

macro_rules! read_value {
    ($iter:expr, ( $($t:tt),* )) => {
        ( $(read_value!($iter, $t)),* )
    };
    ($iter:expr, [ $t:tt ; $len:expr ]) => {
        (0..$len).map(|_| read_value!($iter, $t)).collect::<Vec<_>>()
    };
    ($iter:expr, chars) => {
        read_value!($iter, String).chars().collect::<Vec<char>>()
    };
    ($iter:expr, usize1) => {
        read_value!($iter, usize) - 1
    };
    ($iter:expr, $t:ty) => {
        $iter.next().unwrap().parse::<$t>().expect("Parse error")
    };
}

// ここまで

fn run() {
    input! {
        n: usize,
        a: [u32; n],
    }
    let mut n = n;
    let mut a = a;
    let mut ans = 0;
    while n > 0 {
        a.sort();
        let v = a[0];
        let mut b = vec![];
        for i in 1..n {
            if a[i] % v != 0 {
                b.push(a[i]);
            }
        }
        a = b;
        n = a.len();
        ans += 1;
    }
    println!("{}", ans);
}

fn main() {
    run();
}


// ######### contest shortcuts
#![allow(unused_imports, dead_code, unused_variables)]
use std::io::{stdin, stdout, BufWriter, BufReader, Read, Write};
use std::cmp;

#[derive(Default)]
struct Scanner (Vec<String>,);

impl Scanner {
    fn next<T: std::str::FromStr>(&mut self) -> T {
        loop {
            if let Some(token) = self.0.pop() {
                return token.parse().ok().expect("Failed parse");
            }
            let mut input = String::new();
            stdin().read_line(&mut input).expect("Failed read");
            self.0 = input.split_whitespace().rev()
                .map(String::from).collect();
        }
    }
}
// ## END ## contest shortcuts

fn main() {
    let mut scan = Scanner::default();
    let out = &mut BufWriter::new(stdout());

    let n = scan.next::<usize>();
    // let mut a = scan.next::<String>();
    let a: Vec<u32> = (0..n)
        .map(|_| scan.next::<u32>())
        .collect();
    let mut s_a: Vec<_> = a.iter()
        .map(|e| e.clone())
        .enumerate()
        .collect();
    s_a.sort_by_key(|&(_, e)| e);
   // println!("{:?}", s_a);
    let mut marks = vec![false; n];
    let mut colors = 0usize;
    for &(j, e) in s_a.iter() {
        if marks[j] { continue; }
        colors += 1;

        for (i, ae) in a.iter().enumerate(){
            if marks[i] == false && ae % e == 0 {
                marks[i] = true;
                // println!("{:?}", e);
            }
        }
    }
    write!(out, "{}", colors).ok();
}


use std::collections::{BTreeSet, VecDeque};
use std::io::Write;

#[cfg(feature = "badcw")]
pub use notes::one_line::*;

// ---------- begin scannner ----------
#[allow(dead_code, unused_imports)]
mod scanner {
    use std::str::FromStr;
    pub struct Scanner<'a> {
        it: std::str::SplitWhitespace<'a>,
    }
    impl<'a> Scanner<'a> {
        pub fn new(s: &'a String) -> Scanner<'a> {
            Scanner {
                it: s.split_whitespace(),
            }
        }
        pub fn next<T: FromStr>(&mut self) -> T {
            self.it.next().unwrap().parse::<T>().ok().unwrap()
        }
        pub fn next_bytes(&mut self) -> Vec<u8> {
            self.it.next().unwrap().bytes().collect()
        }
        pub fn next_chars(&mut self) -> Vec<char> {
            self.it.next().unwrap().chars().collect()
        }
        pub fn next_vec<T: FromStr>(&mut self, len: usize) -> Vec<T> {
            (0..len).map(|_| self.next()).collect()
        }
        pub fn size(&self) -> usize {
            self.it.clone().count()
        }
    }
}
// ---------- end scannner ----------

fn main() {
    use std::io::Read;
    let mut s = String::new();
    std::io::stdin().read_to_string(&mut s).unwrap();
    let mut sc = scanner::Scanner::new(&s);
    let out = std::io::stdout();
    let mut out = std::io::BufWriter::new(out.lock());
    run(&mut sc, &mut out);
}

fn run<W: Write>(sc: &mut scanner::Scanner, out: &mut std::io::BufWriter<W>) {
    let T = sc.size()/2;
    for kase in 0..T {
        let n: usize = sc.next();
        let x: usize = sc.next();
        let mut qu = VecDeque::new();
        let mut st = BTreeSet::new();
        qu.push_back((x, 0));
        st.insert(x);
        let mut f = false;
        while let Some((u, dp)) = qu.pop_front() {
            if u.to_string().len() > n {
                break;
            }
            if u.to_string().len() == n {
                f = true;
                writeln!(out, "{}", dp);
                break;
            }
            for c in u.to_string().as_bytes() {
                if c < &b'2' {
                    continue;
                }
                let v = u * ((c - b'0') as usize);
                if st.insert(v) {
                    qu.push_back((v, dp + 1));
                }
            }
        }
        if !f {
            writeln!(out, "-1");
        }
    }
}


#![allow(dead_code, unused)]

mod io {
    use std::str::{FromStr, SplitWhitespace};

    pub fn read_from_stdin() -> String {
        use std::io::Read;
        let mut input = String::new();

        std::io::stdin()
            .read_to_string(&mut input)
            .expect("Error reading from stdin");
        input
            .trim()
            .to_string()
    }

    pub struct Input<'a> {
        values: SplitWhitespace<'a>
    }

    impl <'a> Input<'a> {
        pub fn from(input: &'a str) -> Self {
            Self { values: input.split_whitespace() }
        }

        pub fn next<T>(&mut self) -> T where T: FromStr {
            self
                .values
                .next()
                .unwrap()
                .parse::<T>()
                .ok()
                .unwrap()
        }

        pub fn vec<T>(&mut self, n: usize) -> Vec<T> where T: FromStr {
            (0..n)
                .map(|_| self.next())
                .collect()
        }
    }
}

use std::collections::{HashMap, HashSet, VecDeque};
use std::io::{BufWriter, StdoutLock, Write};

fn main() {
    let stdin = io::read_from_stdin();
    let stdout = std::io::stdout();
    let mut input = io::Input::from(&stdin);
    let mut output = BufWriter::new(stdout.lock());
    //let k: usize = input.next();

    //for _ in 0..k { solve(&mut input, &mut output) }
    solve(&mut input, &mut output);
}

const MAX: i64 = 1e9 as i64 + 10;

fn solve(input: &mut io::Input, output: &mut BufWriter<StdoutLock>) {
    let n: usize = input.next();
    let x: i64 = input.next();
    let mut map = HashMap::<i64, i64>::new();
    let mut ans = dfs(n, x, &mut map);
    ans = if ans == MAX { -1 } else { ans };

    writeln!(output, "{ans}");
}

fn dfs(n: usize, x: i64, map: &mut HashMap<i64, i64>) -> i64 {
    let s = x.to_string();
    let ss: HashSet<char> = s.chars().collect();
    let mut min = MAX;
    if s.len() > n { return MAX }
    if s.len() == n { return 0 }
    if let Some(&result) = map.get(&x) { return result }

    for c in ss {
        let i = c as u8 - '0' as u8;
        if i > 1 {
            let p = x * i as i64 ;
            min = min.min(1 + dfs(n, p, map));
        }
    }
    *map.entry(x).or_insert(0) = min;
    min
}


use std::io::{self, BufWriter, Write};

mod scanner {
    use std::{io, str};
    /* https://github.com/EbTech/rust-algorithms */

    /// Same API as Scanner but nearly twice as fast, using horribly unsafe dark arts
    /// **REQUIRES** Rust 1.34 or higher
    pub struct UnsafeScanner<R> {
        reader: R,
        buf_str: Vec<u8>,
        buf_iter: str::SplitAsciiWhitespace<'static>,
    }

    impl<R: io::BufRead> UnsafeScanner<R> {
        pub fn new(reader: R) -> Self {
            Self {
                reader,
                buf_str: Vec::new(),
                buf_iter: "".split_ascii_whitespace(),
            }
        }

        /// This function should be marked unsafe, but noone has time for that in a
        /// programming contest. Use at your own risk!
        pub fn token<T: str::FromStr>(&mut self) -> T {
            loop {
                if let Some(token) = self.buf_iter.next() {
                    return token.parse().ok().expect("Failed parse");
                }
                self.buf_str.clear();
                self.reader
                    .read_until(b'\n', &mut self.buf_str)
                    .expect("Failed read");
                self.buf_iter = unsafe {
                    let slice = str::from_utf8_unchecked(&self.buf_str);
                    std::mem::transmute(slice.split_ascii_whitespace())
                }
            }
        }
    }
}

use std::cmp::{min, max};

fn s2vec(s: String) -> Vec<char> {
    s.chars().collect()
}

fn main() {
    let (stdin, stdout) = (io::stdin(), io::stdout());
    let (mut scan, mut sout) = (
        scanner::UnsafeScanner::new(stdin.lock()),
        BufWriter::new(stdout.lock()),
    );
    use std::collections::{HashSet, VecDeque};
    let n: usize = scan.token();
    let x: i64 = scan.token();
    let mut s: HashSet<i64> = HashSet::new();
    let mut ret = std::i32::MAX;
    let mut q = VecDeque::new();
    s.insert(x);
    q.push_back((x, 0));
    while let Some((x, c)) = q.pop_front() {
        let mut x_t = x;
        let mut k = 0;
        while x_t > 0 {
            k += 1;
            x_t /= 10;
        }
        if n == k {
            ret = min(ret, c);
        } else {
            x_t = x;
            while x_t > 0 {
            if (x_t % 10) > 1 {
                let y = x * (x_t % 10);
                if !s.contains(&y) {
                    s.insert(y);
                    q.push_back((y, c+1));
                }
            }
            x_t /= 10;
            }
        }
    }
    if ret == std::i32::MAX {
        writeln!(sout, "-1").ok();
    } else {
        writeln!(sout, "{}", ret).ok();
    }
}


#![allow(non_snake_case)]
#![allow(unused_imports)]

#[macro_use]
mod singleton {
    #[macro_export]
    macro_rules! singleton {
        ($type:ty, $e:expr) => {
            static mut INSTANCE: *mut $type = 0 as _;
            static mut INIT: bool = false;

            pub fn instance() -> &'static mut $type {
                unsafe {
                    if !INIT {
                        INSTANCE = Box::into_raw(Box::new($e));
                        INIT = true;
                    }
                    INSTANCE.as_mut().unwrap()
                }
            }
        };
    }

    #[macro_export]
    macro_rules! defglobal {
        ($type:ty, $set:ident, $get:ident) => {
            mod $get {
                pub(crate) static mut INSTANCE: *mut $type = 0 as _;
            }

            pub fn $set(value: $type) {
                unsafe {
                    $get::INSTANCE = Box::into_raw(Box::new(value));
                }
            }

            pub fn $get() -> &'static mut $type {
                unsafe { $get::INSTANCE.as_mut().unwrap() }
            }
        };
    }

}
pub use singleton::*;

#[macro_use]
mod scanner {

    use std::io::BufRead;
    use std::io::BufReader;

    pub struct Scanner {
        reader: Box<dyn BufRead>,
        buffer: Vec<String>,
    }

    impl Default for Scanner {
        fn default() -> Self {
            let mut reader_opt: Option<Box<dyn BufRead>> = None;
            for arg in std::env::args().skip(1) {
                if let Ok(fd) = std::fs::File::open(arg) {
                    reader_opt = Some(Box::new(BufReader::new(fd)));
                    break;
                }
            }
            let reader = reader_opt.unwrap_or_else(|| Box::new(BufReader::new(std::io::stdin())));
            Scanner {
                reader,
                buffer: vec![],
            }
        }
    }

    singleton!(Scanner, Scanner::default());

    // global scanner
    #[macro_export]
    macro_rules! scanner_impl {
        ( $name2:ident, $name:ident
            $(< $( $lt:tt : $clt:tt ),+ >)?
            ( $scanner:ident ) -> $ret_type:ty
            $body:block
        )
             =>
        {
            fn $name2 $(< $( $lt : $clt ),+ >)? ($scanner: &mut Scanner) -> $ret_type
                $body

            pub fn $name $(< $( $lt : $clt ),+ >)? () -> $ret_type {
                $name2(crate::scanner::instance())
            }

            impl Scanner {
                pub fn $name $(< $( $lt : $clt ),+ >)? ( &mut self ) -> $ret_type {
                    $name2(self)
                }
            }
        };
        ( $name2:ident, $name:ident
            $(< $( $lt:tt : $clt:tt ),+ >)?
            ( $scanner:ident, $( $arg:ident : $type:ty ),* ) -> $ret_type:ty
            $body:block
        )
             =>
        {
            fn $name2 $(< $( $lt : $clt ),+ >)? ( $scanner: &mut Scanner, $( $arg : $type ),* ) -> $ret_type
                $body

            pub fn $name $(< $( $lt : $clt ),+ >)? ( $( $arg : $type ),* ) -> $ret_type {
                $name2(crate::scanner::instance(), $( $arg ),* )
            }

            impl Scanner {
                pub fn $name $(< $( $lt : $clt ),+ >)? ( &mut self, $( $arg : $type ),* ) -> $ret_type {
                    $name2( self, $( $arg ),* )
                }
            }
        };
    }

    scanner_impl!(_scan, scan<T: Token>(sc) -> T {
        use std::io::Write;
        crate::debug!(sc.buffer);
        loop {
            if let Some(token) = sc.buffer.pop() {
                debug_scan(&token);
                return token.parse().ok().expect("Failed parse");
            }
            let mut input = String::new();
            sc.reader.read_line(&mut input).expect("Failed read");
            sc.buffer = input.split_whitespace().rev().map(String::from).collect();
        }
    });

    #[rustfmt::skip]
    macro_rules! scanner_impl_for_type {
        ($ty:ty, $name:ident) => {
            impl Scanner {
                pub fn $name(&mut self) -> $ty {
                    self.scan()
                }
            }
            impl Token for $ty {
            }
            pub fn $name() -> $ty {
                instance().$name()
            }
        };
        ($ty:ty, $name:ident, $name1:ident) => {
            scanner_impl_for_type!($ty, $name);
            impl TokenNum for $ty {
            }
            impl Scanner {
                pub fn $name1(&mut self, ofs: $ty) -> $ty {
                    self.scan1(ofs)
                }
            }
            pub fn $name1(ofs: $ty) -> $ty {
                instance().$name1(ofs)
            }
        };
    }

    pub trait Token: std::str::FromStr + std::fmt::Debug {}
    pub trait TokenNum: Token + std::ops::Sub<Output = Self> {}

    scanner_impl_for_type!(usize, scan_usize, scan1_usize);
    scanner_impl_for_type!(isize, scan_isize, scan1_isize);
    scanner_impl_for_type!(i32, scan_i32, scan1_i32);
    scanner_impl_for_type!(i64, scan_i64, scan1_i64);
    scanner_impl_for_type!(u32, scan_u32, scan1_u32);
    scanner_impl_for_type!(u64, scan_u64, scan1_u64);
    scanner_impl_for_type!(String, scan_string);

    fn debug_scan<T: ToString>(val: T) {
        if crate::output_writer::macro_use::do_debug_scan() {
            let instance = crate::output_writer::macro_use::instance();
            instance.push_tok(val.to_string());
        }
    }

    // extensions
    scanner_impl!(_scan1, scan1<T: TokenNum>(sc, ofs: T) -> T {
        sc.scan::<T>() - ofs
    });
    scanner_impl!(_scan_vector, scan_vector<T: Token>(sc, n: usize) -> Vec<T> {
        debug_scan("[");
        let mut v = Vec::with_capacity(n);
        for _ in 0..n { v.push(sc.scan()); }
        debug_scan("]");
        v
    });
    scanner_impl!(_scan_pair, scan_pair<T1: Token, T2: Token>(sc) -> (T1, T2) {
        debug_scan("#p[");
        let t1 = sc.scan();
        let t2 = sc.scan();
        debug_scan("]");
        (t1,t2)
    });

}
pub use scanner::*;

#[macro_use]
mod output_writer {
    pub mod macro_use {
        use std::io::stdout;
        use std::io::BufWriter;
        use std::io::Stdout;
        use std::io::Write;
        use std::ops::Deref;
        use std::ops::DerefMut;

        static mut DEBUG: bool = false;
        static mut DEBUG_SCAN: bool = false;

        // OutputWriterImpl
        pub struct OutputWriterImpl {
            inner: BufWriter<Stdout>,
            pending_tokens: Vec<String>,
        }

        impl Default for OutputWriterImpl {
            fn default() -> Self {
                unsafe {
                    for arg in std::env::args().skip(1) {
                        match arg.as_str() {
                            "debug" => DEBUG = true,
                            "scan" => DEBUG_SCAN = true,
                            _ => {}
                        }
                    }
                }
                OutputWriterImpl {
                    inner: BufWriter::new(stdout()),
                    pending_tokens: vec![],
                }
            }
        }
        singleton!(OutputWriterImpl, OutputWriterImpl::default());

        impl OutputWriterImpl {
            pub fn push_tok(&mut self, tok: String) {
                self.pending_tokens.push(tok);
            }
        }

        impl Deref for OutputWriterImpl {
            type Target = BufWriter<Stdout>;

            fn deref(&self) -> &Self::Target {
                &instance().inner
            }
        }

        impl DerefMut for OutputWriterImpl {
            fn deref_mut(&mut self) -> &mut Self::Target {
                &mut instance().inner
            }
        }

        #[rustfmt::skip]
        pub fn start_debug() -> bool {
            crate::output_writer::macro_use::flush_pending_tokens();

            let res = unsafe { DEBUG };
            if res { instance().write(b"\x1B[33m").ok(); }
            res
        }

        #[rustfmt::skip]
        pub fn do_debug_scan() -> bool {
            unsafe { DEBUG_SCAN }
        }

        pub fn end_debug() {
            instance().write(b"\x1B[0m").ok();
        }

        pub fn flush_pending_tokens() {
            if do_debug_scan() {
                let mut any = false;
                for (i, ref tok) in instance().pending_tokens.drain(..).enumerate() {
                    let sep = if i == 0 {
                        instance().write(b"\x1B[34m").ok();
                        "DEBUG_SCAN\t"
                    } else {
                        " "
                    };

                    let instance = crate::output_writer::macro_use::instance();
                    write!(instance, "{}{}", sep, &tok).ok();
                    any = true;
                }
                if any {
                    crate::output_writer::macro_use::end_debug();
                    let instance = crate::output_writer::macro_use::instance();
                    write!(instance, "\n").ok();
                }
            }
        }

        impl Drop for crate::OutputWriter {
            fn drop(&mut self) {
                crate::output_writer::macro_use::flush_pending_tokens();
                instance().inner.flush().expect("flush");
            }
        }
    }

    // OutputWriter
    pub struct OutputWriter;

    #[macro_export]
    macro_rules! debug {
        () => {
            if crate::output_writer::macro_use::start_debug() {
                let instance = crate::output_writer::macro_use::instance();
                write!(instance, "DEBUG [{}:{}]",
                    file!(), line!()).ok();
                crate::output_writer::macro_use::end_debug();
                write!(instance, "\n").ok();
                instance.flush().ok();
            }
        };
        ($val:expr) => {
            if crate::output_writer::macro_use::start_debug() {
                let instance = crate::output_writer::macro_use::instance();
                write!(instance, "DEBUG [{}:{}] {} = {:?}",
                    file!(), line!(), stringify!($val), &$val).ok();
                crate::output_writer::macro_use::end_debug();
                write!(instance, "\n").ok();
                instance.flush().ok();
            }
        };
        ($val0:expr, $($val:expr),* $(,)?) => {
            if crate::output_writer::macro_use::start_debug() {
                let instance = crate::output_writer::macro_use::instance();
                write!(instance, "DEBUG [{}:{}] {} = {:?}",
                    file!(), line!(), stringify!($val0), &$val0).ok();
                $(write!(instance, "\nDEBUG [{}:{}] {} = {:?}",
                    file!(), line!(), stringify!($val), &$val).ok(); )*
                crate::output_writer::macro_use::end_debug();
                write!(instance, "\n").ok();
                instance.flush().ok();
            }
        };
    }

    #[macro_export]
    macro_rules! pp {
        () => {
            crate::output_writer::macro_use::flush_pending_tokens();
            let instance = crate::output_writer::macro_use::instance();
            writeln!(instance).ok()
        };
        ($e:expr $(,)?) => {
            crate::output_writer::macro_use::flush_pending_tokens();
            let instance = crate::output_writer::macro_use::instance();
            writeln!(instance, "{}", $e).ok()
        };
        ($($e:expr),+  $(,)?) => {
            crate::output_writer::macro_use::flush_pending_tokens();
            let instance = crate::output_writer::macro_use::instance();
            $( write!(instance, "{} ", $e).ok(); )+
            writeln!(instance).ok()
        };
        ($($e:expr),*;!) => {
            pp!($($e),*);
            let instance = crate::output_writer::macro_use::instance();
            instance.flush().ok();
        };
    }

    #[macro_export]
    macro_rules! pf {
        ($fmt:tt, $($e:expr),*  $(,)?) => {
            crate::output_writer::macro_use::flush_pending_tokens();
            let instance = crate::output_writer::macro_use::instance();
            writeln!(instance, $fmt, $($e),*).ok();
        };
        ($fmt:tt, $($e:expr),*  $(,)?; !) => {
            pf!($fmt,$($e),+);
            let instance = crate::output_writer::macro_use::instance();
            instance.flush().ok();
        };
    }

    #[macro_export]
    macro_rules! pps {
        ($v:expr, $ofs:expr) => {
            crate::output_writer::macro_use::flush_pending_tokens();
            let instance = crate::output_writer::macro_use::instance();
            for (i, x) in $v.iter().enumerate() {
                let e = if i + 1 == $v.len() { "\n" } else { " " };
                write!(instance, "{}{}", *x + $ofs, e).ok();
            }
        };
        ($v:expr) => {
            pps!($v, 0)
        };
    }

    #[macro_export]
    macro_rules! output_init {
        () => {
            #[warn(unused_variables)]
            let __OUTPUT__ = OutputWriter;
            let _ = instance();
        };
    }

}
pub use output_writer::*;

use std::io::Write;

fn digits(n: u64) -> usize {
    if n == 0 {
        return 0;
    }
    let mut lo = 1;
    let mut d = 1;
    while lo * 10 <= n {
        lo *= 10;
        d += 1;
    }
    d
}

#[test]
fn test_d() {
    assert_eq!(3, digits(343));
    assert_eq!(3, digits(999));
    assert_eq!(4, digits(1000));
    assert_eq!(0, digits(0));
    assert_eq!(1, digits(1));
}

fn main() {
    output_init!();

    let N = scan();
    let X = scan_u64();
    debug!(N, X);

    let mut vis = std::collections::HashSet::new();
    let mut q = std::collections::VecDeque::new();
    q.push_back((0, X));
    while let Some(x) = q.pop_front() {
        if vis.contains(&x.1) {
            continue;
        }
        vis.insert(x.1);
        if digits(x.1) == N {
            pp!(x.0);
            return;
        }
        let mut mask = 0;
        let mut xx = x.1;
        while xx > 0 {
            let d = xx % 10;
            xx /= 10;
            if (mask & (1 << d)) != 0 {
                continue;
            }
            mask |= 1 << d;
            let y: (usize, u64) = (x.0 + 1, x.1.saturating_mul(d));
            q.push_back(y);
        }
    }
    pp!(-1);
}


use std::collections::{BTreeSet, VecDeque};
use std::io::Write;

#[cfg(feature = "badcw")]
pub use notes::one_line::*;

// ---------- begin scannner ----------
#[allow(dead_code, unused_imports)]
mod scanner {
    use std::str::FromStr;
    pub struct Scanner<'a> {
        it: std::str::SplitWhitespace<'a>,
    }
    impl<'a> Scanner<'a> {
        pub fn new(s: &'a String) -> Scanner<'a> {
            Scanner {
                it: s.split_whitespace(),
            }
        }
        pub fn next<T: FromStr>(&mut self) -> T {
            self.it.next().unwrap().parse::<T>().ok().unwrap()
        }
        pub fn next_bytes(&mut self) -> Vec<u8> {
            self.it.next().unwrap().bytes().collect()
        }
        pub fn next_chars(&mut self) -> Vec<char> {
            self.it.next().unwrap().chars().collect()
        }
        pub fn next_vec<T: FromStr>(&mut self, len: usize) -> Vec<T> {
            (0..len).map(|_| self.next()).collect()
        }
        pub fn size(&self) -> usize {
            self.it.clone().count()
        }
    }
}
// ---------- end scannner ----------

fn main() {
    use std::io::Read;
    let mut s = String::new();
    std::io::stdin().read_to_string(&mut s).unwrap();
    let mut sc = scanner::Scanner::new(&s);
    let out = std::io::stdout();
    let mut out = std::io::BufWriter::new(out.lock());
    run(&mut sc, &mut out);
}

fn run<W: Write>(sc: &mut scanner::Scanner, out: &mut std::io::BufWriter<W>) {
    let T = sc.size()/2;
    for kase in 0..T {
        let n: usize = sc.next();
        let x: usize = sc.next();
        let mut qu = VecDeque::new();
        let mut st = BTreeSet::new();
        qu.push_back((x, 0));
        st.insert(x);
        let mut f = false;
        while let Some((u, dp)) = qu.pop_front() {
            let str = u.to_string();
            if str.len() > n {
                break;
            }
            if str.len() == n {
                f = true;
                writeln!(out, "{}", dp);
                break;
            }
            for c in str.as_bytes() {
                if c < &b'2' {
                    continue;
                }
                let v = u * ((c - b'0') as usize);
                if st.insert(v) {
                    qu.push_back((v, dp + 1));
                }
            }
        }
        if !f {
            writeln!(out, "-1");
        }
    }
}


use std::collections::{BTreeSet, VecDeque};
use std::io::Write;

#[cfg(feature = "badcw")]
pub use notes::one_line::*;

// ---------- begin scannner ----------
#[allow(dead_code, unused_imports)]
mod scanner {
    use std::str::FromStr;
    pub struct Scanner<'a> {
        it: std::str::SplitWhitespace<'a>,
    }
    impl<'a> Scanner<'a> {
        pub fn new(s: &'a String) -> Scanner<'a> {
            Scanner {
                it: s.split_whitespace(),
            }
        }
        pub fn next<T: FromStr>(&mut self) -> T {
            self.it.next().unwrap().parse::<T>().ok().unwrap()
        }
        pub fn next_bytes(&mut self) -> Vec<u8> {
            self.it.next().unwrap().bytes().collect()
        }
        pub fn next_chars(&mut self) -> Vec<char> {
            self.it.next().unwrap().chars().collect()
        }
        pub fn next_vec<T: FromStr>(&mut self, len: usize) -> Vec<T> {
            (0..len).map(|_| self.next()).collect()
        }
        pub fn size(&self) -> usize {
            self.it.clone().count()
        }
    }
}
// ---------- end scannner ----------

fn main() {
    use std::io::Read;
    let mut s = String::new();
    std::io::stdin().read_to_string(&mut s).unwrap();
    let mut sc = scanner::Scanner::new(&s);
    let out = std::io::stdout();
    let mut out = std::io::BufWriter::new(out.lock());
    run(&mut sc, &mut out);
}

fn run<W: Write>(sc: &mut scanner::Scanner, out: &mut std::io::BufWriter<W>) {
    let T = sc.size()/2;
    for kase in 0..T {
        let n: usize = sc.next();
        let x: usize = sc.next();
        let mut qu = VecDeque::new();
        let mut st = BTreeSet::new();
        qu.push_back((x, 0));
        st.insert(x);
        let mut f = false;
        while let Some((u, dp)) = qu.pop_front() {
            if u.to_string().len() > n {
                break;
            }
            if u.to_string().len() == n {
                f = true;
                writeln!(out, "{}", dp);
                break;
            }
            for c in u.to_string().as_bytes() {
                let v = u * ((c - b'0') as usize);
                if st.insert(v) {
                    qu.push_back((v, dp + 1));
                }
            }
        }
        if !f {
            writeln!(out, "-1");
        }
    }
}


#![allow(dead_code, unused_macros, unused_imports)]
use std::{cell::{Cell, RefCell, UnsafeCell}, cmp::{Ordering, Reverse, max, min}, collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, VecDeque, hash_map::{DefaultHasher, RandomState}}, error::Error, fmt::{Display, Write as FmtWrite}, hash::{BuildHasher, Hash, Hasher}, io::{BufWriter, Read, Stdin, Stdout, Write}, iter::{FromIterator, Peekable}, mem::swap, ops::*, process::exit, rc::Rc, str::{FromStr, from_utf8_unchecked}, time::{Duration, Instant}, convert::TryInto, marker::PhantomData};

const IO_BUF_SIZE: usize = 1 << 16;
type Input = Scanner<Stdin>;
type Output = BufWriter<Stdout>;
fn _init_input() -> Input { Scanner::new(std::io::stdin()) }
fn _init_output() -> Output { BufWriter::with_capacity(IO_BUF_SIZE, std::io::stdout()) }

#[repr(transparent)] struct Unsync<T>(T);
unsafe impl<T> Sync for Unsync<T> {}

type BadLazy<T> = Unsync<UnsafeCell<Option<T>>>;
impl<T> BadLazy<T> {
    const fn new() -> Self { Self(UnsafeCell::new(None)) }
}

static INPUT: BadLazy<Input> = BadLazy::new();
static OUTPUT: BadLazy<Output> = BadLazy::new();

fn inp<F: FnOnce(&mut Input) -> R, R>(f: F) -> R {
    unsafe { f((&mut *INPUT.0.get()).get_or_insert_with(_init_input)) }
}
fn out<F: FnOnce(&mut Output) -> R, R>(f: F) -> R {
    unsafe { f((&mut *OUTPUT.0.get()).get_or_insert_with(_init_output)) }
}

macro_rules! read {
    () => { read() };
    ($t: ty) => { read::<$t>() };
    ($t: ty, $($tt: ty),*) => { (read::<$t>(), $(read::<$tt>(),)*) };
    [$t: ty; $n: expr] => { read_vec::<$t>($n) };
}
macro_rules! println {
    () => { out(|x| { let _ = writeln!(x); }) };
    ($exp: expr) => { out(|x| { let _ = writeln!(x, "{}", $exp); }) };
    ($fmt: expr, $($arg : tt )*) => { out(|x| { let _ = writeln!(x, $fmt, $($arg)*); }) }
}
macro_rules! print {
    ($exp: expr) => { out(|x| { let _ = write!(x, "{}", $exp); }) };
    ($fmt: expr, $($arg : tt )*) => { out(|x| { let _ = write!(x, $fmt, $($arg)*); }) }
}

fn out_flush() { out(|x| { let _ = x.flush(); }); }

fn input_is_eof() -> bool { inp(|x| x.eof()) }
fn read_byte() -> u8 { inp(|x| x.byte()) }
fn read_bytes_no_skip(n: usize) -> Vec<u8> { inp(|x| x.bytes_no_skip(n)) }
fn read_bytes(n: usize) -> Vec<u8> { inp(|x| x.bytes(n)) }
fn read_bytes2(n: usize, m: usize) -> Vec<Vec<u8>> { inp(|x| x.bytes2(n, m)) }
fn read_token() -> Vec<u8> { inp(|x| x.token_bytes()) }
fn read_token_str() -> String { unsafe { String::from_utf8_unchecked(read_token()) } }
fn read_line() -> Vec<u8> { inp(|x| x.line_bytes()) }
fn read_line_str() -> String { unsafe { String::from_utf8_unchecked(read_line()) } }
fn read<T: FromStr>() -> T { read_token_str().parse::<T>().ok().expect("failed parse") }
fn read_vec<T: FromStr>(n: usize) -> Vec<T> { (0..n).map(|_| read()).collect() }
fn read_vec2<T: FromStr>(n: usize, m: usize) -> Vec<Vec<T>> { (0..n).map(|_| read_vec(m)).collect() }

struct Scanner<R: Read> {
    src: R,
    _buf: Vec<u8>,
    _pt: usize, // pointer
    _rd: usize, // bytes read
}

#[allow(dead_code)]
impl<R: Read> Scanner<R> {
    fn new(src: R) -> Scanner<R> {
        Scanner { src, _buf: vec![0; IO_BUF_SIZE], _pt: 1, _rd: 1 }
    }

    fn _check_buf(&mut self) {
        if self._pt == self._rd {
            self._rd = self.src.read(&mut self._buf).unwrap_or(0);
            self._pt = (self._rd == 0) as usize;
        }
    }

    // returns true if end of file
    fn eof(&mut self) -> bool {
        self._check_buf();
        self._rd == 0
    }

    // filters \r, returns \0 if eof
    fn byte(&mut self) -> u8 {
        loop {
            self._check_buf();
            if self._rd == 0 { return 0; }
            let res = self._buf[self._pt];
            self._pt += 1;
            if res != b'\r' { return res; }
        }
    }

    fn bytes_no_skip(&mut self, n: usize) -> Vec<u8> { (0..n).map(|_| self.byte()).collect() }
    fn bytes(&mut self, n: usize) -> Vec<u8> {
        let res = self.bytes_no_skip(n);
        self.byte();
        res
    }
    fn bytes2(&mut self, n: usize, m: usize) -> Vec<Vec<u8>> { (0..n).map(|_| self.bytes(m)).collect() }

    fn token_bytes(&mut self) -> Vec<u8> {
        let mut res = Vec::new();
        let mut c = self.byte();
        while c <= b' ' {
            if c == b'\0' { return res; }
            c = self.byte();
        }
        loop {
            res.push(c);
            c = self.byte();
            if c <= b' ' { return res; }
        }
    }

    fn line_bytes(&mut self) -> Vec<u8> {
        let mut res = Vec::new();
        let mut c = self.byte();
        while c != b'\n' && c != b'\0' {
            res.push(c);
            c = self.byte();
        }
        res
    }
}

trait JoinToStr {
    fn join_to_str(self, sep: &str) -> String;
    fn concat_to_str(self) -> String;
}
impl<T: Display, I: Iterator<Item = T>> JoinToStr for I {
    fn join_to_str(mut self, sep: &str) -> String {
        match self.next() {
            Some(first) => {
                let mut res = first.to_string();
                while let Some(item) = self.next() {
                    res.push_str(sep);
                    res.push_str(&item.to_string());
                }
                res
            }
            None => { String::new() }
        }
    }

    fn concat_to_str(self) -> String {
        let mut res = String::new();
        for item in self { res.push_str(&item.to_string()); }
        res
    }
}
trait AsStr { fn as_str(&self) -> &str; }
impl AsStr for [u8] { fn as_str(&self) -> &str {std::str::from_utf8(self).expect("attempt to convert non-UTF8 byte string.")} }

macro_rules! veci {
    ($n:expr , $i:ident : $gen:expr) => {{
        let _veci_n = $n;
        let mut _veci_list = Vec::with_capacity(_veci_n);
        for $i in 0.._veci_n {
            _veci_list.push($gen);
        }
        _veci_list
    }};
    ($n:expr , $gen:expr) => { veci!($n, _veci_: $gen) }
}

fn abs_diff<T: Sub<Output = T> + PartialOrd>(x: T, y: T) -> T {
    if x < y { y - x } else { x - y }
}

trait CommonNumExt {
    fn div_ceil(self, b: Self) -> Self;
    fn div_floor(self, b: Self) -> Self;
    fn gcd(self, b: Self) -> Self;
    fn highest_one(self) -> Self;
    fn lowest_one(self) -> Self;
    fn sig_bits(self) -> u32;
}

macro_rules! impl_common_num_ext {
    ($($ix:tt = $ux:tt),*) => {
        $(
            impl CommonNumExt for $ux {
                fn div_ceil(self, b: Self) -> Self {
                    let q = self / b; let r = self % b;
                    if r != 0 { q + 1 } else { q }
                }
                fn div_floor(self, b: Self) -> Self { self / b }
                fn gcd(self, mut b: Self) -> Self {
                    let mut a = self; while a != 0 { swap(&mut a, &mut b); a %= b; }
                    b
                }
                #[inline] fn highest_one(self) -> Self {
                    if self == 0 { 0 } else { const ONE: $ux = 1; ONE << self.sig_bits() - 1 }
                }
                #[inline] fn lowest_one(self) -> Self { self & self.wrapping_neg() }
                #[inline] fn sig_bits(self) -> u32 { std::mem::size_of::<$ux>() as u32 * 8 - self.leading_zeros() }
            }

            impl CommonNumExt for $ix {
                fn div_ceil(self, b: Self) -> Self {
                    let q = self / b; let r = self % b;
                    if self ^ b >= 0 && r != 0 { q + 1 } else { q }
                }
                fn div_floor(self, b: Self) -> Self {
                    let q = self / b; let r = self % b;
                    if self ^ b < 0 && r != 0 { q - 1 } else { q }
                }
                fn gcd(self, mut b: Self) -> Self {
                    let mut a = self; while a != 0 { swap(&mut a, &mut b); a %= b; }
                    b.abs()
                }
                #[inline] fn highest_one(self) -> Self { (self as $ux).highest_one() as _ }
                #[inline] fn lowest_one(self) -> Self { self & self.wrapping_neg() }
                #[inline] fn sig_bits(self) -> u32 { std::mem::size_of::<$ix>() as u32 * 8 - self.leading_zeros() }
            }
        )*
    }
}
impl_common_num_ext!(i8 = u8, i16 = u16, i32 = u32, i64 = u64, i128 = u128, isize = usize);

trait ChMaxMin<T> {
    fn chmax(&mut self, v: T) -> bool;
    fn chmin(&mut self, v: T) -> bool;
}
impl<T: PartialOrd> ChMaxMin<T> for Option<T> {
    fn chmax(&mut self, v: T) -> bool { if self.is_none() || v > *self.as_ref().unwrap() { *self = Some(v); true } else { false } }
    fn chmin(&mut self, v: T) -> bool { if self.is_none() || v < *self.as_ref().unwrap() { *self = Some(v); true } else { false } }
}
impl<T: PartialOrd> ChMaxMin<T> for T {
    fn chmax(&mut self, v: T) -> bool { if v > *self { *self = v; true } else { false } }
    fn chmin(&mut self, v: T) -> bool { if v < *self { *self = v; true } else { false } }
}

// * end commons * //

fn generate_seed() -> u64 {
    let state = RandomState::new();
    let mut hasher = state.build_hasher();
    Instant::now().hash(&mut hasher);
    hasher.finish()
}

#[derive(Debug, Clone, Copy)]
struct SHash(u64, u64);
impl SHash {
    pub fn new() -> Self {
        Self::from_seed(generate_seed(), generate_seed())
    }

    pub fn from_seed(k: u64, m: u64) -> Self {
        Self(k, m)
    }
}
impl BuildHasher for SHash {
    type Hasher = Self;
    fn build_hasher(&self) -> Self::Hasher {
        *self
    }
}
impl Hasher for SHash {
    fn write(&mut self, mut bytes: &[u8]) {
        while bytes.len() >= 8 {
            let x = bytes.as_ptr() as *const u64;
            let x = unsafe { x.read_unaligned() };
            self.write_u64(x);
            bytes = &bytes[8..];
        }
        if bytes.len() > 0 {
            let mut x = [!0u8; 8];
            unsafe { std::ptr::copy_nonoverlapping(bytes.as_ptr(), x.as_mut_ptr(), bytes.len()) }
            let x = u64::from_ne_bytes(x);
            self.write_u64(x);
        }
    }
    fn write_u8(&mut self, i: u8) { self.write_u64(i as _) }
    fn write_u16(&mut self, i: u16) { self.write_u64(i as _) }
    fn write_u32(&mut self, i: u32) { self.write_u64(i as _) }
    fn write_usize(&mut self, i: usize) { self.write_u64(i as _) }
    #[inline] fn write_u64(&mut self, i: u64) {
        let mut z = i.wrapping_add(self.1);
        z ^= z.rotate_right(25) ^ z.rotate_right(47);
        z = z.wrapping_mul(0x9E6C63D0676A9A99).wrapping_add(self.0);
        z ^= z >> 23 ^ z >> 51;
        z = z.wrapping_mul(0x9E6D62D06F6A9A9B);
        z ^= z >> 23 ^ z >> 51;
        self.0 = z;
        self.1 = self.1.wrapping_mul(6364136223846793005).wrapping_add(1442695040888963407);
    }
    fn write_u128(&mut self, i: u128) { self.write_u64(i as _); self.write_u64((i >> 64) as _); }
    fn finish(&self) -> u64 {
        self.0
    }
}
impl Default for SHash { fn default() -> Self { Self::new() } }

#[allow(non_snake_case, non_upper_case_globals)]
fn main() {
    let num_cases: usize = 1;//read();

    for _case_num in 1..=num_cases {
        let n = read!(usize);
        let x = read!(u64);

        let mut D = HashMap::with_hasher(SHash::new());
        D.insert(x, 0);
        let mut que = VecDeque::new();
        que.push_back(x);

        let ans = (||{
            while let Some(u) = que.pop_front() {
                let s = u.to_string().into_bytes();
                if s.len() > n { continue; }
                let d = D[&u];
                if s.len() == n { return d; }

                for c in s {
                    let c = (c - b'0') as u64;
                    let v = u.saturating_mul(c);
                    if D.entry(v).or_insert(i32::MAX).chmin(d + 1) {
                        que.push_back(v);
                    }
                }
            }

            -1
        })();
        println!(ans);
    }

    out_flush();
}


use std::collections::{BTreeMap, VecDeque};

fn main() {
    let (r, w) = (std::io::stdin(), std::io::stdout());
    let mut sc = IO::new(r.lock(), w.lock());

    let n: usize = sc.read();
    let x: i64 = sc.read();

    if n < x.to_string().len() {
        println!("-1");
        return;
    }

    let mut dist = BTreeMap::new();
    dist.insert(x, 0);
    let mut q = VecDeque::new();
    q.push_back(x);
    while let Some(v) = q.pop_front() {
        let s = v.to_string();
        if s.len() == n {
            println!("{}", dist[&v]);
            return;
        }

        let mut cur = v;
        while cur > 0 {
            let p = cur % 10;
            let next = v * p;
            if next.to_string().len() <= n && !dist.contains_key(&next) {
                let d = dist[&v] + 1;
                dist.insert(next, d);
                q.push_back(next);
            }

            cur /= 10;
        }
    }
    println!("-1");
}

pub struct IO<R, W: std::io::Write>(R, std::io::BufWriter<W>);

impl<R: std::io::Read, W: std::io::Write> IO<R, W> {
    pub fn new(r: R, w: W) -> Self {
        Self(r, std::io::BufWriter::new(w))
    }
    pub fn write<S: ToString>(&mut self, s: S) {
        use std::io::Write;
        self.1.write_all(s.to_string().as_bytes()).unwrap();
    }
    pub fn read<T: std::str::FromStr>(&mut self) -> T {
        use std::io::Read;
        let buf = self
            .0
            .by_ref()
            .bytes()
            .map(|b| b.unwrap())
            .skip_while(|&b| b == b' ' || b == b'\n' || b == b'\r' || b == b'\t')
            .take_while(|&b| b != b' ' && b != b'\n' && b != b'\r' && b != b'\t')
            .collect::<Vec<_>>();
        unsafe { std::str::from_utf8_unchecked(&buf) }
            .parse()
            .ok()
            .expect("Parse error.")
    }
    pub fn usize0(&mut self) -> usize {
        self.read::<usize>() - 1
    }
    pub fn vec<T: std::str::FromStr>(&mut self, n: usize) -> Vec<T> {
        (0..n).map(|_| self.read()).collect()
    }
    pub fn chars(&mut self) -> Vec<char> {
        self.read::<String>().chars().collect()
    }
}


use std::io;

fn main() {
    const vowels: [char; 6] = ['a', 'o', 'y', 'e', 'u', 'i'];

    let mut input = String::new();
    io::stdin().read_line(&mut input);

    for letter in input.trim().to_ascii_lowercase().chars() {
        if vowels.contains(&letter) { continue; }
        print!(".");
        print!("{}", letter);
    }
}


use std::io;

fn main() {
	let mut s = String::new();
	io::stdin().read_line(&mut s).unwrap();
	s = s.trim().to_string();
	let mut result = String::new();
	for mut i in s.chars() {
		match i {
			'a' | 'A' |
			'o' | 'O' |
			'y' | 'Y' |
			'e' | 'E' |
			'u' | 'U' |
			'i' | 'I' => {}
			_ => {
				result.push('.');
				if i >= 'A' && i <= 'Z' {
					result.push(i.to_lowercase().next().unwrap());
				} else {
					result.push(i);
				}
			}
		}
	}
    println!("{}", result);
}


fn main() {
    let mut s = String::new();
    std::io::stdin().read_line(&mut s).unwrap();

    for c in s.trim().chars() {
        match c {
            'A' | 'O' | 'Y' | 'E' | 'U' | 'I' |
            'a' | 'o' | 'y' | 'e' | 'u' | 'i' => {
                continue;
            }, _ => {
                print!(".");
                if c.is_lowercase() {
                    print!("{}", c);
                } else {
                    print!("{}", (('a' as u8) + (c as u8) - ('A' as u8)) as char);
                }
            }
        }
    }

    println!("");
}


use std::io;

fn get_line() -> String {
	let mut input = String::new();

	io::stdin().read_line(&mut input)
		.expect("");

	String::from(input.trim())
}

fn main() {
	let s = get_line();
	let mut r = String::new();

	for c in s.chars() {
		match c {
			'A'|'E'|'I'|'O'|'U'|'Y'|'a'|'e'|'i'|'o'|'u'|'y' => {},
			d if d.is_uppercase() => { r += ".";
									   r += &d.to_lowercase()
									   		  .nth(0)
									   		  .unwrap()
									   		  .to_string();
									  },
			_ => { r += ".";
				   r += &c.to_string()
				 }
		}
	}

	println!("{}", r);
}


fn main() {
    let inp = read_string();
    let inp: String = inp.chars().filter(|c| {
        c.to_lowercase().to_string() != "a" &&
        c.to_lowercase().to_string() != "i" &&
        c.to_lowercase().to_string() != "u" &&
        c.to_lowercase().to_string() != "e" &&
        c.to_lowercase().to_string() != "o" &&
        c.to_lowercase().to_string() != "y"
    }).collect();
    for i in inp.chars() {
        print!(".{}", i.to_lowercase());
    }
}

fn read_string() -> String {
    let mut buffer = String::new();
    std::io::stdin().read_line(&mut buffer).expect("x");
    buffer.trim().to_string()
}


use std::io;
fn main(){
  let mut input = String::new();
  io::stdin().read_line(&mut input);
  for c in input.to_lowercase().chars(){
    match c{
      'a' | 'o' | 'e' | 'i' | 'y'| 'u'|'\r'|'\n' =>{
        continue;
      }
      _ =>{
        print!(".{}", c);
      }
    }
  }
}


use std::io;

fn main() {
  let stdin = io::stdin();
  let mut s = String::new();
  stdin.read_line(&mut s).unwrap();
  s = s.trim().to_string();

  let mut r = String::new();

  for c in s.chars() {
    let mut a = c;
    a.make_ascii_lowercase();
    if "aoyeui".contains(a) {
      continue;
    } else {
      r.push('.');
      r.push(a);
    }
  }

  println!("{}", r);
}


use std::collections::HashSet;

fn main() {
    let mut s = String::new();
    std::io::stdin().read_line(&mut s).unwrap();
    let mut vowels = HashSet::new();
    for c in b"aeiouy".iter() {
        vowels.insert(c);
    }
    for c in s.trim().to_lowercase().bytes().filter(|c| !vowels.contains(c)) {
        print!(".{}", c as char);
    }
    println!("");
}


// ---------- begin ModInt ----------
const MOD: u32 = 998_244_353;
#[derive(Clone, Copy)]
struct ModInt(u32);

impl std::ops::Add for ModInt {
    type Output = ModInt;
    fn add(self, rhs: ModInt) -> ModInt {
        let mut d = self.0 + rhs.0;
        if d >= MOD {
            d -= MOD;
        }
        ModInt(d)
    }
}

impl std::ops::Mul for ModInt {
    type Output = ModInt;
    fn mul(self, rhs: ModInt) -> ModInt {
        ModInt((self.0 as u64 * rhs.0 as u64 % MOD as u64) as u32)
    }
}

impl std::ops::Sub for ModInt {
    type Output = ModInt;
    fn sub(self, rhs: ModInt) -> ModInt {
        let mut d = self.0 + MOD - rhs.0;
        if d >= MOD {
            d -= MOD;
        }
        ModInt(d)
    }
}

impl std::ops::Neg for ModInt {
    type Output = ModInt;
    fn neg(self) -> ModInt {
        if self.0 == 0 {self} else {ModInt(MOD - self.0)}
    }
}

impl std::ops::AddAssign for ModInt {
    fn add_assign(&mut self, rhs: ModInt) {
        *self = *self + rhs;
    }
}

impl std::ops::MulAssign for ModInt {
    fn mul_assign(&mut self, rhs: ModInt) {
        *self = *self * rhs;
    }
}

impl std::ops::SubAssign for ModInt {
    fn sub_assign(&mut self, rhs: ModInt) {
        *self = *self - rhs;
    }
}

impl std::fmt::Display for ModInt {
    fn fmt<'a>(&self, f: &mut std::fmt::Formatter<'a>) -> std::fmt::Result {
        write!(f, "{}", self.0)
    }
}

impl std::str::FromStr for ModInt {
    type Err = std::num::ParseIntError;
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        let val = s.parse::<u32>()?;
        Ok(ModInt::new(val))
    }
}

#[allow(dead_code)]
impl ModInt {
    pub fn new(v: u32) -> ModInt {
        ModInt(v % MOD)
    }
    pub fn zero() -> ModInt {
        ModInt(0)
    }
    pub fn one() -> ModInt {
        ModInt(1)
    }
    pub fn pow(self, mut n: u32) -> ModInt {
        let mut t = ModInt::one();
        let mut s = self;
        while n > 0 {
            if n & 1 == 1 {
                t = t * s;
            }
            s = s * s;
            n >>= 1;
        }
        t
    }
    pub fn inv(self) -> ModInt {
        self.pow(MOD - 2)
    }
}
// ---------- end ModInt ----------
// ---------- begin Precalc ----------
#[allow(dead_code)]
struct Precalc {
    n: usize,
    inv: Vec<ModInt>,
    fact: Vec<ModInt>,
    ifact: Vec<ModInt>,
}

#[allow(dead_code)]
impl Precalc {
    pub fn new(n: usize) -> Precalc {
        let mut inv = vec![ModInt::one(); n + 1];
        let mut fact = vec![ModInt::one(); n + 1];
        let mut ifact = vec![ModInt::one(); n + 1];
        for i in 2..(n + 1) {
            inv[i] = -inv[MOD as usize % i] * ModInt(MOD / i as u32);
            fact[i] = fact[i - 1] * ModInt(i as u32);
            ifact[i] = ifact[i - 1] * inv[i];
        }
        Precalc {
            n: n,
            inv: inv,
            fact: fact,
            ifact: ifact,
        }
    }
    pub fn fact(&self, n: usize) -> ModInt {
        self.fact[n]
    }
    pub fn ifact(&self, n: usize) -> ModInt {
        self.ifact[n]
    }
    pub fn comb(&self, n: usize, k: usize) -> ModInt {
        self.fact[n] * self.ifact[k] * self.ifact[n - k]
    }
    pub fn inv(&self, n: usize) -> ModInt {
        self.inv[n]
    }
}

// ---------- end Precalc ----------
// ---------- begin NTT ----------
fn ntt(f: &mut [ModInt]) {
    let n = f.len();
    assert!(n.count_ones() == 1);
    let len = n.trailing_zeros() as usize;
    for i in 1..(n - 1){
        let mut x = i;
        let mut j = 0;
        for _ in 0..len {
            j = (j << 1) | (x & 1);
            x >>= 1;
        }
        if i < j {
            f.swap(i, j);
        }
    }
    for k in 0..(n.trailing_zeros() as usize) {
        let m = 1 << k;
        let z = ModInt(3).pow((MOD - 1) >> (k + 1) as u32);
        for f in f.chunks_mut(2 * m) {
            let mut q = ModInt::one();
            let (x, y) = f.split_at_mut(m);
            for (x, y) in x.iter_mut().zip(y.iter_mut()) {
                let a = *x;
                let b = q * *y;
                *x = a + b;
                *y = a - b;
                q *= z;
            }
        }
    }
}

fn intt(f: &mut [ModInt]) {
    ntt(f);
    f[1..].reverse();
    let ik = ModInt(f.len() as u32).inv();
    for f in f.iter_mut() {
        *f *= ik;
    }
}

fn multiply(a: &[ModInt], b: &[ModInt]) -> Vec<ModInt> {
    let n = a.len() + b.len() - 1;
    let mut k = 1;
    while k < n {
        k *= 2;
    }
    assert!(k <= (1 << 23));
    let mut f = Vec::with_capacity(k);
    let mut g = Vec::with_capacity(k);
    f.extend_from_slice(a);
    f.resize(k, ModInt::zero());
    ntt(&mut f);
    g.extend_from_slice(b);
    g.resize(k, ModInt::zero());
    ntt(&mut g);
    for (f, g) in f.iter_mut().zip(g.iter()) {
        *f *= *g;
    }
    intt(&mut f);
    f.truncate(n);
    f
}

// ---------- end NTT ----------

fn calc(n: usize, p: ModInt, k: usize) -> Vec<ModInt> {
    if n == 1 {
        let mut ans = vec![ModInt::one()];
        for _ in 1..=k {
            ans.push(p);
        }
        ans
    } else if n % 2 == 1 {
        let mut dp = calc(n - 1, p, k);
        let mut v = calc(1, p, k);
        let pc = Precalc::new(2 * k);
        for i in 0..=k {
            dp[i] *= pc.ifact(i);
            v[i] *= pc.ifact(i);
        }
        let mut ans = multiply(&dp, &v);
        for i in 0..=k {
            ans[i] *= pc.fact(i);
        }
        ans.truncate(k + 1);
        ans
    } else {
        let mut dp = calc(n / 2, p, k);
        let pc = Precalc::new(2 * k);
        for i in 0..=k {
            dp[i] *= pc.ifact(i);
        }
        let mut ans = multiply(&dp, &dp);
        for i in 0..=k {
            ans[i] *= pc.fact(i);
        }
        ans.truncate(k + 1);
        ans
    }
}

fn run() {
    let mut s = String::new();
    std::io::stdin().read_line(&mut s).unwrap();
    let mut it = s.trim().split_whitespace();
    let n: usize = it.next().unwrap().parse().unwrap();
    let m: u32 = it.next().unwrap().parse().unwrap();
    let k: usize = it.next().unwrap().parse().unwrap();
    let ans = calc(n, ModInt(m).inv(), k);
    println!("{}", ans[k]);
}

fn main() {
    run();
}


#[allow(unused_imports)]
use std::cmp::*;
#[allow(unused_imports)]
use std::collections::*;
use std::io::{Write, BufWriter};
// https://qiita.com/tanakh/items/0ba42c7ca36cd29d0ac8
macro_rules! input {
    ($($r:tt)*) => {
        let stdin = std::io::stdin();
        let mut bytes = std::io::Read::bytes(std::io::BufReader::new(stdin.lock()));
        let mut next = move || -> String{
            bytes
                .by_ref()
                .map(|r|r.unwrap() as char)
                .skip_while(|c|c.is_whitespace())
                .take_while(|c|!c.is_whitespace())
                .collect()
        };
        input_inner!{next, $($r)*}
    };
}

macro_rules! input_inner {
    ($next:expr) => {};
    ($next:expr, ) => {};

    ($next:expr, $var:ident : $t:tt $($r:tt)*) => {
        let $var = read_value!($next, $t);
        input_inner!{$next $($r)*}
    };
}

macro_rules! read_value {
    ($next:expr, ( $($t:tt),* )) => {
        ( $(read_value!($next, $t)),* )
    };

    ($next:expr, [ $t:tt ; $len:expr ]) => {
        (0..$len).map(|_| read_value!($next, $t)).collect::<Vec<_>>()
    };

    ($next:expr, chars) => {
        read_value!($next, String).chars().collect::<Vec<char>>()
    };

    ($next:expr, usize1) => {
        read_value!($next, usize) - 1
    };

    ($next:expr, [ $t:tt ]) => {{
        let len = read_value!($next, usize);
        (0..len).map(|_| read_value!($next, $t)).collect::<Vec<_>>()
    }};

    ($next:expr, $t:ty) => {
        $next().parse::<$t>().expect("Parse error")
    };
}

/// Verified by https://atcoder.jp/contests/arc093/submissions/3968098
mod mod_int {
    use std::ops::*;
    pub trait Mod: Copy { fn m() -> i64; }
    #[derive(Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
    pub struct ModInt<M> { pub x: i64, phantom: ::std::marker::PhantomData<M> }
    impl<M: Mod> ModInt<M> {
        // x >= 0
        pub fn new(x: i64) -> Self { ModInt::new_internal(x % M::m()) }
        fn new_internal(x: i64) -> Self {
            ModInt { x: x, phantom: ::std::marker::PhantomData }
        }
        pub fn pow(self, mut e: i64) -> Self {
            debug_assert!(e >= 0);
            let mut sum = ModInt::new_internal(1);
            let mut cur = self;
            while e > 0 {
                if e % 2 != 0 { sum *= cur; }
                cur *= cur;
                e /= 2;
            }
            sum
        }
        #[allow(dead_code)]
        pub fn inv(self) -> Self { self.pow(M::m() - 2) }
    }
    impl<M: Mod, T: Into<ModInt<M>>> Add<T> for ModInt<M> {
        type Output = Self;
        fn add(self, other: T) -> Self {
            let other = other.into();
            let mut sum = self.x + other.x;
            if sum >= M::m() { sum -= M::m(); }
            ModInt::new_internal(sum)
        }
    }
    impl<M: Mod, T: Into<ModInt<M>>> Sub<T> for ModInt<M> {
        type Output = Self;
        fn sub(self, other: T) -> Self {
            let other = other.into();
            let mut sum = self.x - other.x;
            if sum < 0 { sum += M::m(); }
            ModInt::new_internal(sum)
        }
    }
    impl<M: Mod, T: Into<ModInt<M>>> Mul<T> for ModInt<M> {
        type Output = Self;
        fn mul(self, other: T) -> Self { ModInt::new(self.x * other.into().x % M::m()) }
    }
    impl<M: Mod, T: Into<ModInt<M>>> AddAssign<T> for ModInt<M> {
        fn add_assign(&mut self, other: T) { *self = *self + other; }
    }
    impl<M: Mod, T: Into<ModInt<M>>> SubAssign<T> for ModInt<M> {
        fn sub_assign(&mut self, other: T) { *self = *self - other; }
    }
    impl<M: Mod, T: Into<ModInt<M>>> MulAssign<T> for ModInt<M> {
        fn mul_assign(&mut self, other: T) { *self = *self * other; }
    }
    impl<M: Mod> Neg for ModInt<M> {
        type Output = Self;
        fn neg(self) -> Self { ModInt::new(0) - self }
    }
    impl<M> ::std::fmt::Display for ModInt<M> {
        fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
            self.x.fmt(f)
        }
    }
    impl<M> ::std::fmt::Debug for ModInt<M> {
        fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
            self.x.fmt(f)
        }
    }
    impl<M: Mod> From<i64> for ModInt<M> {
        fn from(x: i64) -> Self { Self::new(x) }
    }
} // mod mod_int

macro_rules! define_mod {
    ($struct_name: ident, $modulo: expr) => {
        #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
        struct $struct_name {}
        impl mod_int::Mod for $struct_name { fn m() -> i64 { $modulo } }
    }
}
const MOD: i64 = 998244353;
define_mod!(P, MOD);
type ModInt = mod_int::ModInt<P>;

/// FFT (in-place, verified as NTT only)
/// R: Ring + Copy
/// Verified by: https://codeforces.com/contest/1096/submission/47672373
mod fft {
    use std::ops::*;
    /// n should be a power of 2. zeta is a primitive n-th root of unity.
    /// one is unity
    /// Note that the result should be multiplied by 1/sqrt(n).
    pub fn transform<R>(f: &mut [R], zeta: R, one: R)
        where R: Copy +
        Add<Output = R> +
        Sub<Output = R> +
        Mul<Output = R> {
        let n = f.len();
        assert!(n.is_power_of_two());
        {
            let mut i = 0;
            for j in 1 .. n - 1 {
                let mut k = n >> 1;
                loop {
                    i ^= k;
                    if k <= i { break; }
                    k >>= 1;
                }
                if j < i { f.swap(i, j); }
            }
        }
        let mut zetapow = Vec::new();
        {
            let mut m = 1;
            let mut cur = zeta;
            while m < n {
                zetapow.push(cur);
                cur = cur * cur;
                m *= 2;
            }
        }
        let mut m = 1;
        while m < n {
            let base = zetapow.pop().unwrap();
            let mut r = 0;
            while r < n {
                let mut w = one;
                for s in r .. r + m {
                    let u = f[s];
                    let d = f[s + m] * w;
                    f[s] = u + d;
                    f[s + m] = u - d;
                    w = w * base;
                }
                r += 2 * m;
            }
            m *= 2;
        }
    }
}

use fft::*;

// Depends on ModInt.rs
fn fact_init(w: usize) -> (Vec<ModInt>, Vec<ModInt>) {
    let mut fac = vec![ModInt::new(1); w];
    let mut invfac = vec![0.into(); w];
    for i in 1 .. w {
        fac[i] = fac[i - 1] * i as i64;
    }
    invfac[w - 1] = fac[w - 1].inv();
    for i in (0 .. w - 1).rev() {
        invfac[i] = invfac[i + 1] * (i as i64 + 1);
    }
    (fac, invfac)
}

fn solve() {
    let out = std::io::stdout();
    let mut out = BufWriter::new(out.lock());
    macro_rules! puts {
        ($($format:tt)*) => (write!(out,$($format)*).unwrap());
    }
    input! {
        n: usize,
        k: usize,
        l: i64,
    }
    const N: usize = 4096;
    let (fac, invfac) = fact_init(N);

    let mut p = vec![ModInt::new(0); N];
    let mut q = vec![ModInt::new(0); N];
    p[1] = ModInt::new(2);
    p[2] = -ModInt::new(2);
    q[0] = ModInt::new(1);
    q[1] = -ModInt::new(2);
    q[2] = ModInt::new(2);

    let zeta = ModInt::new(3).pow((MOD - 1) / N as i64);
    transform(&mut p, zeta, ModInt::new(1));
    transform(&mut q, zeta, ModInt::new(1));

    let mut ans = vec![ModInt::new(0); N];
    let mut coef = vec![ModInt::new(0); N];
    for i in k..n + 1 {
        coef[i] = fac[n] * invfac[n - i] * invfac[i];
    }
    for j in 0..N {
        let mut pp = p[j].pow(k as i64);
        let mut qp = q[j].pow((n - k) as i64);
        let mut qinv = q[j].inv();
        for i in k..n + 1 {
            let coef = coef[i];
            ans[j] += pp * qp * coef;
            pp *= p[j];
            qp *= qinv;
        }
    }
    transform(&mut ans, zeta.inv(), ModInt::new(1));
    // eprintln!("ans = {:?}", &ans[0..10]);
    let mut tot = ModInt::new(0);
    for i in 0..2 * n + 1 {
        tot += ans[i] * ModInt::new((i + 1) as i64).inv();
    }
    tot *= ModInt::new(N as i64).inv();
    puts!("{}\n", tot * l);
}

fn main() {
    // In order to avoid potential stack overflow, spawn a new thread.
    let stack_size = 104_857_600; // 100 MB
    let thd = std::thread::Builder::new().stack_size(stack_size);
    thd.spawn(|| solve()).unwrap().join().unwrap();
}


// ---------- begin ModInt ----------
const MOD: u32 = 998_244_353;

#[derive(Clone, Copy)]
struct ModInt(u32);

impl std::ops::Add for ModInt {
    type Output = ModInt;
    fn add(self, rhs: ModInt) -> Self::Output {
        let mut d = self.0 + rhs.0;
        if d >= MOD {
            d -= MOD;
        }
        ModInt(d)
    }
}

impl std::ops::AddAssign for ModInt {
    fn add_assign(&mut self, rhs: ModInt) {
        *self = *self + rhs;
    }
}

impl std::ops::Sub for ModInt {
    type Output = ModInt;
    fn sub(self, rhs: ModInt) -> Self::Output {
        let mut d = self.0 + MOD - rhs.0;
        if d >= MOD {
            d -= MOD;
        }
        ModInt(d)
    }
}

impl std::ops::SubAssign for ModInt {
    fn sub_assign(&mut self, rhs: ModInt) {
        *self = *self - rhs;
    }
}

impl std::ops::Mul for ModInt {
    type Output = ModInt;
    fn mul(self, rhs: ModInt) -> Self::Output {
        ModInt((self.0 as u64 * rhs.0 as u64 % MOD as u64) as u32)
    }
}

impl std::ops::MulAssign for ModInt {
    fn mul_assign(&mut self, rhs: ModInt) {
        *self = *self * rhs;
    }
}

impl std::ops::Neg for ModInt {
    type Output = ModInt;
    fn neg(self) -> Self::Output {
        ModInt(if self.0 == 0 {0} else {MOD - self.0})
    }
}

/*
impl std::fmt::Display for ModInt {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "{}", self.0)
    }
}
*/

#[allow(dead_code)]
impl ModInt {
    pub fn new(n: u32) -> ModInt {
        ModInt(n % MOD)
    }
    pub fn zero() -> ModInt {
        ModInt(0)
    }
    pub fn one() -> ModInt {
        ModInt(1)
    }
    pub fn pow(self, mut n: u32) -> ModInt {
        let mut t = ModInt::one();
        let mut s = self;
        while n > 0 {
            if n & 1 == 1 {
                t *= s;
            }
            s *= s;
            n >>= 1;
        }
        t
    }
    pub fn inv(self) -> ModInt {
        self.pow(MOD - 2)
    }
    pub fn comb(n: u32, k: u32) -> ModInt {
        if k > n {
            return ModInt::zero();
        }
        let k = std::cmp::min(k, n - k);
        let mut nu = ModInt::one();
        let mut de = ModInt::one();
        for i in 0..k {
            nu *= ModInt(n - i);
            de *= ModInt(i + 1);
        }
        nu * de.inv()
    }
}

#[allow(dead_code)]
struct Precalc {
    inv: Vec<ModInt>,
    fact: Vec<ModInt>,
    ifact: Vec<ModInt>,
}

#[allow(dead_code)]
impl Precalc {
    pub fn new(n: usize) -> Precalc {
        let mut inv = vec![ModInt::one(); n + 1];
        let mut fact = vec![ModInt::one(); n + 1];
        let mut ifact = vec![ModInt::one(); n + 1];
        for i in 2..(n + 1) {
            inv[i] = -inv[MOD as usize % i] * ModInt(MOD / i as u32);
            fact[i] = fact[i - 1] * ModInt(i as u32);
            ifact[i] = ifact[i - 1] * inv[i];
        }
        Precalc {
            inv: inv,
            fact: fact,
            ifact: ifact,
        }
    }
    pub fn inv(&self, n: usize) -> ModInt {
        self.inv[n]
    }
    pub fn fact(&self, n: usize) -> ModInt {
        self.fact[n]
    }
    pub fn ifact(&self, n: usize) -> ModInt {
        self.ifact[n]
    }
    pub fn comb(&self, n: usize, k: usize) -> ModInt {
        if k > n {
            return ModInt::zero();
        }
        self.fact[n] * self.ifact[k] * self.ifact[n - k]
    }
}
// ---------- end ModInt ----------

fn run() {
    let mut s = String::new();
    std::io::stdin().read_line(&mut s).unwrap();
    let mut it = s.trim().split_whitespace();
    let n: usize = it.next().unwrap().parse().unwrap();
    let k: usize = it.next().unwrap().parse().unwrap();
    let l: u32 = it.next().unwrap().parse().unwrap();
    let pc = Precalc::new(2 * n + 1);
    let mut dp = vec![ModInt::zero(); 2 * n + 1];
    dp[0] = ModInt::one();
    for i in 0..n {
        for j in (0..=(2 * i)).rev() {
            let p = dp[j];
            dp[j + 2] -= ModInt(2) * p;
            dp[j + 1] += ModInt(2) * p;
            dp[j] = ModInt(0);
        }
    }
    let mut ans = ModInt::zero();
    for i in (k..=n).rev() {
        let mut eval = ModInt::zero();
        for j in 0..=(2 * n) {
            eval += dp[j] * pc.inv(j + 1)
        }
        ans += pc.comb(n, i) * eval;
        let f = ModInt(2).inv();
        let mut next = vec![ModInt::zero(); 2 * n + 1];
        for j in (2..=(2 * n)).rev() {
            let v = dp[j];
            dp[j - 1] += v;
            next[j - 2] = -v * f;
        }
        dp = next;
        for j in (0..=(2 * (n - 1))).rev() {
            let v = dp[j];
            dp[j + 2] += ModInt(2) * v;
            dp[j + 1] -= ModInt(2) * v;
        }
    }
    ans *= ModInt(l);
    println!("{}", ans.0);
}

fn main() {
    run();
}


use std::io::{self, Read};

fn gcd( aa: u64, bb: u64 ) -> u64 {
    let (mut a,mut b) = if aa > bb {
        (bb,aa)
    } else {
        (aa,bb)
    };

    loop {
        let r = b % a;
        if r == 0 {
            break;
        }
        b = a;
        a = r;
    }
    a
}

fn main() -> () {

    let mut buffer = String::new();
    let stdin = io::stdin();
    let mut handle = stdin.lock();

    handle.read_to_string(&mut buffer).expect("stdin");

    let mut arr : Vec<_> = buffer.split_whitespace().map(|x| x.parse::<i64>().unwrap() ).collect();

    let a = arr[0] as u64;
    let b = arr[1] as u64;
    let mut x = arr[2] as u64;
    let mut y = arr[3] as u64;

    let d = gcd(x,y);

    // println!("d:{}",d);

    x = x / d;
    y = y / d;

    // println!("{},{}",x,y);

    let num_numer = a / x;
    let num_denom = b / y;
    use std::cmp;
    let mm = cmp::min( num_numer, num_denom );
    println!("{}",mm);
}


use std::io;

fn get_line() -> String {
	let mut input = String::new();

	io::stdin().read_line(&mut input)
		.expect("");

	String::from(input.trim())
}

fn main() {
	let s = get_line();

	let mut r = String::new();
	for (i, c) in s.chars().enumerate() {
		let d = c.to_digit(10).unwrap();

		if (i == 0 && d >= 5 && d < 9) || (i != 0 && d >= 5) {
			r.push(std::char::from_digit((9-d) as u32, 10).unwrap());
		} else {
			r.push(c);
		}
	}

	println!("{}", r);
}


struct Scan {
    buffer: std::collections::VecDeque<String>
}

impl Scan {
    fn new() -> Scan {
        Scan { buffer: std::collections::VecDeque::new() }
    }

    fn next<T: std::str::FromStr>(&mut self)-> T {
        loop {
            if let Some(token) = self.buffer.pop_front() {
                break token.parse::<T>().ok().unwrap();
            }
            let mut line = String::new();
            std::io::stdin().read_line(&mut line).expect("Fail to read");
            self.buffer = line.split_whitespace().map(String::from).collect();
        }
    }

}

fn _main() {
    let mut scan = Scan::new();
    let mut num: u64 = scan.next();
    let mut result: u64 = 0;
    let mut position: u64 = 1;
    while num/10 > 0 {
        let dig = num%10;
        result += dig.min(9-dig)*position;
        position *= 10;
        num /= 10;
    }
    if num == 9 {
        result += 9*position;
    } else {
        let dig = num%10;
        result += dig.min(9-dig)*position;
    }

    println!("{}", result);
}

fn main() {
    std::thread::Builder::new()
        .stack_size(1<<23).spawn(_main).unwrap().join().unwrap();
}


use std::io::stdin;

fn main() {
    let mut line = String::new();
    stdin().read_line(&mut line).unwrap();
    line.trim().bytes()
        .map(|value| value - '0' as u8)
        .enumerate()
        .map(|(position, value)| {
            match value {
                9 => { if position == 0 { 9 } else { 0 } }
                8 | 7 | 6 | 5 => { 9 - value }
                _ => value
            }
        })
        .for_each(|it| print!("{}", it));
    println!()
}


//! http://codeforces.com/contest/514/problem/A

#[macro_export]
macro_rules! scanln {
  ($($var:ident : $ty:path),+) => {
    $(let $var: $ty;)+
    {
      use std::io;
      let mut __buf = String::new();
      io::stdin().read_line(&mut __buf).unwrap();
      let mut eles = __buf.split_whitespace();
      $($var = Scan::scan(&mut eles);)+
    }
  }
}

pub trait Scan {
  fn scan<'a, I>(eles: &mut I) -> Self where I: Iterator<Item=&'a str>;
}

macro_rules! impl_scan_single {
  ($ty:ty) => {
    impl Scan for $ty {
      fn scan<'a, I>(eles: &mut I) -> Self where I: Iterator<Item=&'a str> {
        let next = eles.next().unwrap();
        match next.parse() {
          Ok(res) => res,
          Err(_) => panic!()
        }
      }
    }
  }
}

impl_scan_single!(u8);
impl_scan_single!(u16);
impl_scan_single!(u32);
impl_scan_single!(u64);
impl_scan_single!(usize);
impl_scan_single!(i8);
impl_scan_single!(i16);
impl_scan_single!(i32);
impl_scan_single!(i64);
impl_scan_single!(f32);
impl_scan_single!(f64);
impl_scan_single!(isize);
impl_scan_single!(String);

const __IMPL_SCAN_FOR_VEC: () = {
  use std::str::FromStr;
  impl<T> Scan for Vec<T> where T: FromStr {
    fn scan<'a, I>(eles: &mut I) -> Self where I: Iterator<Item=&'a str> {
      eles.map(|str| match str.parse() {
        Ok(res) => res,
        Err(_) => panic!()
      }).collect()
    }
  }
};

// -----------------------------------------------------------------------------

fn min_possible_invert(n: u64) -> u64 {
  if n == 0 { return 0; }
  let (top, bot) = (n / 10, n % 10);
  let inv = 9 - bot;
  if top == 0 && inv == 0 {
    bot
  } else {
    min_possible_invert(top) * 10 + std::cmp::min(bot, inv)
  }
}

fn main() {
  scanln!(x: u64);
  println!("{}", min_possible_invert(x));
}


#[allow(unused_imports)]
use std::cmp::{max,min};
#[allow(unused_imports)]
use std::collections::{HashMap,HashSet,VecDeque};

#[allow(unused_macros)]
macro_rules! readln {
    () => {{
        use std::io;

        let mut buf = String::new();
        io::stdin().read_line(&mut buf).unwrap();
        buf.trim().to_string()
    }};
    ( $t:ty ) => {{
        let input = readln!();
        input.parse::<$t>().unwrap()
    }};
    ( $( $t:ty ),+ ) => {{
        let input = readln!();
        let mut input = input.split_whitespace();
        (
            $(
                input.next().unwrap().parse::<$t>().unwrap(),
            )+
        )
    }}
}

#[allow(unused_macros)]
macro_rules! readvec {
    ( $t:ty ) => {{
        let input = readln!();
        let mut input = input.split_whitespace();
        let mut result = Vec::new();
        for elem in input {
            result.push(elem.parse::<$t>().unwrap());
        }
        result
    }}
}

fn main() {
    let s = readln!();
    let z = s.chars().enumerate().map(|(i,c)|
        if i == 0 && c == '9' {
            c
        } else {
            min(c,((9u8 - (c as u8 - '0' as u8)) + ('0' as u8)) as char)
        }).collect::<String>().chars().skip_while(|&c|c=='0').collect::<String>();
    println!("{}",if z.is_empty() { "9" } else { z.as_ref() });
}


//spnauti-rust
#[allow(unused_macros)]
macro_rules! a {
    ($c: tt, $x: expr, $y: expr) => {{
        let b = $y; let a = &mut $x;
        if b $c *a { *a = b; true } else { false }
    }};
}
use std::io::*;
use std::str::*;
use std::fmt::Debug;
struct WordReader<'a> { it : SplitAsciiWhitespace<'a>, }
#[allow(dead_code)]
impl<'a> WordReader<'a> {
    fn new<T: Read>(b: &mut String, mut r: T) -> WordReader {
        b.clear();
        r.read_to_string(b).unwrap();
        WordReader { it: b.split_ascii_whitespace() }
    }
    fn from_stdin(b: &mut String) -> WordReader {
        WordReader::new(b, stdin())
    }
    fn sl(&mut self) ->  &str { self.it.next().unwrap() }
    fn bs(&mut self) -> &[u8] { self.sl().as_bytes()    }
    fn s(&mut self) -> String { String::from(self.sl()) }
    fn i(&mut self) ->    i32 { self.p()                }
    fn p<T: FromStr>(&mut self) -> T where T::Err: Debug {
        self.sl().parse::<T>().unwrap()
    }
    fn vp<T: FromStr>(&mut self, n: usize) -> Vec<T> where T::Err: Debug {
        (0..n).map(|_| self.p()).collect()
    }
}

fn main() {
    let mut bin = String::new();
    let mut input = WordReader::from_stdin(&mut bin);

    input.bs().iter().enumerate()
        .for_each(|(i,&c)| {
            let x = if c >= b'5' {
                if i > 0 || c < b'9' {
                    b'0' + b'9' - c
                } else {
                    c
                }
            } else {
                c
            };
            print!("{}", x as char);
        });
}


use std::io;

fn main() {
    let mut s = String::new();
    io::stdin().read_line(&mut s).unwrap();
    let n : i32 = s.trim().parse().unwrap();
    s.clear();
    for _i in 0..n {
        io::stdin().read_line(&mut s).unwrap();
    }
    let a : Vec<i32> = s.split_whitespace().map(|s| s.parse().unwrap()).collect();
    let mut cnt = 0;
    for i in 0..n {
        for j in 0..n {
            if a[(i*2) as usize] == a[(j*2+1) as usize] {
                cnt += 1;
            }
        }
    }
    println!("{}", cnt);
}


use std::io;
use std::io::Stdin;
use std::str::FromStr;
use std::collections::HashSet;

fn read_line(stdin: &Stdin, line: &mut String) {
    match stdin.read_line(line) {
        Ok(_) => return,
        Err(msg) => panic!("Could not read line! Message: {}.", msg),
    }
}

fn parse_t<T: FromStr>(s: &str) -> T {
    match s.trim().parse() {
        Ok(y) => y,
        Err(_) => panic!("Could not read from string!"),
    }
}

fn read_ts<T: FromStr>(stdin: &Stdin, ts: &mut Vec<T>) {
    let mut line = String::new();
    read_line(stdin, &mut line);
    let word_iter = line.split_whitespace();
    for word in word_iter {
        let x = parse_t(word);
        ts.push(x);
    }
}

pub fn read_i64(stdin: &Stdin) -> i64 {
    let mut line = String::new();
    read_line(&stdin, &mut line);
    match line.trim().parse() {
        Ok(i) => i,
        Err(e) => {
            panic!("Could not read i64!");
        }
    }
}

struct Team {
    a: i32,
    b: i32,
}

fn main() {
    let stdin = io::stdin();
    let n = read_i64(&stdin) as usize;
    let mut k: Vec<Team> = vec![];
    for i in 0..n {
        let mut v= vec![];
        read_ts(&stdin, &mut v);
        k.push(Team { a: v[0], b: v[1] });
    }
    let mut s = 0;
    for i in 0..n {
        for j in 0..n {
            if k[i].a == k[j].b {
                s += 1;
            }
        }
    }
    println!("{}", s);
}


// {{{ by shik

use std::io;

#[allow(dead_code)]
fn gets() -> String {
    let mut s = String::new();
    io::stdin().read_line(&mut s).unwrap();
    s.trim().to_string()
}

#[allow(unused_macros)]
macro_rules! R {
    ( $ty:ty, ... ) => {
        gets().split_whitespace().map(|x| x.parse::<$ty>().unwrap()).collect::<Vec<_>>()
    };
    ( $($ty:ty),* ) => {{
        let line = gets();
        let mut it = line.split_whitespace();
        ( $(it.next().unwrap().parse::<$ty>().unwrap(),)* )
    }}
}

#[allow(unused_macros)]
macro_rules! W {
    ( $x:expr ) => {{
        println!("{}", $x);
    }};
    ( $x:expr, $($xs:expr),* ) => {{
        print!("{} ", $x);
        W!($($xs),*);
    }}
}

#[allow(unused_macros)]
macro_rules! join {
    ($x:expr, $($xs:expr),*; $sep:expr) => { concat!($x, $($sep, $xs),*) }
}

#[allow(unused_macros)]
macro_rules! dump {
    ($($x:expr),*) => {
        eprintln!(join!($(concat!(stringify!($x), " = {:?}")),*; ", "), $($x),*);
    }
}

// }}}

fn main() {

    let mut cnth = vec![0u32; 101];
    let mut cntg = vec![0u32; 101];
    let (n, ) = R!(usize);

    let mut ans = 0;
    for _ in 0..n {
        let (h, g) = R!(usize, usize);
        ans += cnth[g] + cntg[h];
        cnth[h] += 1;
        cntg[g] += 1;
    }

    println!("{}", ans);
}


use std::collections::HashMap;

fn input() -> u8 {
    let mut buf = String::new();
    std::io::stdin().read_line(&mut buf).unwrap();
    buf.trim().parse().unwrap()
}

type Pair = (u8, u8);
fn input_pair() -> Pair {
    let mut buf = String::new();
    std::io::stdin().read_line(&mut buf).unwrap();
    let buf: Vec<u8> = buf
        .trim()
        .split_whitespace()
        .map(|elem| elem.parse().unwrap())
        .collect();
    (buf[0], buf[1])
}

fn main() {
    let mut home = HashMap::new();
    let mut away = HashMap::new();

    for _ in 0..input() {
        let (h, a) = input_pair();
        home.entry(h).and_modify(|e| *e += 1).or_insert(1);
        away.entry(a).and_modify(|e| *e += 1).or_insert(1);
    }

    println!(
        "{}",
        home.iter()
            .filter(|h| away.contains_key(&h.0))
            .fold(0, |a, (k, v)| a + v * away[k])
    );
}


fn readln() -> Vec<i32> {
    let mut line = String::new();
    std::io::stdin().read_line(&mut line).unwrap();
    line.split_whitespace()
        .map(|x| x.parse().unwrap())
        .collect()
}

#[derive(PartialEq, PartialOrd)]
struct Team {
    home_uniform: i32,
    guest_uniform: i32,
}

fn main() {
    let n = readln()[0];

    let mut teams: Vec<Team> = Vec::new();

    for _ in 0..n {
        let input = readln();
        teams.push(Team {
            home_uniform: input[0],
            guest_uniform: input[1],
        })
    }

    let mut ans = 0;
    for home_team in &teams {
        for guest_team in &teams {
            if home_team != guest_team && home_team.home_uniform == guest_team.guest_uniform {
                ans += 1;
            }
        }
    }

    println!("{}", ans);
}


//spnauti-rust
struct WordReader {
    it : std::vec::IntoIter<String>,
}
#[allow(dead_code)]
impl WordReader {
    fn new<T: std::io::Read>(mut reader: T) -> WordReader {
        let mut s = String::new();
        reader.read_to_string(&mut s).unwrap();
        WordReader { it : s
            .split_ascii_whitespace()
            .map(String::from).collect::<Vec<_>>()
            .into_iter()
        }
    }
    fn from_stdin() -> WordReader {
        WordReader::new(std::io::stdin())
    }
    fn s(&mut self) -> String {
        self.it.next().unwrap()
    }
    fn ab(&mut self) -> Vec<u8> {
        self.it.next().unwrap().into_bytes()
    }
    fn i(&mut self) -> i32 {
        self.it.next().unwrap().parse().unwrap()
    }
    fn ai(&mut self, n: usize) -> Vec<i32> {
        let mut a = Vec::with_capacity(n);
        for _ in 0..n { a.push(self.i()); }
        a
    }
}

fn main() {
    let mut input = WordReader::from_stdin();
    let n = input.i() as usize;
    let mut a = Vec::with_capacity(n);
    let mut b = Vec::with_capacity(n);
    for _ in 0..n {
        a.push(input.i());
        b.push(input.i());
    }
    let sol = a.iter()
        .map(|x| b.iter().filter(|&y| x == y).count()).sum::<usize>();
    println!("{}", sol);
}


fn main() {
    let n: usize = {
        let mut buf = String::new();
        std::io::stdin().read_line(&mut buf).unwrap();
        buf.trim_end().parse().unwrap()
    };

    let v = {
        let mut v = vec![];
        for _ in 0..n {
            let mut buf = String::new();
            std::io::stdin().read_line(&mut buf).unwrap();
            let mut ws = buf.split_whitespace();
            let a: usize = ws.next().unwrap().parse().unwrap();
            let b: usize = ws.next().unwrap().parse().unwrap();
            v.push((a, b));
        }
        v
    };

    let mut ans = 0;
    for i in 0..n {
        for j in 0..n {
            if i == j {
                continue;
            }
            if v[i].0 == v[j].1 {
                ans += 1;
            }
        }
    }

    println!("{}", ans);
}


use std::io;
use std::io::Stdin;
use std::str::FromStr;

fn read_line(stdin : &Stdin, line : &mut String) {
    match stdin.read_line(line) {
        Ok(_) => return,
        Err(msg) => panic!("Could not read line! Message: {}.", msg),
    }
}

fn parse_t<T : FromStr>(s : &str) -> T {
    match s.trim().parse() {
        Ok(y) => y,
        Err(_) => panic!("Could not read from string!"),
    }
}

fn read_t<T : FromStr>(stdin : &Stdin) -> T {
    let mut line = String::new();
    read_line(stdin, &mut line);
    parse_t(&line)
}

fn read_ts<T : FromStr>(stdin : &Stdin, ts : &mut Vec<T>) {
    let mut line = String::new();
    read_line(stdin, &mut line);
    let word_iter = line.split_whitespace();
    for word in word_iter {
        let x = parse_t(word);
        ts.push(x);
    }
}

fn cols_frequency(cols : &Vec<u64>, freq : &mut Vec<(u64, u64)>) {
    let mut prev_col = cols[0];
    let mut f = 1;
    for i in 1 .. cols.len() {
        let col = cols[i];
        if col == prev_col {
            f = f + 1;
        } else {
            freq.push((prev_col, f));
            f = 1;
            prev_col = col;
        }
    }
    freq.push((prev_col, f));
}

fn host_guest(home_freq : &Vec<(u64, u64)>, away_freq : &Vec<(u64, u64)>) -> u64 {
    let home_len = home_freq.len();
    let away_len = away_freq.len();
    let mut num_clashes = 0;
    let mut i = 0;
    let mut j = 0;
    loop {
        if (i >= home_len) || (j >= away_len) {
            break;
        } else {
            let (h, f_h) = home_freq[i];
            let (a, f_a) = away_freq[j];
            if h == a {
                num_clashes = num_clashes + (f_h * f_a);
                i = i + 1;
                j = j + 1;
            } else if h > a {
                j = j + 1;
            } else {
                i = i + 1;
            }
        }
    }
    num_clashes
}

fn main() {
    let stdin = io::stdin();
    let n : u64 = read_t(&stdin);
    let mut home_cols = vec![];
    let mut away_cols = vec![];
    for _ in 0 .. n {
        let mut cols =  vec![];
        read_ts(&stdin, &mut cols);
        home_cols.push(cols[0]);
        away_cols.push(cols[1]);
    }
    home_cols.sort();
    away_cols.sort();
    let mut home_freq = vec![];
    let mut away_freq = vec![];
    cols_frequency(&home_cols, &mut home_freq);
    cols_frequency(&away_cols, &mut away_freq);
    println!("{}", host_guest(&home_freq, &away_freq));
}


fn main() {
    let v: Vec<i64> = vec![1,0,1,2,9];
    let mut ri = ReadIn::new();
    let tp = ri.int2();
    let mut ans:i64 = 1;
    for kk in 2..tp.1+1 {
        ans += cal(tp.0 as i64, kk as i64) * v[(kk as usize)] ;
    }
    println!("{}", ans)
}

fn cal(n: i64, k: i64) -> i64{
    let mut up: i64 = 1;
    let mut down: i64 = 1;
    for kk in 0..k {
        up = up * (n - kk);
        down = down * (1 + kk);
    }
    up / down
}

use std::iter::Map;
use std::str::SplitWhitespace;
use std::io::stdin;
use std::mem::forget;

pub struct ReadIn(pub String);

impl ReadIn {
    pub fn new() -> ReadIn {
        ReadIn(String::new())
    }
    fn read_i32(s: &str) -> i32 {
        s.parse().unwrap()
    }
    pub fn read_line(&mut self) {
        self.0.clear();
        forget(stdin().read_line(&mut self.0));
    }
    pub fn ints(&mut self) -> Map<SplitWhitespace, fn(&str) -> i32> {
        self.read_line();
        self.0.split_whitespace().map(ReadIn::read_i32)
    }
    pub fn int(&mut self) -> i32 {
        self.ints().next().unwrap()
    }
    pub fn int2(&mut self) -> (i32, i32) {
        let mut it = self.ints();
        (it.next().unwrap(), it.next().unwrap())
    }
}