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

// I have no idea what I'm doing

/// Copied from https://github.com/EbTech/rust-algorithms/blob/master/src/scanner.rs
/// 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: SplitAsciiWhitespace<'static>,
}

impl<R: io::BufRead> UnsafeScanner<R> {
    pub fn new(reader: R) -> Self {
        Self {
            reader,
            buf_str: vec![],
            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())
            }
        }
    }

    pub fn pair<T: str::FromStr>(&mut self) -> (T, T) {
        (self.token(), self.token())
    }
}

fn main() -> Result<(), io::Error> {
    let (stdin, stdout) = (io::stdin(), io::stdout());
    let mut scan = UnsafeScanner::new(stdin.lock());
    let mut out = BufWriter::new(stdout.lock());

    let mut x: i32 = scan.token();
    let m: i32 = scan.token();

    x %= m;

    let mut seen = vec![false; m as usize];

    while x > 0 && !seen[x as usize] {
        seen[x as usize] = true;
        x += x;
        if x >= m {
            x -= m;
        }
    }

    writeln!(out, "{}", match x {
        0 => "Yes",
        _ => "No",
    })?;

    Ok(())
}


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

// I have no idea what I'm doing

/// Copied from https://github.com/EbTech/rust-algorithms/blob/master/src/scanner.rs
/// 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: SplitAsciiWhitespace<'static>,
}

impl<R: io::BufRead> UnsafeScanner<R> {
    pub fn new(reader: R) -> Self {
        Self {
            reader,
            buf_str: vec![],
            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())
            }
        }
    }

    pub fn pair<T: str::FromStr>(&mut self) -> (T, T) {
        (self.token(), self.token())
    }
}

fn main() -> Result<(), io::Error> {
    let (stdin, stdout) = (io::stdin(), io::stdout());
    let mut scan = UnsafeScanner::new(stdin.lock());
    let mut out = BufWriter::new(stdout.lock());

    let mut x: u32 = scan.token();
    let mut m: u32 = scan.token();

    x >>= x.trailing_zeros();
    m >>= m.trailing_zeros();

    writeln!(out, "{}", if x % m == 0 { "Yes" } else { "No" })?;

    Ok(())
}


//  ____            _                  _                       _       _
// |  _ \ _   _ ___| |_    ___ _ __   | |_ ___ _ __ ___  _ __ | | __ _| |_ ___
// | |_) | | | / __| __|  / __| '_ \  | __/ _ \ '_ ` _ \| '_ \| |/ _` | __/ _ \
// |  _ <| |_| \__ \ |_  | (__| |_) | | ||  __/ | | | | | |_) | | (_| | ||  __/
// |_| \_\\__,_|___/\__|  \___| .__/___\__\___|_| |_| |_| .__/|_|\__,_|\__\___|
//                            |_| |_____|               |_|

//https://github.com/manta1130/Competitive_Programming_Template_Rust

#[macro_use]
mod input {

    use std;
    use std::io;

    const SPLIT_DELIMITER: char = ' ';

    #[macro_export]
    #[allow(unused_macros)]
    macro_rules! input {
    ( $($x:expr ),*) => {
        {
            let temp_str = input_line_str();
            let mut split_result_iter = temp_str.split_whitespace();
                $(
                let buf_split_result = split_result_iter.next();
                let buf_split_result = buf_split_result.unwrap();
                    ($x) = buf_split_result.parse().unwrap();
                )*
        }
    };
}

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

    #[allow(dead_code)]
    pub fn p<T>(t: T)
    where
        T: std::fmt::Display,
    {
        println!("{}", t);
    }

    #[allow(dead_code)]
    pub fn input_vector2d<T>(line: usize) -> Vec<Vec<T>>
    where
        T: std::str::FromStr,
    {
        let mut v: Vec<Vec<T>> = Vec::new();

        for _ in 0..line {
            let vec_line = input_vector();
            v.push(vec_line);
        }
        v
    }

    #[allow(dead_code)]
    pub fn input_vector<T>() -> Vec<T>
    where
        T: std::str::FromStr,
    {
        let mut v: Vec<T> = Vec::new();

        let s = input_line_str();
        let split_result = s.split(SPLIT_DELIMITER);
        for z in split_result {
            let buf = match z.parse() {
                Ok(r) => r,
                Err(_) => panic!("Parse Error"),
            };
            v.push(buf);
        }
        v
    }

    #[allow(dead_code)]
    pub fn input_vector_row<T>(n: usize) -> Vec<T>
    where
        T: std::str::FromStr,
    {
        let mut v = Vec::with_capacity(n);
        for _ in 0..n {
            let buf = match input_line_str().parse() {
                Ok(r) => r,
                Err(_) => panic!("Parse Error"),
            };
            v.push(buf);
        }
        v
    }

    pub trait ToCharVec {
        fn to_charvec(&self) -> Vec<char>;
    }

    impl ToCharVec for String {
        fn to_charvec(&self) -> Vec<char> {
            self.to_string().chars().collect::<Vec<_>>()
        }
    }
}

use input::*;

fn main() {
    let (n, k): (usize, u64);
    input!(n, k);
    let mut factorial = vec![1];
    for i in 1..n + 1 {
        let prev = *factorial.last().unwrap();
        factorial.push((i as u64 * prev) % k);
    }

    let mut ans = 0;
    for l in 1..n + 1 {
        ans += ((factorial[l] * factorial[n - l + 1]) % k * (n as u64 - l as u64 + 1)) % k;
        ans %= k;
    }
    p(ans);
}


// https://codeforces.com/contest/1284/problem/C
//
#![allow(unused_imports)]
use std::io::*;
use std::io::Write;
use std::fmt::*;
use std::str::*;
use std::cmp::*;
use std::collections::*;

// Input macros.
// Original by tanakh: https://qiita.com/tanakh/items/0ba42c7ca36cd29d0ac8
#[allow(unused_macros)]
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)*}
    };
}

#[allow(unused_macros)]
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)*}
    };

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

#[allow(unused_macros)]
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, [ next / $t:tt ]) => {
        {
            let len = read_value!($iter, usize);
            (0..len).map(|_| read_value!($iter, $t)).collect::<Vec<_>>()
        }
    };

    ($iter:expr, switch) => {
        {
            let ty = read_value!($iter, i32);
            if ty == 1 {
                vec![ty, read_value!($iter, i32), read_value!($iter, i32)]
            } else if ty == 2 {
                vec![ty, read_value!($iter, i32)]
            } else {
                vec![ty, read_value!($iter, i32)]
            }
        }
    };

    ($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")
    };
}

#[allow(unused_macros)]
macro_rules! read_line {
    ($t:tt) => {
        {
            let mut s = String::new();
            std::io::stdin().read_line(&mut s).unwrap();
            s.trim_right().parse::<$t>().unwrap()
        }
    }
}

#[allow(unused_macros)]
macro_rules! dvec {
    ($t:expr ; $len:expr) => {
        vec![$t; $len]
    };

    ($t:expr ; $len:expr, $($rest:expr),*) => {
        vec![dvec!($t; $($rest),*); $len]
    };
}

#[allow(unused_macros)]
macro_rules! ifv {
    ($t:expr, $a:expr, $b: expr) => {
        if $t { $a } else { $b }
    }
}

#[allow(unused_macros)]
macro_rules! fill {
    ($t:expr, $v:expr) => {
        for i in 0..$t.len() {
            $t[i] = $v;
        }
    };
}

#[allow(unused_macros)]
macro_rules! join {
    ($t:expr, $glue:expr) => {
        $t.into_iter().map(|w| w.to_string()).collect::<Vec<_>>().join($glue)
    };
}

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

// ===

