// use std::ops::{Index, IndexMut};
// use std::cmp::{Ordering, min, max};
// use std::collections::{BinaryHeap, BTreeMap};
// use std::collections::btree_map::Entry::{Occupied, Vacant};
// use std::clone::Clone;

fn getline() -> String{
    let mut res = String::new();
    std::io::stdin().read_line(&mut res).ok();
    res
}

macro_rules! readl {
    ($t: ty) => {
        {
            let s = getline();
            s.trim().parse::<$t>().unwrap()
        }
    };
    ($( $t: ty),+ ) => {
        {
            let s = getline();
            let mut iter = s.trim().split(' ');
            ($(iter.next().unwrap().parse::<$t>().unwrap(),)*) 
        }
    };
}

macro_rules! readlvec {
    ($t: ty) => {
        {
            let s = getline();
            let iter = s.trim().split(' ');
            iter.map(|x| x.parse().unwrap()).collect::<Vec<$t>>()
        }
    }
}

macro_rules! mvec {
    ($v: expr, $s: expr) => {
        vec![$v; $s]
    };
    ($v: expr, $s: expr, $($t: expr),*) => {
        vec![mvec!($v, $($t),*); $s]
    };
}

macro_rules! debug {
    ($x: expr) => {
        println!("{}: {:?}", stringify!($x), $x)
    }
}

fn printiter<'a, T>(v: &'a T)
where
    &'a T: std::iter::IntoIterator, 
    <&'a T as std::iter::IntoIterator>::Item: std::fmt::Display {
    for (i,e) in v.into_iter().enumerate() {
        if i != 0 {
            print!(" ");
        }
        print!("{}", e);
    }
    println!("");
}


type Cost = i64;

#[derive(Clone)]
struct Edge {
    to: usize,
    cost: Cost,
}

impl Ord for Edge {
    fn cmp(&self, other: &Edge) -> std::cmp::Ordering {
        (-self.cost).cmp(&(-other.cost))
    }
}

impl PartialOrd for Edge {
    fn partial_cmp(&self, other: &Edge) -> Option<std::cmp::Ordering> {
        Some(self.cmp(other))
    }
}

impl Eq for Edge {}

impl PartialEq for Edge {
    fn eq(&self, other: &Edge) -> bool {
        self.cost == other.cost
    }
}

#[derive(Clone)]
struct Graph {
    adj: Vec<Vec<Edge>>,
}

impl std::ops::Index<usize> for Graph {
    type Output = Vec<Edge>;

    fn index(&self, i: usize) -> &Vec<Edge> {
        &self.adj[i]
    }
}

impl std::ops::IndexMut<usize> for Graph {
    fn index_mut<'a>(&'a mut self, i: usize) -> &'a mut Vec<Edge> {
        &mut self.adj[i]
    }
}

impl Graph {

    fn new(n: usize) -> Graph{
        Graph {
            adj: vec![vec![]; n],
        }
    }

    fn size(&self) -> usize{
        self.adj.capacity()
    }

    fn add_edge(&mut self, from: usize, to_: usize, cost_: Cost) {
        self.adj[from].push(Edge{to: to_, cost: cost_});
    }

    fn add_uedge(&mut self, from: usize, to_: usize, cost_: Cost) {
        self.add_edge(from, to_, cost_);
        self.add_edge(to_, from, cost_);
    }

}

impl Graph {
    fn get_shortest_path(&self, from: usize) -> (Vec<Cost>, Vec<usize>) {
        let n = self.size();
        
        let mut dist = vec![std::i64::MAX; n];
        let mut pre = vec![n as usize; n];
        let mut heap = std::collections::BinaryHeap::new();
        heap.push(Edge{to: from, cost: 0});
        dist[from] = 0;
        while let Some(p) = heap.pop() {
            for e in &(*self)[p.to] {
                if p.cost+e.cost >= dist[e.to] {
                    continue;
                }
                heap.push(Edge{to: e.to, cost: p.cost+e.cost});
                dist[e.to] = p.cost+e.cost;
                pre[e.to] = p.to;
            }
        }
        (dist, pre)
    }
}


use std::io::prelude::*;
impl Graph{
    fn vizualize(&self, name: &str) {
        let path = std::path::Path::new("tmp.dot");
        let mut file = std::fs::File::create(path).unwrap();
        let n = self.size();
        file.write_all("digraph graph_name {\n".as_bytes());
        for p in 0..n {
            let s = ["    ".to_string(), p.to_string(),  "[];\n".to_string()].connect("");
            file.write_all(s.as_bytes());
        }
        for p in 0..n {
            for e in &self[p] {
                file.write_all(b"    ");
                file.write_all(p.to_string().as_bytes());
                file.write_all(b" -> ");
                file.write_all(e.to.to_string().as_bytes());
                file.write_all(b"\n");
            }
        }
        file.write(b"}\n");
        let mut cmd = std::process::Command::new("dot");
        cmd.arg("-T");
        cmd.arg("png");
        cmd.arg("tmp.dot");
        cmd.arg("-o");
        cmd.arg(name);
        cmd.spawn().expect("commend failed to start");
    }
}

fn main() {
    let k = readl!(usize);
    let mut g = Graph::new(k);
    for i  in 0..k {
        g.add_edge(i, (i+1)%k, 1);
        g.add_edge(i, (i*10)%k, 0);
    }
    let g = g;
    // g.vizualize("a.png");
    println!("{}",g.get_shortest_path(1).0[0]+1);
}



Measured memory_bytes: 18684