use std::io::stdin;
use std::io::prelude::*;
use std::io::BufReader;

fn main() {
    let mut br = BufReader::new(stdin());
    let input: u64 = br.lines().next().unwrap().unwrap().parse().unwrap();

    print!("{}", CF1177B(input));
}

fn CF1177B(mut k: u64) ->  u64 {
    let mut num_digits = 1;

    while k > digit_length(num_digits) {
        k -= digit_length(num_digits);
        num_digits += 1;
    }

    let a = if k % num_digits == 0 {
        (k / num_digits) - 1
    } else {
        (k / num_digits)
    };

    k -= a * num_digits;

    nth_digit(a + int_pow(10, num_digits - 1), num_digits, k)
}

fn nth_digit(num: u64, digits: u64, n: u64) -> u64{
    let a = int_pow(10, digits - n);

    (num / a) % 10
}

fn digit_length(digit: u64) -> u64 {
    digit * 9 * int_pow(10, digit-1)
}

fn int_pow(a: u64, b: u64) -> u64 {
    let mut rv = 1;

    for _ in 0..b {
        rv *= a;
    }

    rv
}

use std::error::Error;
use std::io::stdin;

struct Digits {
    number: u64,
    divisor: u64,
}

impl Digits {
    fn new(number: u64) -> Self {
        let mut divisor = 1;
        while number >= divisor * 10 {
            divisor *= 10;
        }

        Digits {
            number,
            divisor,
        }
    }

    fn reset(&mut self, number: u64){
        let mut divisor = 1;
        while number >= divisor * 10 {
            divisor *= 10;
        }
        self.divisor = divisor;
        self.number = number;

    }
}

impl Iterator for Digits {
    type Item = u64;

    fn next(&mut self) -> Option<Self::Item> {
        if self.divisor == 0 {
            None
        } else {
            let v = Some(self.number / self.divisor);
            self.number %= self.divisor;
            self.divisor /= 10;
            v
        }

    }
}

struct InfinityCounter{
    num: Digits,
    current: u64,
}
impl InfinityCounter{
    pub fn new() -> Self{
        Self{
            current: 0,
            num: Digits::new(1),
        }
    }
}

impl Iterator for InfinityCounter{
    type Item = u64;

    fn next(&mut self) -> Option<Self::Item> {
        let next = self.num.next();
        if next.is_none() {
            self.current += 1;
            self.num.reset(self.current);
            return self.num.next();
        }
        next
    }
}

fn main() -> Result<(), Box<dyn Error>> {
    let mut input = String::new();
    stdin().read_line(&mut input)?;
    let number: usize = input.trim().parse()?;
    let mut counter = InfinityCounter::new();
    if let Some(x) = counter.nth(number){
        println!("{}", x);
    }
    Ok(())
}

pub fn get_digits_len(mut k: usize) -> usize {
    let mut n: usize = 1;

    loop {
        k /= 10;

        if k > 0 {
            n+=1;
        }else{
            break n;
        }
    }
}

pub fn get_nth_right_digit(n: usize, k: usize) -> usize {

    (k/usize::pow(10, n as u32)) % 10
}

pub fn get_kth(mut k: usize) -> usize {
    let mut x: usize = 1;

    'outer: loop {
        let n = get_digits_len(x);

        if n > k {
            break get_nth_right_digit(n-k, x);
        } else if (k - n) == 0 {
            break get_nth_right_digit(0, x);
        } else {
            k -= n;
        }

        x += 1;
    }
}

use std::{io, io::BufRead};

fn main() {
    let stdin = io::stdin();
    let locked_stdin = stdin.lock();
    println!("{}", locked_stdin.lines().take(1).map(|l| str::parse::<usize>(&l.unwrap()).unwrap()).map(|k| get_kth(k)).last().unwrap())
}

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

fn it() -> impl Iterator<Item=char> {
    (0..).flat_map(|i| i.to_string().chars().collect::<Vec<_>>())
}

fn main() {
    let stdin = io::stdin();
    let line = stdin.lock().lines().next().expect("input").expect("UTF-8");
    let index: usize = line.parse().expect("Numeric value");

    println!("{}", it().skip(index).next().unwrap());
}

#[test]
fn vectors() {
    let in_out = [(7, '7'), (21, '5')];

    for (i, o) in &in_out {
        assert_eq!(it().skip(*i).next().unwrap(), *o);
    }
}

type Res = u64;

fn main() {
    let k = {
        let mut input = String::new();
        std::io::stdin().read_line(&mut input).unwrap();
        input.trim().parse::<Res>().unwrap()
    };

    let result = solve(k);

    println!("{}", result);

}

fn int_len(inp: Res) -> Res {
    if inp == 0 {
        return 1;
    }

    let mut res = 0;
    let mut temp = 1;
    while temp <= inp {
        res += 1;
        temp *= 10
    }
    res
}

fn solve(k: Res) -> char {
    // counter for digits
    let mut n: Res = 1;
    // Potential number of the digit we search
    let mut d: Res = 1;
    while n<k {
        d += 1;
        n += int_len(d);
        //dbg!((n,d));
    }
    let delta = n-k;
    // At tis point we know our digit d and the index of the number we search for.

    let d_str = format!("{}", d);
    let d_len = int_len(d);
    let idx = (d_len - delta - 1) as usize;
    //println!("n{} d{} k{} delta{} idx{}", n, d, k, delta, idx);
    let result = d_str.chars().nth(idx).expect("Invalid index");
    result
}