fn main() {
    input! {
        n: usize, m: i64
    };
    let mut fact = vec![0i64; n+1];
    fact[0] = 1;
    for i in 1..=n {
        fact[i] = fact[i-1] * (i as i64) % m;
    }

    let mut ans = 0;
    for i in 1..=n {
        ans += (n - i + 1) as i64 * fact[i] % m * fact[n-i] % m * ((n - i + 1) as i64) % m;
        ans %= m;
    }

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


use std::io;

use std::io::Read;

use std::collections::{HashMap, HashSet};

//generate factorial modulo m
fn fac_gen(n: i64, m: i64) -> Vec<i64> {
    let it = (1..=n).scan(1, |s, x: i64| {*s = *s * x % m; Some(*s)} );
    (1..=1).chain(it).collect()
}

fn main() {
    let mut buffer = String::new();
    {
        let stdin = io::stdin();
        let mut handle = stdin.lock();
        handle.read_to_string(&mut buffer).unwrap();
    }

    let arr = buffer
        .split_whitespace()
        .map(|x| x.parse::<i64>().expect("convert to number"))
        .collect::<Vec<_>>();

    let n = arr[0];
    let m = arr[1];

    let factorials = fac_gen(n, m);

    // dbg!(&factorials);

    let ans = (1..=n)
        .map(|length| (n-length+1) * factorials[length as usize] % m * factorials[(n-length + 1) as usize] % m )
        // .inspect(|x| {dbg!(x);} )
        .fold(0i64, |acc, x| (x + acc) % m);

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


pub trait Readable {
    type Output;
    fn words_count() -> usize;
    fn read_words(words: &[&str]) -> Result<Self::Output, String>;
}
#[macro_export]
macro_rules! readable {
    ( $ t : ty , $ words_count : expr , |$ words : ident | $ read_words : expr ) => {
        impl Readable for $t {
            type Output = $t;
            fn words_count() -> usize {
                $words_count
            }
            fn read_words($words: &[&str]) -> Result<$t, String> {
                Ok($read_words)
            }
        }
    };
}
readable!((), 1, |_ss| ());
readable!(String, 1, |ss| ss[0].to_string());
impl Readable for char {
    type Output = char;
    fn words_count() -> usize {
        1
    }
    fn read_words(words: &[&str]) -> Result<char, String> {
        let chars: Vec<char> = words[0].chars().collect();
        if chars.len() == 1 {
            Ok(chars[0])
        } else {
            Err(format!("cannot parse `{}` as a char", words[0]))
        }
    }
}
pub struct Chars();
impl Readable for Chars {
    type Output = Vec<char>;
    fn words_count() -> usize {
        1
    }
    fn read_words(words: &[&str]) -> Result<Vec<char>, String> {
        Ok(words[0].chars().collect())
    }
}
macro_rules ! impl_readable_for_ints { ( $ ( $ t : ty ) * ) => { $ ( impl Readable for $ t { type Output = Self ; fn words_count ( ) -> usize { 1 } fn read_words ( words : & [ & str ] ) -> Result <$ t , String > { use std :: str :: FromStr ; <$ t >:: from_str ( words [ 0 ] ) . map_err ( | _ | { format ! ( "cannot parse `{}` as {}" , words [ 0 ] , stringify ! ( $ t ) ) } ) } } ) * } ; }
impl_readable_for_ints ! ( i8 u8 i16 u16 i32 u32 i64 u64 isize usize f32 f64 ) ;
macro_rules ! define_one_origin_int_types { ( $ new_t : ident $ int_t : ty ) => { # [ doc = " Converts 1-origin integer into 0-origin when read from stdin." ] # [ doc = "" ] # [ doc = " # Example" ] # [ doc = "" ] # [ doc = " ```no_run" ] # [ doc = " # #[macro_use] extern crate atcoder_snippets;" ] # [ doc = " # use atcoder_snippets::read::*;" ] # [ doc = " // Stdin: \"1\"" ] # [ doc = " read!(a = usize_);" ] # [ doc = " assert_eq!(a, 0);" ] # [ doc = " ```" ] # [ allow ( non_camel_case_types ) ] pub struct $ new_t ; impl Readable for $ new_t { type Output = $ int_t ; fn words_count ( ) -> usize { 1 } fn read_words ( words : & [ & str ] ) -> Result < Self :: Output , String > { <$ int_t >:: read_words ( words ) . map ( | n | n - 1 ) } } } ; ( $ new_t : ident $ int_t : ty ; $ ( $ inner_new_t : ident $ inner_int_t : ty ) ;* ) => { define_one_origin_int_types ! ( $ new_t $ int_t ) ; define_one_origin_int_types ! ( $ ( $ inner_new_t $ inner_int_t ) ;* ) ; } ; }
define_one_origin_int_types ! ( u8_ u8 ; u16_ u16 ; u32_ u32 ; u64_ u64 ; usize_ usize ) ;
macro_rules ! impl_readable_for_tuples { ( $ t : ident $ var : ident ) => ( ) ; ( $ t : ident $ var : ident ; $ ( $ inner_t : ident $ inner_var : ident ) ;* ) => { impl_readable_for_tuples ! ( $ ( $ inner_t $ inner_var ) ;* ) ; impl <$ t : Readable , $ ( $ inner_t : Readable ) ,*> Readable for ( $ t , $ ( $ inner_t ) ,* ) { type Output = ( <$ t >:: Output , $ ( <$ inner_t >:: Output ) ,* ) ; fn words_count ( ) -> usize { let mut n = <$ t >:: words_count ( ) ; $ ( n += <$ inner_t >:: words_count ( ) ; ) * n } # [ allow ( unused_assignments ) ] fn read_words ( words : & [ & str ] ) -> Result < Self :: Output , String > { let mut start = 0 ; let $ var = <$ t >:: read_words ( & words [ start .. start +<$ t >:: words_count ( ) ] ) ?; start += <$ t >:: words_count ( ) ; $ ( let $ inner_var = <$ inner_t >:: read_words ( & words [ start .. start +<$ inner_t >:: words_count ( ) ] ) ?; start += <$ inner_t >:: words_count ( ) ; ) * Ok ( ( $ var , $ ( $ inner_var ) ,* ) ) } } } ; }
impl_readable_for_tuples ! ( T8 x8 ; T7 x7 ; T6 x6 ; T5 x5 ; T4 x4 ; T3 x3 ; T2 x2 ; T1 x1 ) ;
pub trait ReadableFromLine {
    type Output;
    fn read_line(line: &str) -> Result<Self::Output, String>;
}
fn split_into_words(line: &str) -> Vec<&str> {
    #[allow(deprecated)]
    line.trim_right_matches('\n').split_whitespace().collect()
}
impl<T: Readable> ReadableFromLine for T {
    type Output = T::Output;
    fn read_line(line: &str) -> Result<T::Output, String> {
        let words = split_into_words(line);
        if words.len() != T::words_count() {
            return Err(format!(
                "line `{}` has {} words, expected {}",
                line,
                words.len(),
                T::words_count()
            ));
        }
        T::read_words(&words)
    }
}
macro_rules ! impl_readable_from_line_for_tuples_with_from_iterator { ( $ u : ident : $ ( + $ bound : path ) * => $ seq_in : ty , $ seq_out : ty ; $ t : ident $ var : ident ) => { impl <$ u : Readable > ReadableFromLine for $ seq_in where <$ u as Readable >:: Output : Sized $ ( + $ bound ) * { type Output = $ seq_out ; fn read_line ( line : & str ) -> Result <$ seq_out , String > { let n = $ u :: words_count ( ) ; let words = split_into_words ( line ) ; if words . len ( ) % n != 0 { return Err ( format ! ( "line `{}` has {} words, expected multiple of {}" , line , words . len ( ) , n ) ) ; } let mut result = Vec :: new ( ) ; for chunk in words . chunks ( n ) { match $ u :: read_words ( chunk ) { Ok ( v ) => result . push ( v ) , Err ( msg ) => { let flagment_msg = if n == 1 { format ! ( "word {}" , result . len ( ) ) } else { let l = result . len ( ) ; format ! ( "words {}-{}" , n * l + 1 , ( n + 1 ) * l ) } ; return Err ( format ! ( "{} of line `{}`: {}" , flagment_msg , line , msg ) ) ; } } } Ok ( result . into_iter ( ) . collect ( ) ) } } impl < T : Readable , $ u : Readable > ReadableFromLine for ( T , $ seq_in ) where <$ u as Readable >:: Output : Sized $ ( + $ bound ) * { type Output = ( T :: Output , $ seq_out ) ; fn read_line ( line : & str ) -> Result < Self :: Output , String > { let n = T :: words_count ( ) ; # [ allow ( deprecated ) ] let trimmed = line . trim_right_matches ( '\n' ) ; let words_and_rest : Vec <& str > = trimmed . splitn ( n + 1 , ' ' ) . collect ( ) ; if words_and_rest . len ( ) < n { return Err ( format ! ( "line `{}` has {} words, expected at least {}" , line , words_and_rest . len ( ) , n ) ) ; } let words = & words_and_rest [ .. n ] ; let empty_str = "" ; let rest = words_and_rest . get ( n ) . unwrap_or ( & empty_str ) ; Ok ( ( T :: read_words ( words ) ?, <$ seq_in >:: read_line ( rest ) ? ) ) } } } ; ( $ u : ident : $ ( + $ bound : path ) * => $ seq_in : ty , $ seq_out : ty ; $ t : ident $ var : ident , $ ( $ inner_t : ident $ inner_var : ident ) ,+ ) => { impl_readable_from_line_for_tuples_with_from_iterator ! ( $ u : $ ( + $ bound ) * => $ seq_in , $ seq_out ; $ ( $ inner_t $ inner_var ) ,+ ) ; impl <$ t : Readable , $ ( $ inner_t : Readable ) ,+ , $ u : Readable > ReadableFromLine for ( $ t , $ ( $ inner_t ) ,+ , $ seq_in ) where <$ u as Readable >:: Output : Sized $ ( + $ bound ) * { type Output = ( $ t :: Output , $ ( $ inner_t :: Output ) ,+ , $ seq_out ) ; fn read_line ( line : & str ) -> Result < Self :: Output , String > { let mut n = $ t :: words_count ( ) ; $ ( n += $ inner_t :: words_count ( ) ; ) + # [ allow ( deprecated ) ] let trimmed = line . trim_right_matches ( '\n' ) ; let words_and_rest : Vec <& str > = trimmed . splitn ( n + 1 , ' ' ) . collect ( ) ; if words_and_rest . len ( ) < n { return Err ( format ! ( "line `{}` has {} words, expected at least {}" , line , words_and_rest . len ( ) , n ) ) ; } let words = & words_and_rest [ .. n ] ; let empty_str = "" ; let rest = words_and_rest . get ( n ) . unwrap_or ( & empty_str ) ; let ( $ var , $ ( $ inner_var ) ,* ) = < ( $ t , $ ( $ inner_t ) ,+ ) >:: read_words ( words ) ?; Ok ( ( $ var , $ ( $ inner_var ) ,* , <$ seq_in >:: read_line ( rest ) ? ) ) } } } ; }
#[macro_export]
macro_rules ! readable_collection { ( $ u : ident => $ collection_in : ty , $ collection_out : ty ) => { impl_readable_from_line_for_tuples_with_from_iterator ! ( $ u : => $ collection_in , $ collection_out ; T8 x8 , T7 x7 , T6 x6 , T5 x5 , T4 x4 , T3 x3 , T2 x2 , T1 x1 ) ; } ; ( $ u : ident : $ ( $ bound : path ) ,* => $ collection_in : ty , $ collection_out : ty ) => { impl_readable_from_line_for_tuples_with_from_iterator ! ( $ u : $ ( + $ bound ) * => $ collection_in , $ collection_out ; T8 x8 , T7 x7 , T6 x6 , T5 x5 , T4 x4 , T3 x3 , T2 x2 , T1 x1 ) ; } }
readable_collection ! ( U => Vec < U >, Vec < U :: Output > ) ;
readable_collection ! ( U => std :: collections :: VecDeque < U >, std :: collections :: VecDeque < U :: Output > ) ;
readable_collection ! ( U : Eq , std :: hash :: Hash => std :: collections :: HashSet < U >, std :: collections :: HashSet < U :: Output > ) ;
readable_collection ! ( U : Ord => std :: collections :: BTreeSet < U >, std :: collections :: BTreeSet < U :: Output > ) ;
readable_collection ! ( U : Ord => std :: collections :: BinaryHeap < U >, std :: collections :: BinaryHeap < U :: Output > ) ;
pub fn read<T: ReadableFromLine>() -> T::Output {
    let mut line = String::new();
    std::io::stdin().read_line(&mut line).unwrap();
    T::read_line(&line).unwrap()
}
#[macro_export]
macro_rules ! read { ( ) => { let mut line = String :: new ( ) ; std :: io :: stdin ( ) . read_line ( & mut line ) . unwrap ( ) ; } ; ( $ pat : pat = $ t : ty ) => { let $ pat = read ::<$ t > ( ) ; } ; ( $ ( $ pat : pat = $ t : ty ) ,+ ) => { read ! ( ( $ ( $ pat ) ,* ) = ( $ ( $ t ) ,* ) ) ; } ; }
#[macro_export]
macro_rules ! readls { ( $ ( $ pat : pat = $ t : ty ) ,+ ) => { $ ( read ! ( $ pat = $ t ) ; ) * } ; }
pub fn readx<T: ReadableFromLine>() -> Vec<T::Output> {
    use std::io::{self, BufRead};
    let stdin = io::stdin();
    let result = stdin
        .lock()
        .lines()
        .map(|line_result| {
            let line = line_result.expect("read from stdin failed");
            T::read_line(&line).unwrap()
        })
        .collect();
    result
}
#[macro_export]
macro_rules ! readx_loop { ( |$ pat : pat = $ t : ty | $ body : expr ) => { { use std :: io :: BufRead ; let stdin = std :: io :: stdin ( ) ; for line in stdin . lock ( ) . lines ( ) { let line = line . expect ( "read from stdin failed" ) ; let $ pat = <$ t >:: read_line ( & line ) . unwrap ( ) ; $ body } } } ; ( |$ ( $ pat : pat = $ t : ty ) ,*| $ body : expr ) => { readx_loop ! ( | ( $ ( $ pat ) ,* ) = ( $ ( $ t ) ,* ) | $ body ) ; } ; }
pub fn readn<T: ReadableFromLine>(n: usize) -> Vec<T::Output> {
    use std::io::{self, BufRead};
    let stdin = io::stdin();
    let result: Vec<T::Output> = stdin
        .lock()
        .lines()
        .take(n)
        .map(|line_result| {
            let line = line_result.expect("read from stdin failed");
            T::read_line(&line).unwrap()
        })
        .collect();
    if result.len() < n {
        panic!(
            "expected reading {} lines, but only {} lines are read",
            n,
            result.len()
        );
    }
    result
}
#[macro_export]
macro_rules ! readn_loop { ( $ n : expr , |$ pat : pat = $ t : ty | $ body : expr ) => { { use std :: io :: BufRead ; let stdin = std :: io :: stdin ( ) ; let mut lock = stdin . lock ( ) ; for _ in 0 ..$ n { let mut line = String :: new ( ) ; lock . read_line ( & mut line ) . expect ( "read from stdin failed" ) ; let $ pat = <$ t >:: read_line ( & line ) . unwrap ( ) ; $ body } } } ; ( $ n : expr , |$ ( $ pat : pat = $ t : ty ) ,*| $ body : expr ) => { readn_loop ! ( $ n , | ( $ ( $ pat ) ,* ) = ( $ ( $ t ) ,* ) | $ body ) ; } ; }
pub trait Words {
    fn read<T: Readable>(&self) -> T::Output;
}
impl<'a> Words for [&'a str] {
    fn read<T: Readable>(&self) -> T::Output {
        T::read_words(self).unwrap()
    }
}
impl<'a> Words for &'a str {
    fn read<T: Readable>(&self) -> T::Output {
        T::read_words(&[self]).unwrap()
    }
}

#[derive(Clone)]
pub struct HashCounter<T: Eq + std::hash::Hash> {
    counter: std::collections::HashMap<T, usize>,
}
pub struct HashCounterIter<'a, T: 'a> {
    iter: std::collections::hash_map::Iter<'a, T, usize>,
}
impl<'a, T> Iterator for HashCounterIter<'a, T> {
    type Item = (&'a T, usize);
    fn next(&mut self) -> Option<(&'a T, usize)> {
        while let Some((key, &count)) = self.iter.next() {
            if count > 0 {
                return Some((key, count));
            }
        }
        None
    }
}
pub struct HashCounterIntoIter<T> {
    iter: std::collections::hash_map::IntoIter<T, usize>,
}
impl<'a, T> Iterator for HashCounterIntoIter<T> {
    type Item = (T, usize);
    fn next(&mut self) -> Option<(T, usize)> {
        while let Some((key, count)) = self.iter.next() {
            if count > 0 {
                return Some((key, count));
            }
        }
        None
    }
}
pub struct HashCounterValues<'a, T: 'a> {
    iter: std::collections::hash_map::Values<'a, T, usize>,
}
impl<'a, T> Iterator for HashCounterValues<'a, T> {
    type Item = usize;
    fn next(&mut self) -> Option<usize> {
        while let Some(&n) = self.iter.next() {
            if n > 0 {
                return Some(n);
            }
        }
        None
    }
}
impl<T: Eq + std::hash::Hash> HashCounter<T> {
    pub fn new() -> HashCounter<T> {
        HashCounter {
            counter: std::collections::HashMap::new(),
        }
    }
    pub fn with_capacity(capacity: usize) -> HashCounter<T> {
        HashCounter {
            counter: std::collections::HashMap::with_capacity(capacity),
        }
    }
    pub fn values(&self) -> HashCounterValues<T> {
        HashCounterValues {
            iter: self.counter.values(),
        }
    }
    pub fn iter(&self) -> HashCounterIter<T> {
        HashCounterIter {
            iter: self.counter.iter(),
        }
    }
}
static HASH_COUNTER_ZERO: usize = 0;
impl<'a, T, Q: ?Sized> std::ops::Index<&'a Q> for HashCounter<T>
where
    T: Eq + std::hash::Hash + std::borrow::Borrow<Q>,
    Q: Eq + std::hash::Hash,
{
    type Output = usize;
    fn index(&self, key: &Q) -> &usize {
        self.counter.get(key).unwrap_or(&HASH_COUNTER_ZERO)
    }
}
impl<'a, T, Q: ?Sized> std::ops::IndexMut<&'a Q> for HashCounter<T>
where
    T: Eq + std::hash::Hash + std::borrow::Borrow<Q>,
    Q: Eq + std::hash::Hash + std::borrow::ToOwned<Owned = T>,
{
    fn index_mut(&mut self, key: &Q) -> &mut usize {
        self.counter.entry(key.to_owned()).or_insert(0)
    }
}
impl<T: std::hash::Hash + Eq> std::iter::FromIterator<T> for HashCounter<T> {
    fn from_iter<I>(iter: I) -> HashCounter<T>
    where
        I: IntoIterator<Item = T>,
    {
        let mut counter = HashCounter::new();
        for item in iter {
            *counter.counter.entry(item).or_insert(0) += 1;
        }
        counter
    }
}
impl<T: std::hash::Hash + Eq> std::iter::IntoIterator for HashCounter<T> {
    type Item = (T, usize);
    type IntoIter = HashCounterIntoIter<T>;
    fn into_iter(self) -> HashCounterIntoIter<T> {
        HashCounterIntoIter {
            iter: self.counter.into_iter(),
        }
    }
}
#[macro_export]
macro_rules ! hash_counter { ( $ ( $ item : expr ) ,* ) => { { let mut counter = HashCounter :: new ( ) ; $ ( counter [ &$ item ] += 1 ; ) * counter } } }

#[macro_export]
#[cfg(local)]
macro_rules! dbg {
    ( ) => {{
        use std::io::{self, Write};
        writeln!(io::stderr(), "{}: dbg", line!()).unwrap();
    }};
    ( $ e : expr ) => {{
        use std::io::{self, Write};
        let result = $e;
        writeln!(
            io::stderr(),
            "{}: {} = {:?}",
            line!(),
            stringify!($e),
            result
        )
            .unwrap();
        result
    }};
}
#[macro_export]
#[cfg(not(local))]
macro_rules! dbg {
    ( ) => {};
    ( $ e : expr ) => {
        $e
    };
}

use std::cmp;

fn main() {
    read!(query_count = usize);
    for _ in 0..query_count {
        read!(_ = usize, _ = usize, d = usize);
        read!(aa = Vec<usize_>);
        let mut l = 0;
        let mut r = d;
        let mut counter: HashCounter<usize> = aa[l..r].iter().cloned().collect();
        let mut cnt = counter.iter().count();
        let mut ans = cnt;
        dbg!((l, r, cnt));
        while r < aa.len() {
            if counter[&aa[l]] == 1 {
                cnt -= 1;
            }
            counter[&aa[l]] -= 1;
            l += 1;

            if counter[&aa[r]] == 0 {
                cnt += 1;
            }
            counter[&aa[r]] += 1;
            r += 1;

            ans = cmp::min(ans, cnt);
            dbg!((l, r, cnt));
        }
        println!("{}", ans);
    }
}


use std::str::FromStr;
use std::io;
use std::fs::File;
use std::io::BufReader;
use std::io::BufRead;
use std::collections::HashMap;
use std::cmp;

struct Reader {
    index: usize,
    items: Vec::<String>,
    reader: Box<io::BufRead>
}

impl Reader {
    fn read<T: FromStr>(&mut self) -> T {
        if self.index >= self.items.len() {
            let mut buffer = String::new();
            self.reader.read_line(&mut buffer).expect("Error reading new line");
            self.items = buffer.split_ascii_whitespace().map(|x| x.to_string()).collect();
            self.index = 0;
        }

        let result = self.items[self.index].parse::<T>();
        self.index += 1;
        return match result {
            Ok(value) => value,
            Err(_) => {
                panic!("Error reading next value");
            }
        }
    }

    fn read_vec<T: FromStr>(&mut self) -> Vec::<T> {
        let mut buffer = String::new();
        self.reader.read_line(&mut buffer).expect("Error reading new line");
        buffer.split_ascii_whitespace().map(|x| match x.parse::<T>() {
            Ok(v) => v,
            Err(_) => {
                panic!("Error reading next value")
            }
        }).collect()
    }

    fn new(from_file: bool) -> Reader {
        Reader {
            index: 0,
            items: Vec::with_capacity(0),
            reader: if from_file {
                Box::new(BufReader::new(File::open("./././src/input.txt").unwrap()))
            }
            else {
                Box::new(BufReader::new(io::stdin()))
            }
        }
    }
}

fn main() {
    let mut reader = Reader::new(false);

    let mut q: i32 = reader.read();
    while q > 0 {
        q -= 1;

        let n: i32 = reader.read();
        let k: i32 = reader.read();
        let d: i32 = reader.read();
        let serials: Vec::<i32> = reader.read_vec();
        let mut asnwer = std::i32::MAX;
        let mut i = 0;
        while i + d <= n {
            let mut j = 0;
            let mut used: HashMap::<i32, bool> = HashMap::new();
            let mut curr = 0;
            while j < d {
                let next = serials[(i + j) as usize];
                if !used.contains_key(&next) {
                    curr += 1;
                }
                used.entry(next).or_insert(true);

                j += 1;
            }

            asnwer = cmp::min(asnwer, curr);
            i += 1;
        }

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


use std::io;

fn read_uint() -> usize {
    let mut input_line = String::new();
    io::stdin().read_line(&mut input_line).unwrap();
    input_line.trim().parse::<usize>().unwrap()
}

fn read_uvec() -> Vec<usize> {
    let mut input_line = String::new();
    io::stdin().read_line(&mut input_line).unwrap();
    input_line.trim().split(" ").map(|x| x.parse::<usize>().unwrap()).collect::<Vec<_>>()
}

fn main() {
    let t = read_uint();
    for _ in 0..t {
        let nkd = read_uvec();
        let n = nkd[0];
        let k = nkd[1];
        let d = nkd[2];
        let x = read_uvec().iter().map( |it| it - 1 ).collect::<Vec<usize>>();
        let mut c = vec!(0; k);
        let mut r = k;
        let mut s = 0;
        for it in 0..n {
            if c[ x[it] ] == 0 { s += 1 }
            c[ x[it] ] += 1;
            if it >= d {
                c[ x[ it-d ] ] -= 1;
                if c[ x[ it-d ] ] == 0 { s-= 1 }
            }
            if it >= d-1 {
                if s < r { r = s }
            }
        }
        println!("{}", r )
    }
}


use std::io::stdin;
use std::collections::HashMap;

macro_rules! readln {
        () => {{ let mut line = String::new(); stdin().read_line(&mut line).unwrap(); line }};
        ($type:ty) => {{ readln!().split_whitespace().next().unwrap().parse::<$type>().unwrap() }};
        (|$type_vec:ty|) => {{ readln!().split_whitespace().map(|it| it.parse().unwrap()).collect::<Vec<$type_vec>>() }};
        ($($type:ty),*) => {{ let line = readln!(); let mut iter = line.split_whitespace(); ($(iter.next().unwrap().parse::<$type>().unwrap(),)*) }};
        ($($type:ty),*, |$type_vec:ty|) => {{ let line = readln!(); let mut iter = line.split_whitespace();
            ($(iter.next().unwrap().parse::<$type>().unwrap(),)*iter.map(|it| it.parse().unwrap()).collect::<Vec<$type_vec>>(),)}};
}

fn main() {
    let t = readln!(usize);
    for _ in 0..t {
        let (n, k, d) = readln!(usize, usize, usize);
        let a = readln!(|usize|);

        let mut count = HashMap::with_capacity(k);

        for i in 0..d {
            *count.entry(a[i]).or_insert(0usize) += 1;
        }

        let mut size = count.len();
        let mut min_size = size;
        for i in d..n {
            let x = count.entry(a[i - d]).or_insert(0);
            *x -= 1;
            if *x == 0 {
                size -= 1;
            }

            let y = count.entry(a[i]).or_insert(0);
            *y += 1;
            if *y == 1 {
                size += 1;
            }
            min_size = min_size.min(size);
        }
        println!("{}", min_size);
    }
}


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

use std::cmp::*;
use std::collections::*;
use std::ops::*;

macro_rules! eprint {
	($($t:tt)*) => {{
		use ::std::io::Write;
		let _ = write!(::std::io::stderr(), $($t)*);
	}};
}
macro_rules! eprintln {
	() => { eprintln!(""); };
	($($t:tt)*) => {{
		use ::std::io::Write;
		let _ = writeln!(::std::io::stderr(), $($t)*);
	}};
}
macro_rules! dbg {
	($v:expr) => {{
		let val = $v;
		eprintln!("[{}:{}] {} = {:?}", file!(), line!(), stringify!($v), val);
		val
	}}
}

macro_rules! mat {
	($($e:expr),*) => { Vec::from(vec![$($e),*]) };
	($($e:expr,)*) => { Vec::from(vec![$($e),*]) };
	($e:expr; $d:expr) => { Vec::from(vec![$e; $d]) };
	($e:expr; $d:expr $(; $ds:expr)+) => { Vec::from(vec![mat![$e $(; $ds)*]; $d]) };
}

macro_rules! ok {
	($a:ident$([$i:expr])*.$f:ident()$(@$t:ident)*) => {
		$a$([$i])*.$f($($t),*)
	};
	($a:ident$([$i:expr])*.$f:ident($e:expr$(,$es:expr)*)$(@$t:ident)*) => { {
		let t = $e;
		ok!($a$([$i])*.$f($($es),*)$(@$t)*@t)
	} };
}

pub fn readln() -> String {
	let mut line = String::new();
	::std::io::stdin().read_line(&mut line).unwrap_or_else(|e| panic!("{}", e));
	line
}

macro_rules! read {
	($($t:tt),*; $n:expr) => {{
		let stdin = ::std::io::stdin();
		let ret = ::std::io::BufRead::lines(stdin.lock()).take($n).map(|line| {
			let line = line.unwrap();
			let mut it = line.split_whitespace();
			_read!(it; $($t),*)
		}).collect::<Vec<_>>();
		ret
	}};
	($($t:tt),*) => {{
		let line = readln();
		let mut it = line.split_whitespace();
		_read!(it; $($t),*)
	}};
}

macro_rules! _read {
	($it:ident; [char]) => {
		_read!($it; String).chars().collect::<Vec<_>>()
	};
	($it:ident; [u8]) => {
		Vec::from(_read!($it; String).into_bytes())
	};
	($it:ident; usize1) => {
		$it.next().unwrap_or_else(|| panic!("input mismatch")).parse::<usize>().unwrap_or_else(|e| panic!("{}", e)) - 1
	};
	($it:ident; [usize1]) => {
		$it.map(|s| s.parse::<usize>().unwrap_or_else(|e| panic!("{}", e)) - 1).collect::<Vec<_>>()
	};
	($it:ident; [$t:ty]) => {
		$it.map(|s| s.parse::<$t>().unwrap_or_else(|e| panic!("{}", e))).collect::<Vec<_>>()
	};
	($it:ident; $t:ty) => {
		$it.next().unwrap_or_else(|| panic!("input mismatch")).parse::<$t>().unwrap_or_else(|e| panic!("{}", e))
	};
	($it:ident; $($t:tt),+) => {
		($(_read!($it; $t)),*)
	};
}

pub fn main() {
	let _ = ::std::thread::Builder::new().name("run".to_string()).stack_size(32 * 1024 * 1024).spawn(run).unwrap().join();
}

const MOD: u32 = 1_000_000_007;

fn solve() {
	let t = read!(usize);
	for i in 0..t {
		let (n,k,d) = read!(usize,usize,usize);
		let a = read!([usize]);
		let mut ans = n;
		let mut sum = 0;
		let mut v = vec![0;k+1];
		for i in 0..n {
			if i < d {
				if v[a[i]]==0 {sum+=1;}
				v[a[i]]+=1;
				continue;
			}
			ans = min(ans, sum);
			v[a[i-d]]-=1;
			if v[a[i-d]]==0 {sum-=1;}
			v[a[i]]+=1;
			if v[a[i]]==1 {sum+=1;}
			ans = min(ans, sum);
		}
		ans = min(ans, sum);
		println!("{}", ans);
	}
}

fn run() {
    solve();
}


use std::collections::BTreeSet;
fn main() {
    let mut ri = ReadIn::new();
    let tp = ri.int2();
    let n = tp.0 as usize;
    let m = tp.1;
    let mut it = ri.ints();
    let mut num = Vec::new();
    for _ in 0..n {
        num.push(it.next().unwrap());
    }
    if n == 1 {
        println!("{}", num[0] % m);
        return ;
    }
    let fst = num[0..n/2].to_vec();
    let snd = num[n/2..n].to_vec();
    let s1 = explore(fst,m);
    let s2 = explore(snd,m);
    let mut it3 = s1.iter();
    let mut it4 = s2.iter();
    let x = it3.next_back().unwrap();
    let y = it4.next_back().unwrap();
    let mut ans = (*x + *y) % m;
    let mut it1 = s1.iter();
    loop {
        match it1.next() {
            Some(v1) => {
                match s2.range(0..m-v1).next_back() {
                    Some(v2) => {
                        if v1 + v2 > ans {
                            ans = v1 + v2;
                        }
                    },
                    None => continue,
                }
            },
            None => break,
        }
    }
    println!("{}", ans);
}

fn explore(v:Vec<i32>, m:i32) -> BTreeSet<i32> {
    let n = v.len();
    let mut st = BTreeSet::new();
    for msk in 0..1<<n {
        let mut s = 0;
        for i in 0..n {
            if (msk & (1<<i)) > 0 {
                s = (s + v[i]) % m;
            }
        }
        st.insert(s);
    }
    st
}

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())
    }
}


//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 enumerate(a: &[u32], m: u32) -> Vec<u32> {
    let mut ans = vec![0];
    for &a in a.iter() {
        let mut next = ans.clone();
        for v in ans {
            next.push((v + a) % m);
        }
        ans = next;
    }
    ans.sort();
    ans.dedup();
    ans
}

fn run() {
    input! {
        n: usize,
        m: u32,
        a: [u32; n],
    }
    let mid = n / 2;
    let (l, r) = a.split_at(mid);
    let l = enumerate(l, m);
    let r = enumerate(r, m);
    let mut ans = (*l.last().unwrap() + *r.last().unwrap()) % m;
    let mut j = 0;
    for l in l.iter().rev() {
        while j + 1 < r.len() && *l + r[j + 1] < m {
            j += 1;
        }
        ans = std::cmp::max(ans, (*l + r[j]) % m);
    }
    println!("{}", ans);
}

fn main() {
    run();
}


#[allow(unused_imports)]
use std::cmp::{max, min, Ordering};
#[allow(unused_imports)]
use std::collections::{HashMap, HashSet, BinaryHeap};
#[allow(unused_imports)]
use std::iter::FromIterator;
#[allow(unused_imports)]
use std::io::stdin;

mod util {
    use std::io::stdin;
    use std::str::FromStr;
    use std::fmt::Debug;

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

    #[allow(dead_code)]
    pub fn gets<T: FromStr>() -> Vec<T>
    where
        <T as FromStr>::Err: Debug,
    {
        let mut line: String = String::new();
        stdin().read_line(&mut line).unwrap();
        line.split_whitespace()
            .map(|t| t.parse().unwrap())
            .collect()
    }
}

#[allow(unused_macros)]
macro_rules! get {
    ($t:ty) => {
        {
            let mut line: String = String::new();
            stdin().read_line(&mut line).unwrap();
            line.trim().parse::<$t>().unwrap()
        }
    };
    ($($t:ty),*) => {
        {
            let mut line: String = String::new();
            stdin().read_line(&mut line).unwrap();
            let mut iter = line.split_whitespace();
            (
                $(iter.next().unwrap().parse::<$t>().unwrap(),)*
            )
        }
    };
    ($t:ty; $n:expr) => {
        (0..$n).map(|_|
                    get!($t)
                   ).collect::<Vec<_>>()
    };
    ($($t:ty),*; $n:expr) => {
        (0..$n).map(|_|
                    get!($($t),*)
                   ).collect::<Vec<_>>()
    };
    ($t:ty ;;) => {
        {
            let mut line: String = String::new();
            stdin().read_line(&mut line).unwrap();
            line.split_whitespace()
                .map(|t| t.parse::<$t>().unwrap())
                .collect::<Vec<_>>()
        }
    };
}

#[allow(unused_macros)]
macro_rules! debug {
    ($($a:expr),*) => {
        println!(concat!($(stringify!($a), " = {:?}, "),*), $($a),*);
    }
}

fn combs(s: &[u64]) -> Vec<u64> {
    let mut res = HashSet::new();
    res.insert(0);

    for &x in s {
        let copy = res.clone();
        for &y in &copy {
            res.insert(x + y);
        }
    }

    let mut v = res.iter().cloned().collect::<Vec<_>>();
    v.sort();
    v
}

fn bsearch(t: u64, s: &[u64]) -> u64 {
    match s.binary_search(&t) {
        Ok(i) => s[i],
        Err(i) => {
            let mut i = i;
            if i >= s.len() {
                return s.last().cloned().unwrap();
            }
            while i > 0 && s[i] > t {
                i -= 1;
            }
            s[i]
        }
    }
}

fn main() {
    let (n, m) = get!(usize, u64);
    let s: Vec<u64> = get!(u64;;).into_iter().map(|x| x % m).collect();

    let v1 = combs(&s[..n / 2]);
    let v2 = combs(&s[n / 2..]);

    let ans = (1..40)
        .map(|i| {
            v1.iter()
                .map(|&x| (x + bsearch(i * m - x - 1, &v2)) % m)
                .max()
                .unwrap()
        })
        .max()
        .unwrap();

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


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

fn main() -> io::Result<()> {
    let mut buf = String::new();
    io::stdin().read_to_string(&mut buf)?;
    let v: Vec<u32> = buf
        .split_ascii_whitespace()
        .map(|x| x.parse().unwrap())
        .collect();
    let (k, mut l) = (v[0], v[1]);

    let mut ans = -1;
    while l % k == 0 {
        l /= k;
        ans += 1;
    }

    if l == 1 {
        println!("YES");
        println!("{}", ans);
    } else {
        println!("NO");
    }

    Ok(())
}


fn main() {
    let (k, l): (u64, u64);
    inputm!(k);
    inputm!(l);
    let mut cnt = 0;
    let mut buf = k;
    while buf < l {
        cnt += 1;
        buf *= k;
    }
    if buf == l {
        println!("YES");
        println!("{}", cnt);
    } else {
        println!("NO");
    }
}

pub mod input {
    use std::io;
    const SPLIT_DELIMITER: char = ' ';

    #[macro_export]
    #[allow(unused_macros)]
    macro_rules! inputm {
    ( $($x:expr ),*) => {
        {
            let temp_str = input_line_str();
            let mut split_result_iter = temp_str.split_whitespace();
                $(
                let buf_split_result = split_result_iter.next();
                let buf_split_result = buf_split_result.unwrap();
                    ($x) = buf_split_result.parse().unwrap();
                )*
        }
    };
}

    pub fn input_line_str() -> String {
        let mut s = String::new();
        io::stdin().read_line(&mut s).unwrap();
        s.trim().to_string()
    }

    pub fn input_vector2d<T>(line: usize) -> Vec<Vec<T>>
    where
        T: std::str::FromStr,
    {
        let mut v: Vec<Vec<T>> = Vec::new();

        for _ in 0..line {
            let vec_line = input_vector();
            v.push(vec_line);
        }
        v
    }

    #[allow(clippy::match_wild_err_arm)]
    pub fn input_vector<T>() -> Vec<T>
    where
        T: std::str::FromStr,
    {
        let mut v: Vec<T> = Vec::new();

        let s = input_line_str();
        let split_result = s.split(SPLIT_DELIMITER);
        for z in split_result {
            let buf = match z.parse() {
                Ok(r) => r,
                Err(_) => panic!("Parse Error",),
            };
            v.push(buf);
        }
        v
    }

    #[allow(clippy::match_wild_err_arm)]
    pub fn input_vector_row<T>(n: usize) -> Vec<T>
    where
        T: std::str::FromStr,
    {
        let mut v = Vec::with_capacity(n);
        for _ in 0..n {
            let buf = match input_line_str().parse() {
                Ok(r) => r,
                Err(_) => panic!("Parse Error",),
            };
            v.push(buf);
        }
        v
    }

    pub trait ToCharVec {
        fn to_charvec(&self) -> Vec<char>;
    }

    impl ToCharVec for String {
        fn to_charvec(&self) -> Vec<char> {
            self.to_string().chars().collect::<Vec<_>>()
        }
    }
}
use input::*;


use std::io::{self, Stdin};
use std::str::{self, FromStr};
use std::error::Error;

fn exec() {
    let mut sc = Scanner::new();
    let n: usize = sc.ne();
    let _: String = sc.ne();
    let hoge: String = sc.ne();
    if hoge == "week" {
        let ans = match n {
            val if val == 5 || val == 6 => 53,
            _ => 52,
        };
        println!("{}", ans);
    } else {
        let ans = match n {
            val if val <= 29 => 12,
            val if val == 30 => 11,
            _ => 7,
        };
        println!("{}", ans);
    }
}

fn main() {
    const STACK: usize = 16 * 1024 * 1024;
    let _ = std::thread::Builder::new()
        .stack_size(STACK)
        .spawn(|| { exec(); })
        .unwrap()
        .join()
        .unwrap();
}

#[allow(dead_code)]
struct Scanner {
    stdin: Stdin,
    id: usize,
    buf: Vec<u8>,
}

#[allow(dead_code)]
impl Scanner {
    fn new() -> Scanner {
        Scanner {
            stdin: io::stdin(),
            id: 0,
            buf: Vec::new(),
        }
    }
    fn next_line(&mut self) -> Option<String> {
        let mut res = String::new();
        match self.stdin.read_line(&mut res) {
            Ok(0) => None,
            Ok(_) => Some(res),
            Err(why) => panic!("error in read_line: {}", why.description()),
        }
    }
    fn next<T: FromStr>(&mut self) -> Option<T> {
        while self.buf.len() == 0 {
            self.buf = match self.next_line() {
                Some(r) => {
                    self.id = 0;
                    r.trim().as_bytes().to_owned()
                }
                None => return None,
            };
        }
        let l = self.id;
        assert!(self.buf[l] != b' ');
        let n = self.buf.len();
        let mut r = l;
        while r < n && self.buf[r] != b' ' {
            r += 1;
        }
        let res = match str::from_utf8(&self.buf[l..r]).ok().unwrap().parse::<T>() {
            Ok(s) => Some(s),
            Err(_) => {
                panic!("parse error, {:?}",
                       String::from_utf8(self.buf[l..r].to_owned()))
            }
        };
        while r < n && self.buf[r] == b' ' {
            r += 1;
        }
        if r == n {
            self.buf.clear();
        } else {
            self.id = r;
        }
        res
    }
    fn ne<T: FromStr>(&mut self) -> T {
        self.next::<T>().unwrap()
    }
}


//spnauti-rusT
use std::io::*;
use std::str::{self,*};
use std::fmt::Debug;
#[allow(unused_imports)] use std::cmp::Ordering::{self,*};
#[allow(unused_imports)] use std::ops::{self,*};
#[allow(unused_imports)] use std::iter::{self,*};
#[allow(unused_imports)] use std::collections::*;
#[allow(unused_macros)]
macro_rules! m {
    ($c:tt, $x:expr, $y:expr) => {{
        let b = $y; let a = &mut $x;
        if b $c *a { *a = b; true } else { false }
    }};
}
#[allow(unused_macros)]
macro_rules! l {
    ($($v:ident),* = $i:ident.$f:ident $a:tt) => {
        $( let $v = $i.$f$a; )*
    };
    ($($v:ident),*:$t:ty = $i:ident.$f:ident $a:tt) => {
        $( let $v:$t = $i.$f$a; )*
    };
}
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).ok();
        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 f(&mut self) ->    f64 { self.p()                }
    fn u(&mut self) ->  usize { self.p()                }
    fn sk(&mut self, n: usize) { self.it.nth(n - 1); }
    fn ii(&mut self, n: usize) -> impl Iterator<Item=i32> {
        self.ip(n).into_iter()
    }
    fn vi(&mut self, n: usize) -> Vec<i32> {
        self.vp::<i32>(n)
    }
    fn p<T: FromStr>(&mut self) -> T where T::Err: Debug {
        self.sl().parse::<T>().unwrap()
    }
    fn ip<T: FromStr>(&mut self, n: usize) -> impl Iterator<Item=T> where T::Err: Debug {
        self.vp(n).into_iter()
    }
    fn vp<T: FromStr>(&mut self, n: usize) -> Vec<T> where T::Err: Debug {
        (0..n).map(|_| self.p()).collect()
    }
}
//------------------- End rusT

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

    let n = input.i();
    input.sk(1);
    if input.bs()[0] == b'm' {
        println!("{}", if n <= 29 {12} else if n <= 30 {11} else {7});
    } else {
        println!("{}", if n == 5 || n == 6 {53} else {52});
    }
}


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

fn main() -> () {
    let mut buffer = String::new();
    let stdin = io::stdin();
    let mut handle = stdin.lock();

    handle.read_to_string(&mut buffer).unwrap();

    let mut arr = buffer.split_whitespace().take(1).map(|x| x.parse::<i32>().unwrap() ).collect::<Vec<_>>();
    let n = arr[0] as usize;
    let mut num = buffer.split_whitespace().skip(1).take(1).next().unwrap();
    let mut b = vec![];
    for i in num.chars() {
        let digit = i as u32 - '0' as u32;
        b.push(digit);
    }
    let s : u32 = b.iter().sum();

    if s == 0 {
        println!("YES");
        return
    }

    'outer: for i in 1..s+1 {
        if s % i == 0 {
            let ss = s / i;
            let mut segsum = 0;
            let mut count_seg = 0;
            for j in 0..n {
                segsum += b[j];
                if segsum == ss {
                    segsum = 0;
                    count_seg += 1;
                } else if segsum > ss {
                    continue 'outer;
                }
            }
            if count_seg > 1 {
                println!("YES");
                return
            }
        }
    }

    println!("NO");
}


use std::io;

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(),
            )+
        )
    }}
}

fn can_be_splitted(slice : &[i32], sum : i32) -> bool {
    let mut curr_sum = 0;
    let mut index = 0;
    let mut at_least_one = false;
    loop {
        if index >= slice.len() {
            return at_least_one && curr_sum == 0;
        }

        curr_sum += slice[index];
        if curr_sum == sum {
            curr_sum = 0;
            at_least_one = true;
        } else if curr_sum > sum {
            return false;
        }
        index += 1;
    }

    true
}

fn solve(length : usize, digits : Vec<i32>) -> (bool, i32) {
    let mut curr_sum = 0;
    for index in 0..(length - 1) {
        curr_sum += digits[index];
        if can_be_splitted(&digits[(index + 1)..], curr_sum) {
            return (true, curr_sum);
        }
    }
    (false, 0)
}

fn main() {
    let length = readln!(usize);

    let digits = readln!();
    let digits : Vec<i32> = digits.chars().map(|ch| ch.to_digit(10).unwrap() as i32).collect();

    let (result, sum) = solve(length, digits);

    println!("{}", if result { "YES" } else { "NO" });
}


use std::io;

fn main() {
    let mut input_text = String::new();
    io::stdin()
        .read_line(&mut input_text)
        .expect("failed to read from stdin");

    let trimmed = input_text.trim();
    let mut no_of_digits: u32 = 0;
    match trimmed.parse::<u32>() {
        Ok(i) => no_of_digits = i,
        Err(..) => println!("this was not an integer: {}", trimmed),
    };

    let mut input_digits = String::new();
 	io::stdin()
        .read_line(&mut input_digits)
        .expect("failed to read from stdin");
    let digits = input_digits.trim();

   	let mut answer : bool = false;
   	let total_sum: u32 = digits.chars().map(|x| x.to_digit(10).unwrap()).sum();
    for i in 1..total_sum {
        let mut sum: u32 = 0;
    	for c in digits.chars() {
			let current_digit = c.to_digit(10).unwrap();
			sum += current_digit;
			if sum == i {
				sum = 0;
			}
    	}
    	if sum == 0 {
    		answer = true;
    	}
    }
    if answer || total_sum == 0 {
    	println!("YES");
    } else {
    	println!("NO");
    }
}