#[cfg(test)]
mod tests {
    use super::{solve, int_len};

    #[test]
    fn testing (){
        assert_eq!(solve(1), '1');
        assert_eq!(solve(7), '7');
        assert_eq!(solve(9), '9');
        assert_eq!(solve(10), '1');
        assert_eq!(solve(11), '0');
        assert_eq!(solve(21), '5');
        assert_eq!(solve(193), '1');
        assert_eq!(solve(9990), '2');
        assert_eq!(solve(9990), '2');
        assert_eq!(solve(10000), '7');
    }

    #[test]
    fn test_len() {
        for i in 0..1050 {
            assert_eq!(int_len(i), format!("{}",i).len() as u64)
        }
    }
}

fn main() {
    let mut seq = String::with_capacity(10050);
    let mut stat: u32 = 0;
    while seq.len() < 10000 {
        stat += 1;
        seq.push_str(&format!("{}", stat));
    }

    let mut input = String::new();
    std::io::stdin().read_line(&mut input).unwrap();
    let input = input.trim().parse::<usize>().unwrap();
    println!("{}", seq.chars().nth(input-1).unwrap());
}

use std::io::*;

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

    let k: usize = {
        let mut buffer_string = String::new();
        stdin
            .read_line(&mut buffer_string)
            .expect("could not read line");
        buffer_string.trim().parse().unwrap()
    };

    let mut digits = 0;
    for n in (1..).map(|m| m.to_string()) {
        let digits_in_n = n.len();
        if digits + digits_in_n < k {
            digits += digits_in_n;
        } else {
            let index_in_n = k - digits - 1;
            println!("{}", n.chars().nth(index_in_n).unwrap());
            return;
        }
    }
}

use std::io::{self, BufRead};
use std::collections::VecDeque;

struct DigitSequenceIterator {
    inner: u64,
    state: VecDeque<char>,
}

impl Iterator for DigitSequenceIterator {
    type Item = char;

    fn next(&mut self) -> Option<char> {
        if self.state.len() == 0 {
            self.state.extend(self.inner.to_string().chars());;

            self.inner += 1;
        }

        self.state.pop_front()
    }
}

impl DigitSequenceIterator {
    pub fn new() -> Self {
        DigitSequenceIterator {
            inner: 0,
            state: VecDeque::new(),
        }
    }

    pub fn skip(mut to_skip: u64) -> impl Iterator<Item=char> {
        let mut inner = 0;

        if to_skip >= 10 {
            inner = 10;
            to_skip -= 10;
        }

        let mut can_jump = 90;
        let mut i = 2;
        while to_skip > can_jump * i {
            to_skip -= can_jump * i;
            inner *= 10;

            can_jump *= 10;
            i += 1;
        }

        // Now, all numbers between inner and the end are `i` wide.
        // So, to_skip/i is the amount of numbers we can still skip.
        if i > 2 {
            inner += to_skip/i;
            to_skip = to_skip % i;
        }

        DigitSequenceIterator {
            inner,
            state: VecDeque::new(),
        }.skip(to_skip as usize)
    }
}

fn main() {
    let stdin = io::stdin();
    let line = stdin.lock().lines().next().expect("input").expect("UTF-8");
    let index: u64 = line.parse().expect("Numeric value");

    println!("{}", DigitSequenceIterator::skip(index).next().unwrap());
}

#[test]
fn vectors() {
    let in_out = [(7, '7'), (21, '5'), (188, '9'), (192, '0'), (417, '5')];

    for (i, o) in &in_out {
        let test = DigitSequenceIterator::skip(*i).next().unwrap();
        assert_eq!(test, *o,
            "{}th should be {}, but got {}", i, *o, test);
    }
}

use std::io::{self, BufRead};
use std::collections::VecDeque;

struct DigitSequenceIterator {
    inner: usize,
    state: VecDeque<char>,
}

impl Iterator for DigitSequenceIterator {
    type Item = char;

    fn next(&mut self) -> Option<char> {
        if self.state.len() == 0 {
            self.state.extend(self.inner.to_string().chars());;

            self.inner += 1;
        }

        self.state.pop_front()
    }
}

impl DigitSequenceIterator {
    pub fn new() -> Self {
        DigitSequenceIterator {
            inner: 0,
            state: VecDeque::new(),
        }
    }

    pub fn skip(mut to_skip: usize) -> impl Iterator<Item=char> {
        let mut inner = 0;

        if to_skip >= 10 {
            inner = 10;
            to_skip -= 10;
        }

        let mut can_jump = 90;
        while to_skip > can_jump {
            to_skip -= can_jump;
            inner *= 10;

            can_jump *= 10;
        }

        DigitSequenceIterator {
            inner,
            state: VecDeque::new(),
        }.skip(to_skip)
    }
}

fn main() {
    let stdin = io::stdin();
    let line = stdin.lock().lines().next().expect("input").expect("UTF-8");
    let index: usize = line.parse().expect("Numeric value");

    println!("{}", DigitSequenceIterator::skip(index).next().unwrap());
}

#[test]
fn vectors() {
    let in_out = [(7, '7'), (21, '5'), (192, '0'), (417, '5')];

    for (i, o) in &in_out {
        let test = DigitSequenceIterator::skip(*i).next().unwrap();
        assert_eq!(test, *o,
            "{}th should be {}, but got {}", i, *o, test);
    }
}