use std::io;
use std::slice::Iter;
use std::iter::Peekable;

fn check_step(iter : &mut Peekable<Iter<u64>>, check_sum : u64) -> Option<bool> {
    if iter.len() == 0 { return None }
    let mut sum = 0;
    while let Some(x) = iter.next() {
        sum += x;
        if sum == check_sum {
            while iter.peek().map(|x| **x == 0).unwrap_or(false) {
                iter.next();
            }
            return Some(true)
        }
    }
    Some(false)
}

fn check(iter : Iter<u64>, check_sum : u64) -> bool {
    if iter.len() == 0 { return false }
    let mut iter = iter.peekable();
    while let Some(flag) = check_step(&mut iter, check_sum) {
        if !flag {
            return false
        }
    }
    true
}

fn main() {
    let n = {
        let mut buffer = String::new();
        io::stdin().read_line(&mut buffer).unwrap();
        buffer.trim().parse().unwrap()
    };
    let nums : Vec<u64> = {
        let mut buffer = String::with_capacity(n);
        let mut char_str = String::from("0");
        io::stdin().read_line(&mut buffer).unwrap();
        buffer
        .trim()
        .chars()
        .map(|x| {
            char_str.pop();
            char_str.push(x);
            char_str.trim().parse().unwrap()
        })
        .collect()
    };
    let mut iter = nums.iter();
    let mut sum = 0;
    let mut sum_rest : u64 = nums.iter().fold(0, |acc, x| acc + x);
    while let Some(x) = iter.next() {
        sum_rest -= x;
        sum += x;
        if sum_rest.checked_rem(sum).map(|x| x == 0).unwrap_or_else(|| sum == sum_rest) {
            if check(iter.clone(), sum) {
                println!("YES");
                return
            }
        }
    }
    println!("NO");
}


use std::io;

fn can_eat_row(r: &Vec<bool>) -> bool {
  for i in 0..r.len() {
    if !r[i] { return false }
  }
  true
}

fn can_eat_col(m: &Vec<Vec<bool>>, j: usize) -> bool {
  for r in m {
    if !r[j] { return false }
  }
  true
}

fn main() {
  let mut s = String::new();
  io::stdin().read_line(&mut s).unwrap();
  let a: Vec<i32> = s.split_whitespace()
    .map(|x| x.parse().unwrap())
    .collect();

  let r = a[0];
  let c = a[1];

  let mut v: Vec<Vec<bool>> = vec![];

  for _ in 0..r {
    let mut s = String::new();
    io::stdin().read_line(&mut s).unwrap();
    v.push(s.trim().chars()
      .map(|x| x == '.')
      .collect()
    );
  }

  let mut eatable_rows = vec![];
  for i in 0..r as usize {
    if can_eat_row(&v[i]) { eatable_rows.push(i); }
  }

  let mut eatable_cols = vec![];
  for j in 0..c as usize {
    if can_eat_col(&v, j) { eatable_cols.push(j); }
  }

  let er = eatable_rows.len() as i32;
  let ec = eatable_cols.len() as i32;

  if er == 0 {
    println!("{}", ec*r);
  } else if ec == 0 {
    println!("{}", er*c);
  } else {
    println!("{}", er*c + ec*(r-er));
  }
}


use std::io;

fn poisonous_row(r: &Vec<bool>) -> bool {
  for i in 0..r.len() {
    if !r[i] { return true }
  }
  false
}

fn poisonous_col(m: &Vec<Vec<bool>>, j: usize) -> bool {
  for r in m {
    if !r[j] { return true }
  }
  false
}

fn main() {
  let mut s = String::new();
  io::stdin().read_line(&mut s).unwrap();
  let a: Vec<i32> = s.split_whitespace()
    .map(|x| x.parse().unwrap())
    .collect();

  let r = a[0];
  let c = a[1];

  let mut v: Vec<Vec<bool>> = vec![];

  for _ in 0..r {
    let mut s = String::new();
    io::stdin().read_line(&mut s).unwrap();
    v.push(s.trim().chars()
      .map(|x| x == '.')
      .collect()
    );
  }

  let mut poisonous_rows = 0;
  let mut poisonous_cols = 0;
  for i in 0..r as usize {
    if poisonous_row(&v[i]) { poisonous_rows += 1; }
  }
  for j in 0..c as usize {
    if poisonous_col(&v, j) { poisonous_cols += 1; }
  }

  println!("{}", r*c - poisonous_rows*poisonous_cols);
}


#[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")
    };
}

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: i64,
        m: i64,
    }
    if m % n != 0 {
        puts!("-1\n");
        return;
    }
    let mut x = m / n;
    let mut c = 0;
    while x % 2 == 0 {
        x /= 2;
        c += 1;
    }
    while x % 3 == 0 {
        x /= 3;
        c += 1;
    }
    if x != 1 {
        puts!("-1\n");
    } else {
        puts!("{}\n", c);
    }
}

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();
}


/*
«Игра 23» — вот во что сейчас играет Поликарп. ;
Изначально у него есть целое число n и его цель преобразовать его в целое число m.
За один ход он может умножить n на 2 или умножить n на 3. Он может совершать любое количество ходов.

Выведите количество ходов, сколько необходимо Поликарпу, чтобы получить из числа n число m.
Выведите -1, если это невозможно сделать.
*/

use std::io::{BufRead, Write, BufReader, BufWriter};
const MULTIPLE_TESTS: bool = false;

fn task(n: u32, m: u32) -> i32 {
    let mut mult: u32 = m / n;
    if mult * n != m { return -1; }

    let mut steps = 0;
    while mult % 2 == 0 {
        steps += 1;
        mult /= 2;
    }
    while mult % 3 == 0 {
        steps += 1;
        mult /= 3;
    }
    if mult == 1 { steps } else { -1 }
}

fn main() -> std::io::Result<()> {
    let stdin = std::io::stdin();
    let stdout = std::io::stdout();
    let reader = BufReader::new(stdin.lock());
    let mut writer = BufWriter::new(stdout.lock());

    let mut lines = reader.lines();
    let n_tests: i32 = if MULTIPLE_TESTS {
        lines.next().unwrap().map(|s| s.parse::<i32>())?.unwrap()
    } else { 1 };

    for i in 0..n_tests {
        // read arguments
        let line = lines.next().unwrap()?;
        let args = line.split_whitespace().map(|s| s.parse::<u32>().unwrap()).collect::<Vec<_>>();
        // run test
        let result = task(args[0], args[1]);
        writeln!(writer, "{}", result)?;
    }

    Ok(())
}


macro_rules! parse_line {
    ($t: ty) => ({
        let mut a_str = String::new();
        std::io::stdin().read_line(&mut a_str).expect("read error");
        let a_str = a_str.trim();
        a_str.parse::<$t>().expect("parse error")
    });
    ($($t: ty),+) => ({
        let mut a_str = String::new();
        std::io::stdin().read_line(&mut a_str).expect("read error");
        let mut a_iter = a_str.split_whitespace();
        (
            $(
            a_iter.next().unwrap().parse::<$t>().expect("parse error"),
            )+
        )
    })
}

#[allow(unused_macros)]
macro_rules! parse_line_to_vec {
    ($t: ty) => {{
        let mut a_str = String::new();
        std::io::stdin().read_line(&mut a_str).expect("read error");
        (a_str
            .split_whitespace()
            .map(|x| x.parse::<$t>().unwrap())
            .collect::<Vec<$t>>())
    }};
}

use std::io::Write;

fn solve(writer: &mut std::io::BufWriter<std::io::Stdout>) {
    let (n, m) = parse_line!(u32, u32);
    if m % n != 0 {
        writeln!(writer, "-1").unwrap();
        return;
    }
    let mut q = m / n;
    let mut result = 0;
    while q % 2 == 0 {
        q /= 2;
        result += 1;
    }
    while q % 3 == 0 {
        q /= 3;
        result += 1;
    }
    if q != 1 {
        writeln!(writer, "-1").unwrap();
    }else{
        writeln!(writer, "{}", result).unwrap();
    }
}

fn main() {
    let mut writer = std::io::BufWriter::new(std::io::stdout());
    let tests = 1; // parse_line!(usize);
    for _ in 0..tests {
        solve(&mut writer);
    }
}


use std::io::stdin;

fn get_min_transform_move_num(n: usize, m: usize) -> Option<usize> {
    if (m % n) != 0 {
        return None;
    }
    let mut value: usize = m / n;
    let mut step_num: usize = 0;
    while value > 1 {
        if (value % 3) == 0 {
            value /= 3;
            step_num += 1;
        } else if (value % 2) == 0 {
            value /= 2;
            step_num += 1;
        } else {
            return None;
        }
    }
    return Some(step_num);
}

#[cfg(test)]
mod test {
    use super::get_min_transform_move_num;

    #[test]
    fn test1() {
        assert_eq!(get_min_transform_move_num(120, 51840), Some(7));
    }
    #[test]
    fn test2() {
        assert_eq!(get_min_transform_move_num(42, 42), Some(0));
    }
    #[test]
    fn test3() {
        assert_eq!(get_min_transform_move_num(48, 72), None);
    }
}

fn read_data() -> (usize, usize) {
    let mut data_str: String = String::new();
    stdin().read_line(&mut data_str).unwrap();
    let data_str_values: Vec<usize> = data_str
        .trim()
        .split(" ")
        .map(|s| s.parse::<usize>().unwrap())
        .collect();

    return (data_str_values[0], data_str_values[1]);
}

fn main() {
    let (n, m): (usize, usize) = read_data();

    let result: Option<usize> = get_min_transform_move_num(n, m);

    match result {
        Some(x) => println!("{}", x),
        None => println!("-1"),
    };
}


//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 u(&mut self) ->  usize { self.p()                }
    fn vi(&mut self, n: usize) -> Vec<i32> {
        self.vp::<i32>(n)
    }
    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);

    let a = input.i();
    let b = input.i();
    let sol = if b % a > 0 {
        -1
    } else {
        let mut c = b / a;
        let mut sol = 0;
        for i in 2..4 {
            while c % i == 0 {
                c /= i;
                sol += 1;
            }
        }
        if c == 1 {
            sol
        } else {
            -1
        }
    };
    println!("{}", sol);
}


//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: u64,
        m: u64,
    }
    let mut x = m / n;
    let mut ans = 0;
    while x % 2 == 0 {
        x /= 2;
        ans += 1;
    }
    while x % 3 == 0 {
        x /= 3;
        ans += 1;
    }
    if m % n != 0 || x > 1 {
        println!("-1");
    } else {
        println!("{}", ans);
    }
}

fn main() {
    run();
}


use std::io;

fn main() {
  let stdin = io::stdin();

  let mut ln = String::new();
  stdin.read_line(&mut ln).unwrap();
  let mut iter = ln.split_whitespace();
  let mut n:u32 = iter.next().unwrap().parse().unwrap();
  let m:u32 = iter.next().unwrap().parse().unwrap();

  let mut count = 0;
  while m % (n * 2) == 0 {
    n *= 2;
    count += 1;
  }
  while m % (n * 3) == 0 {
    n *= 3;
    count += 1;
  }
  if n != m {
    count = -1;
  }
  println!("{}", count);
}


#![allow(dead_code, clippy::many_single_char_names, unused_variables, non_snake_case, unused_macros, unused_imports, non_upper_case_globals)]
use std::{
    collections::*,
    io::{stdin, StdinLock, stdout, StdoutLock, BufReader, BufRead, BufWriter, Write},
    mem::swap
};

fn parse<T: std::str::FromStr>(n: &str) -> T {
    match n.parse::<T>() {
        Ok(x) => x,
        _ => panic!()
    }
}

macro_rules! fill {
    ($r: expr, str, $($x: ident),+) => { fill!($r, str, 30, $($x),+) };
    ($r: expr, $t: ty, $($x: ident),+) => { fill!($r, $t, 30, $($x),+) };
    ($r: expr, str, $c: expr, $($x: ident),+) => {
        let t = read!($r, $c);
        let mut t = t.split(' ');

        $(
            $x = t.next().unwrap();
        )+
    };
    ($r: expr, $t: ty, $c: expr, $($x: ident),+) => {
        let t = read!($r, $c);
        let mut t = t.split(' ').map(parse::<$t>);

        $(
            $x = t.next().unwrap();
        )+
    }
}

macro_rules! read {
    ($r: expr) => { read!($r, 20) };
    ($r: expr, str) => { read!($r, 20) };
    ($r: expr, $t: ty) => { parse::<$t>(&read!($r, 20)) };
    ($r: expr, str, $c: expr) => { read!($r, $c) };
    ($r: expr, $t: ty, $c: expr) => { parse::<$t>(&read!($r, $c)) };
    ($r: expr, $c: expr) => {
        {
            let mut s = String::with_capacity($c+2);
            $r.read_line(&mut s).unwrap();

            assert!(s.len() <= $c+2);

            if s.ends_with('\n') {
                s.pop();
                if s.ends_with('\r') {
                    s.pop();
                }
            }
            s
        }
    }
}

macro_rules! read_vec {
    ($r: expr) => { read_vec!($r, str, 10_000) };
    ($r: expr, str) => { read_vec!($r, str, 10_000) };
    ($r: expr, $t: ty) => { read_vec!($r, $t, 10_000) };
    ($r: expr, $c: expr) => { read_vec!($r, str, $c) };
    ($r: expr, str, $c: expr) => {
        {
            let v = read!($r, $c).split(' ').collect::<Vec<_>>();
            assert!(v.len() <= $c); // $c is upper bound of string
            v
        }
    };
    ($r: expr, $t: ty, $c: expr) => {
        {
            let v = read!($r, $c).split(' ').map(parse::<$t>).collect::<Vec<_>>();
            assert!(v.len() <= $c);
            v
        }
    };
}

fn main() {
    let r = stdin();
    let mut r = BufReader::with_capacity(10000, r.lock());

    let w = stdout();
    let mut w = BufWriter::with_capacity(10000, w.lock());
    unsafe { solve(&mut r, &mut w); }
}

const M: usize = std::usize::MAX;

unsafe fn solve(r: &mut BufReader<StdinLock>, w: &mut BufWriter<StdoutLock>) {
    let (a, b);
    fill!(r, usize, 19, a, b);

    if b%a != 0 {
        writeln!(w, "-1").unwrap();
    } else {
        let m = b/a;
        let tz = m.trailing_zeros();
        let mut m = m>>tz;

        let mut i = 0;
        while m != 1 {
            if m%3 != 0 {
                write!(w, "-1").unwrap();
                return;
            }
            m /= 3;
            i += 1;
        }

        write!(w, "{}", tz+i).unwrap();
    }
}


fn run() {
    let mut s = String::new();
    std::io::stdin().read_line(&mut s).unwrap();
    let mut it = s.trim().split_whitespace();
    let n: u64 = it.next().unwrap().parse().unwrap();
    let k: u64 = it.next().unwrap().parse().unwrap();
    let ans = n / k * k + k;
    println!("{}", ans);
}

fn main() {
    run();
}


use std::io;
use std::iter;
use std::cmp;

fn main() {
    let (a, b): (f64, f64) = {
        let mut input = String::new();
        io::stdin().read_line(&mut input).unwrap();
        let mut it = input.split_whitespace().map(|k| k.parse().unwrap());
        (
            it.next().unwrap(),
            it.next().unwrap(),
            )
    };

    let n1 = a.sqrt().floor() - 1.0;

    let delta = 1.0 + 4.0 * b;
    let n2 = (delta.sqrt() - 1.0) / 2.0;
    let n2 = n2.floor();

    if n1 < n2 {
        println!("Vladik");
    } else {
        println!("Valera");
    }
}


mod max_flow {
    use std;
    type F = i32;
    pub const INF: F = 1000;
    const ZERO: F = 0;
    fn non_zero(f: F) -> bool {
        f > ZERO
    }
    fn min(a: F, b: F) -> F {
        if a < b {
            a
        } else {
            b
        }
    }
    pub struct Graph {
        n: usize,
        depth: Vec<usize>,
        it: Vec<usize>,
        g: Vec<Vec<(usize, F, usize)>>,
    }
    impl Graph {
        pub fn new(n: usize) -> Graph {
            Graph {
                n: n,
                depth: vec![n + 1; n],
                it: vec![0; n],
                g: vec![vec![]; n],
            }
        }
        pub fn add_edge(&mut self, s: usize, t: usize, f: F) {
            let x = self.g[s].len();
            let y = self.g[t].len();
            self.g[s].push((t, f, y));
            self.g[t].push((s, ZERO, x));
        }
        fn bfs(&mut self, src: usize, dst: usize) {
            let g = &self.g;
            let n = self.n;
            let dp = &mut self.depth;
            dp.clear();
            dp.resize(n, n + 1);
            dp[src] = 0;
            let mut q = std::collections::VecDeque::new();
            q.push_back(src);
            'outer: while let Some(v) = q.pop_front() {
                for &(u, f, _) in g[v].iter() {
                    if dp[u] > dp[v] + 1 && non_zero(f) {
                        dp[u] = dp[v] + 1;
                        if u == dst {
                            break 'outer;
                        }
                        q.push_back(u);
                    }
                }
            }
        }
        fn dfs(&mut self, v: usize, src: usize, f: F) -> F {
            if v == src {
                return f;
            }
            while self.it[v] < self.g[v].len() {
                let (u, _, inv) = self.g[v][self.it[v]];
                if self.depth[u] < self.depth[v] && non_zero(self.g[u][inv].1) {
                    let capa = min(f, self.g[u][inv].1);
                    let c = self.dfs(u, src, capa);
                    if non_zero(c) {
                        self.g[v][self.it[v]].1 += c;
                        self.g[u][inv].1 -= c;
                        return c;
                    }
                }
                self.it[v] += 1;
            }
            ZERO
        }
        pub fn flow(&mut self, src: usize, dst: usize) -> F {
            let mut ans = ZERO;
            loop {
                self.bfs(src, dst);
                if self.depth[dst] > self.n {
                    break;
                }
                self.it.clear();
                self.it.resize(self.n, 0);
                loop {
                    let f = self.dfs(dst, src, INF);
                    if non_zero(f) {
                        ans += f;
                    } else {
                        break;
                    }
                }
            }
            ans
        }
    }
}

fn diff(a: usize, b: usize) -> usize {
    std::cmp::max(a, b) - std::cmp::min(a, b)
}

#[allow(dead_code)]
fn test() {
    let n = 25;
    for h in 1..=n {
        print!("{:>2}: ", h);
        for w in 1..=n {
            let mut g = max_flow::Graph::new(h * w + 2);
            let src = h * w + 1;
            let dst = src - 1;
            for i in 0..h {
                for j in 0..w {
                    if (i + j) & 1 == 0 {
                        g.add_edge(src, i * w + j, 1);
                        for k in 0..h {
                            for l in 0..w {
                                if diff(i, k) + diff(j, l) == 3 {
                                    g.add_edge(i * w + j, k * w + l, 1);
                                }
                            }
                        }
                    } else {
                        g.add_edge(i * w + j, dst, 1);
                    }
                }
            }
            let ans = g.flow(src, dst) * 2;
            let c = if ans as usize == h * w { ' ' } else { '!' };
            print!("{:>4}{}", ans, c);
        }
        println!();
    }
}

fn run() {
    let mut s = String::new();
    std::io::stdin().read_line(&mut s).unwrap();
    let mut it = s.trim().split_whitespace();
    let mut h: usize = it.next().unwrap().parse().unwrap();
    let mut w: usize = it.next().unwrap().parse().unwrap();
    if h > w {
        std::mem::swap(&mut h, &mut w);
    }
    if h * w <= 100 {
        let mut g = max_flow::Graph::new(h * w + 2);
        let src = h * w + 1;
        let dst = src - 1;
        for i in 0..h {
            for j in 0..w {
                if (i + j) & 1 == 0 {
                    g.add_edge(src, i * w + j, 1);
                    for k in 0..h {
                        for l in 0..w {
                            if diff(i, k) + diff(j, l) == 3 {
                                g.add_edge(i * w + j, k * w + l, 1);
                            }
                        }
                    }
                } else {
                    g.add_edge(i * w + j, dst, 1);
                }
            }
        }
        let ans = g.flow(src, dst) * 2;
        println!("{}", ans);
    } else if h == 1 {
        let mut ans = w / 6 * 6;
        if w % 6 >= 4 {
            ans += 2;
        }
        if w % 6 >= 5 {
            ans += 2;
        }
        println!("{}", ans);
    } else if h % 2 == 1 && w % 2 == 1 {
        let ans = h as u64 * w as u64 - 1;
        println!("{}", ans);
    } else {
        let ans = h as u64 * w as u64;
        println!("{}", ans);
    }
}

fn main() {
//    test();
    run();
}


fn solution(s: String, n: i32) -> i32 {
  let mut chars = s.trim().as_bytes().iter().cloned().map (|x| x - 96u8).collect::<Vec<u8>>();
  chars.sort();
  let mut iter = chars.iter().peekable();
  let mut not_found = false;
  let mut prev_char = *iter.next().unwrap() as i32;
  let mut sum = prev_char.clone() as i32;
  let mut m = n;
  loop {
    if m < 2 {
      break;
    }
    if iter.peek().is_none() {
      not_found = true;
      break;
    }

    let a = *iter.next().unwrap() as i32;
    if a - prev_char < 2 {
      continue;
    }
    sum += a.clone() as i32;
    prev_char = a;
    m-=1;
  }
  if not_found {-1} else {sum}
}

fn main() {
  assert_eq!(29,solution(String::from("xyabd"),3));
  assert_eq!(34,solution(String::from("problem"),4));
  assert_eq!(-1,solution(String::from("ab"),2));
  assert_eq!(1,solution(String::from("abaabbaaabbb"),1));

  let mut r = String::new();
  std::io::stdin().read_line(&mut r).unwrap();
  let mut ns = r.split_whitespace().map(|x| x.parse::<i32>().unwrap());
  ns.next().unwrap();
  let n  = ns.next().unwrap();
  let mut s = String::new();
  std::io::stdin().read_line(&mut s).unwrap();
  println!("{}",solution(s,n));
}


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

fn main() {
    let mut buf = String::new();
    stdin().read_to_string(&mut buf).unwrap();
    let mut tok = buf.split_whitespace();
    let mut get = || tok.next().unwrap();
    macro_rules! get {
        ($t:ty) => (get().parse::<$t>().unwrap());
        () => (get!(usize));
    }

    let _n = get!();
    let k = get!();
    let s = get().as_bytes();
    let mut xs = vec![false; 30];
    for &ch in s {
        xs[ch as usize - b'a' as usize] = true;
    }
    let xs: Vec<_> = xs
        .into_iter()
        .enumerate()
        .filter(|(_, v)| *v)
        .collect();

    if k * 2 > 26 || xs.len() < k {
        println!("-1");
        return;
    }

    let mut ans = 0;
    let mut b = 27;
    let mut c = 0;
    for (i, _) in xs.iter() {
        let i = *i;
        if b + 1 != i {
            ans += i + 1;
            b = i;
            c += 1;
            if c >= k {
                break;
            }
        }
    }
    if c < k {
        println!("-1");
    } else {
        println!("{}", ans);
    }

}


#![allow(dead_code)]
#![allow(unused_imports)]
#![allow(unused_macros)]
#![allow(overflowing_literals)]
#![allow(unused_must_use)]
#![allow(non_camel_case_types)]

use std::collections::*;
use std::io::*;
use std::cmp::{max, min, Ordering};
use std::f64::consts::*;
use std::mem::{swap, size_of_val, size_of};
use std::fs::File;
use std::rc::*;
use std::ascii::*;
use std::ops::*;
use std::num::*;
use std::process::*;
//use std::ptr::*;
use std::iter::{once, repeat};

const INF: i32 = std::i32::MAX;
const LINF: i64 = std::i64::MAX;
const MOD: usize = 1000000007;

struct Input<Buf: BufRead> {
	buffer: Buf,
}

impl<Buf: BufRead> Input<Buf> {
	fn read_char(&mut self) -> char {
		let mut x = [255u8];
		self.buffer.read(&mut x).expect("EOF");
		x[0] as char
	}
	fn read_line(&mut self) -> String {
		let mut v = Vec::new();
		let mut x = [255u8];
		self.buffer.read(&mut x).expect("EOF");
		while x[0] < b' ' && x[0] != 255u8 {
			x[0] = 255u8;
			self.buffer.read(&mut x).expect("EOF");
		}
		while x[0] >= b' ' && x[0] != 255u8 {
			v.push(x[0]);
			x[0] = 255u8;
			self.buffer.read(&mut x).expect("EOF");
		}
		String::from_utf8(v).unwrap()
	}

	fn read_word(&mut self) -> String {
		let mut v = Vec::new();
		let mut x = [255u8];
		self.buffer.read(&mut x).expect("EOF");
		while x[0] <= b' ' && x[0] != 255u8 {
			x[0] = 255u8;
			self.buffer.read(&mut x).expect("EOF");
		}
		while x[0] > b' ' && x[0] != 255u8 {
			v.push(x[0]);
			x[0] = 255u8;
			self.buffer.read(&mut x).expect("EOF");
		}
		String::from_utf8(v).unwrap()
	}
}

macro_rules! read {
    () => {};
	($inf:ident, $t:ty) => ($inf.read_word().parse::<$t>().expect("Parsing error"));
	($inf:ident, $($t:ty),*) => (($($inf.read_word().parse::<$t>().expect("Parsing error")),*));
}
fn gcd<T>(mut a: T, mut b: T) -> T
	where T: ShrAssign + BitAnd<Output=T> + Ord + From<u8> + Clone + SubAssign + ShlAssign<usize> + Copy
{
	let one = T::from(1);
	let zero = T::from(0);
	let mut ans = 0;
	if a < b {
		swap(&mut a, &mut b);
	}
	while b > zero {
		if (a & one > zero) && (b & one > zero) {
			a -= b;
		} else if a & one > zero {
			b >>= one;
		} else if b & one > zero {
			a >>= one;
		} else {
			ans += 1;
			a >>= one;
			b >>= one;
		}
		if a < b {
			swap(&mut a, &mut b);
		}
	}
	a <<= ans;
	a
}

fn powmod<X, Y>(mut base: X, mut exp: Y, mm: X) -> X
	where X: Copy + Clone + Mul<Output=X> + Rem<Output=X> + From<u8>,
	      Y: ShrAssign + Copy + Clone + BitAnd<Output=Y> + From<u8> + Ord
{
	let mut res = X::from(1);
	while exp > Y::from(0) {
		if exp & Y::from(1) > Y::from(0) {
			res = res * base % mm;
		}
		base = base * base % mm;
		exp >>= Y::from(1);
	}
	res
}

fn main() {
	match std::env::var("home") {
		Ok(_x) => {
			let mut inf = Input { buffer: BufReader::new(File::open("input.txt").expect("File not found")) };
			let stdout = stdout();
			let ostr = stdout.lock();
			let mut ouf = BufWriter::new(ostr);
			solve(&mut inf, &mut ouf);
		}
		Err(_e) => {
			let stdin = stdin();
			let istr = stdin.lock();
			let mut inf = Input { buffer: BufReader::new(istr) };
			let stdout = stdout();
			let ostr = stdout.lock();
			let mut ouf = BufWriter::new(ostr);
			solve(&mut inf, &mut ouf);
		}
	}
}

fn solve<Inner: BufRead, Output: Write>(inf: &mut Input<Inner>, ouf: &mut Output) {
	let n = read!(inf,usize);
	let mut s1 = 0;
	let mut s2 = 0;
	for _i in 0..n {
		let a = read!(inf,i32);
		if a < 0 {
			s2 += a;
		} else {
			s1 += a;
		}
	}
	writeln!(ouf, "{}", s1 - s2);
}


// Try Codeforces
// author: Leonardone @ NEETSDKASU

fn main() {
    let mut stdin = String::new();
    std::io::Read::read_to_string(
        &mut std::io::stdin(),
        &mut stdin).unwrap();
    let mut stdin = stdin.split_whitespace();
    let mut get = || stdin.next().unwrap();
    macro_rules! get {
        () => (get().parse::<i64>().unwrap());
    }
    let n = get!();
    let mut ans = 0;
    for _ in 0..n {
        let a = get!();
        if a > 0 {
            ans += a;
        } else {
            ans -= a;
        }
    }
    println!("{}", ans);
}


use std::cmp;
use std::io;
use std::str::SplitWhitespace;

fn main() {
    let size = read_size();

    let mut v: Vec<i32> = vec![0; size as usize];

    let array_str = read_line();
    let mut iter = array_str.split_whitespace();

    for i in 0..size {
        v[i as usize] = read_split(&mut iter);
    }

    v.sort();

    let mut total = 0;
    for el in v.iter() {
        total += *el;
    }

    let mut answer = total;
    let mut neg = 0;

    for el in v.iter() {
        total -= *el;
        neg += *el;
        answer = cmp::max(answer, total - neg);
    }

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

fn read_size() -> i32 {
    let size_str = read_line();
    let mut iter = size_str.split_whitespace();
    read_split(&mut iter)
}

fn read_split(iter: &mut SplitWhitespace) -> i32 {
    iter.next().unwrap_or("-1").parse::<i32>().unwrap_or(-1)
}

fn read_line() -> String {
    let mut first_line = String::new();
    io::stdin()
        .read_line(&mut first_line)
        .expect("stdin read error");
    first_line
}


mod solution {
  use std::io::{self, Write, BufRead};

  pub fn solve() {
    let stdin = io::stdin();
    let mut iterator = stdin.lock().lines();
    iterator.next(); // Throw away first input
    let nums: Vec<i32> = iterator.next().unwrap().unwrap()
      .split(" ")
      .into_iter()
      .map(|str_num| {
        let num: i32 = str_num.trim().parse().unwrap();
        num.abs() // Absolute value b/c -(-) -> (+)
      })
      .collect();
    let result: i32 = nums.iter().sum();
    io::stdout().write(&result.to_string().as_bytes()).unwrap();
  }
}

fn main() {
  solution::solve();
}


use std::io;

fn main() {
  let mut buffer = String::new();
  io::stdin().read_line(&mut buffer).unwrap();
  buffer.clear();
  io::stdin().read_line(&mut buffer).unwrap();
  let ans = buffer.split_whitespace()
                  .map(|x| i16::abs(x.trim().parse::<i16>().unwrap()))
                  .sum::<i16>();
  println!("{}", ans);
}


use std::io;

fn read_line() -> String {
    let mut input_line = String::new();
    io::stdin().read_line(&mut input_line).unwrap();
    return String::from(input_line.trim());
}

fn digits(mut n: u64) -> u64 {
    let mut count = 0u64;
    while n > 0 {
        count += 1;
        n /= 10;
    }
    return count;
}

fn main() {
    let n: u64 = read_line().parse().unwrap();

    let d = digits(n);
    let mut nums_counted = 0u64;
    let mut nines = 9u64;
    let mut res = 0u64;
    for i in 1 .. d {
        let cur_len = nines - nums_counted;
        nines = nines * 10 + 9;
        res += cur_len * i;
        nums_counted += cur_len;
    }

    let cur_len = n - nums_counted;
    res += cur_len * d;

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


//spnauti-rust
use std::io::*;
use std::str::*;
use std::fmt::Debug;
#[allow(unused_imports)] use std::cmp::Ordering::{self,*};
#[allow(unused_imports)] use std::ops::*;
#[allow(unused_imports)] use std::collections::*;

#[allow(unused_macros)]
macro_rules! m {
    ($c:tt, $x:expr, $y:expr) => {{
        let b = $y; let a = &mut $x;
        if b $c *a { *a = b; true } else { false }
    }};
}
#[allow(unused_macros)]
macro_rules! l {
    ($i:ident . $e:tt : $t:ty, $($a:ident),*) => {
        $( let $a: $t = $i.$e(); )*
    };
    ($i:ident . $e:tt, $($a:ident),*) => {
        $( let $a = $i.$e(); )*
    };
}

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).ok();
        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 f(&mut self) ->    f64 { self.p()                }
    fn u(&mut self) ->  usize { self.p()                }
    fn sk(&mut self, n: usize) { self.it.nth(n - 1); }
    fn vi(&mut self, n: usize) -> Vec<i32> {
        self.vp::<i32>(n)
    }
    fn p<T: FromStr>(&mut self) -> T where T::Err: Debug {
        self.sl().parse::<T>().unwrap()
    }
    fn ip<T: FromStr>(&mut self, n: usize) -> impl std::iter::Iterator<Item=T> where T::Err: Debug {
        self.vp(n).into_iter()
    }
    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);

    let n: i64 = input.p();
    let mut sol = n * 0;
    let mut d = 1;
    let mut x = 1;
    loop {
        let xx = x * 10;
        if n < xx {
            sol += (n - x + 1) * d;
            break;
        } else {
            sol += (xx - x) * d;
            x = xx;
            d += 1;
        }
    }
    println!("{}", sol);
}


#![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),*) => {eprintln!(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;

struct Graph {
    e: Vec<Vec<usize>>,
    v: Vec<usize>,
    u: Vec<usize>,
    f: Vec<bool>,
    c: i64,
    vc: Vec<i64>,
}

impl Graph {
    fn new(n:usize) -> Self {
        Graph {
            e: vec![vec![];n],
            v: vec![],
            u: vec![n;n],
            f: vec![false;n],
            c: 0,
            vc: vec![0;n],
        }
    }

    fn dfs(&mut self, crt: usize) {
        if self.f[crt] { return; }
        self.c += 1;
        self.f[crt] = true;
        self.v.push(crt);
        self.vc[crt] = self.c;
        self.u[crt] = self.v.len()-1;
        for i in 0..self.e[crt].len() {
            self.dfs(self.e[crt][i]);
        }
        //debug!(crt, self.c, self.vc[crt]);
        self.vc[crt] = self.c - self.vc[crt];
    }
}

fn binary_search(s: &Vec<i64>, v:i64) -> usize {
    let mut left = 0;
    let mut right = s.len();

    while right-left > 1 {
        let mid = (right+left)/2;
        //debug!(left,mid,right,s[mid]);
        if s[mid] < v { left = mid; }
        else { right = mid; }
    }
    left
}

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

    //'outer: for _ in 0..t {
        let n:usize = read();
        let s:Vec<char> = read::<String>().chars().collect();

        let mut v:Vec<(String,i64)> = vec![];
        for i in 0..n-1 {
            let mut t = String::new();
            t.push(s[i]);
            t.push(s[i+1]);
            let mut f = false;
            for j in 0..v.len() {
                if t == v[j].0 {
                    v[j].1 += 1;
                    f = true;
                }
            }
            if !f {
                v.push((t,1));
            }
        }

        let mut t = String::new();
        let mut mx = 0;
        for i in 0..v.len() {
            if v[i].1 > mx {
                t = v[i].0.clone();
                mx = v[i].1;
            }
        }

        println!("{}", t);

    //}
}

/*

*/


use std::collections::HashMap;

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 _n: usize = scan.next();
    let input: Vec<char> = scan.next::<String>().chars().collect();
    let mut map: HashMap<String, usize> = HashMap::new();
    let mut res: String = String::new();
    let mut cnt = 0usize;
    for i in 0..input.len() - 1 {
        let current: String = input[i..=i + 1].iter().collect();
        map.entry(current.clone())
            .and_modify(|x| {
                *x += 1;
            })
            .or_insert(1);
        if map[&current] > cnt {
            cnt = map[&current];
            res = current.clone();
        }
    }
    println!("{}", res);
}

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


// use rand::Rng;
use std::collections::HashMap;
use std::io;
macro_rules! parse_input {
    ($x:expr, $t:ident) => {
        $x.trim().parse::<$t>().unwrap()
    };
}

macro_rules! split_line {
    ($y:expr, $t:ident) => {
        $y.split(" ")
            .map(|z| parse_input!(z, $t))
            .collect::<Vec<$t>>();
    };
}

struct xorrand {
    state: u64,
}
#[allow(dead_code)]
impl xorrand {
    fn rand(&mut self) -> u64 {
        let mut x = self.state;
        x ^= x << 13;
        x ^= x >> 7;
        x ^= x << 17;
        self.state = x;
        self.state.wrapping_mul(0x2545F4914F6CDD1Du64)
    }

    fn randint(&mut self, start: u64, end: u64) -> u64 {
        return (self.rand() % (end - start)) + start;
    }

    fn randfloat(&mut self) -> f64 {
        1.0 / (self.rand() as f64)
    }

    fn new(seed: u64) -> xorrand {
        xorrand { state: seed }
    }

    fn newtime() -> xorrand {
        let start = std::time::SystemTime::now();
        let ms = start
            .duration_since(std::time::UNIX_EPOCH)
            .unwrap()
            .as_secs();
        xorrand { state: ms }
    }

    fn shuffle<T: Clone>(&mut self, tgt: &mut Vec<T>) {
        for i in 0..tgt.len() - 1 {
            let j = self.randint(i as u64, tgt.len() as u64) as usize;
            let c = tgt[j].clone();
            tgt[j] = tgt[i].clone();
            tgt[i] = c;
        }
    }
}

#[derive(Debug, Clone)]
struct segment {
    start_0: i64,
    start_1: i64,
    end_0: i64,
    end_1: i64,
}

impl segment {}

fn solve(a: String, b: String) {
    let mut counters = vec![Vec::<i64>::new(); b.len() + 2];
    let mut start = 1;
    for i in 0..a.len() {
        for j in 0..start {
            if a.as_bytes()[i] == b.as_bytes()[j] {
                counters[j + 1].push(i as i64);
                if j == start - 1 && start < b.len() {
                    start += 1;
                }
            }
        }
    }
    let mut end = a.len() as i64;
    for i in (0..b.len()).rev() {
        counters[i + 1].retain(|&x| x < end);
        end = *counters[i + 1].iter().max().unwrap();
    }
    counters[0].push(-1);
    counters[b.len() + 1].push(a.len() as i64);
    let mut best = 0;
    for i in 0..counters.len() - 1 {
        best = std::cmp::max(
            best,
            counters[i + 1].iter().max().unwrap() - counters[i].iter().min().unwrap() - 1,
        );
    }
    println!("{}", best);
}

fn main() {
    let mut input_line = String::new();
    io::stdin().read_line(&mut input_line).unwrap();
    let mut ss = String::new();
    io::stdin().read_line(&mut ss).unwrap();
    let ss = parse_input!(ss, String);
    let input_line = parse_input!(input_line, String);
    solve(input_line, ss);
    // let numTests = parse_input!(input_line, String);
    // solve(numTests as usize, &tgt);
    // // // let numTests = 1;
    // // let mut rng = rand::thread_rng();
    // for _ in 0..numTests {
    //     let mut input_line = String::new();
    //     io::stdin().read_line(&mut input_line).unwrap();
    //     let s = split_line!(input_line, i64);
    //     let mut input_line = String::new();
    //     io::stdin().read_line(&mut input_line).unwrap();
    //     let v = split_line!(input_line, i64);
    //     // let v: Vec<i64> = (0..10).map(|_| rng.gen_range(0, 10000)).collect();

    //     solve(s, v);
    // }
}