CSES - Shared codeLink to this code: https://cses.fi/paste/00b85139a05218744e5888/
/*
 * Keep it Simple!
 * Do It Yourself!
 *
 * - Charles H. Moore, PROGRAMMING A PROBLEM-ORIENTED LANGUAGE (1970)
 */

#include <bits/stdc++.h>

namespace {
    int64_t stack[2048];
    int64_t *sp = stack;
    int64_t retstack[2048];
    int64_t *rp = retstack;
    int64_t vars[2048];
}

template <size_t MaxLen = 10>
struct Str {
    size_t size = 0;
    char buf[1+MaxLen] = {};

    constexpr Str() = default;

    template <size_t N>
    constexpr Str(const char (&s)[N]) {
        std::copy(std::begin(s), std::end(s) - 1, buf);
        size = std::end(s) - std::begin(s) - 1;
    }

    constexpr auto sv() const { return std::string_view(buf, buf+size); }
    constexpr void push(char c) { buf[size++] = c; }
    constexpr char operator[](size_t i) const { return buf[i]; }
    constexpr auto operator<=>(const Str&) const = default;
};

template <size_t N>
Str(const char (&)[N]) -> Str<N - 1>;

struct WordList {
    static const size_t Capacity = 512;

    size_t size = 0;
    Str<> buf[Capacity] = {};

    constexpr WordList() = default;

    template <Str<>... strs>
    static constexpr WordList make() {
        WordList wl;
        (wl.push(strs), ...);
        return wl;
    }

    template <size_t N>
    static constexpr WordList split(const char (&s)[N]) {
        return split(Str<N-1>(s));
    }

    template <size_t N>
    static constexpr WordList split(const Str<N>& str) {
        auto result = WordList();
        Str<> acc;
        for (size_t i = 0; i < str.size; i++) {
            char c = str[i];
            if (c == ' ' || c == '\n') {
                if (acc.size > 0) {
                    result.push(acc);
                    acc = Str<>();
                }
            }
            else {
                acc.push(c);
            }
        }
        if (acc.size > 0) {
            result.push(acc);
        }
        return result;
    }

    constexpr void push(const Str<>& str) { buf[size++] = str; }
    constexpr Str<> operator[](size_t i) const { return buf[i]; }
    constexpr auto operator<=>(const WordList&) const = default;

    constexpr size_t find_first(size_t begin, size_t end, const Str<>& x) const {
        for (size_t it = begin; it != end; it++) {
            if ((*this)[it] == x) {
                return it;
            }
        }
        return end;
    }

    constexpr size_t find_matching(size_t begin, size_t end, const Str<>& open, const Str<>& close) const {
        size_t level = 0;
        for (size_t it = begin; it != end; it++) {
            level += (*this)[it] == open;
            level -= (*this)[it] == close;
            if (!level) return it;
        }
        return end;
    }

    constexpr size_t find_matching(size_t begin, size_t end, const Str<>& open, const Str<>& x, const Str<>& close) const {
        size_t level = 0;
        for (size_t it = begin; it != end; it++) {
            level += (*this)[it] == open;
            level -= (*this)[it] == close;
            if (level == 1 && (*this)[it] == x) return it;
        }
        return end;
    }
};

template <Str FS, typename T>
struct DictDef {
    static constexpr auto name() { return FS; }
    using Impl = T;
};

template <Str name, typename... Entries>
struct Lookup_impl;

template <Str name, typename Def, typename... Defs> requires (name == Def::name())
struct Lookup_impl<name, Def, Defs...> {
    using type = typename Def::Impl;
};

template <Str name, typename Def, typename... Defs>
struct Lookup_impl<name, Def, Defs...> {
    using type = typename Lookup_impl<name, Defs...>::type;
};

template <Str name, typename... Defs>
using Lookup = typename Lookup_impl<name, Defs...>::type;

template <size_t VarIndex> struct VariableEval { static void run() { *sp++ = reinterpret_cast<int64_t>(&vars[VarIndex]); } };
template <size_t VarIndex> struct ConstEval { static void run() { *sp++ = vars[VarIndex]; } };

template <size_t VC=0, typename... Defs>
struct Dictionary {
    static constexpr size_t VarCount = VC;

    template <Str name>
    using lookup = Lookup<name, Defs...>;

    template <Str name>
    using add_var = Dictionary<VarCount+1, DictDef<name, VariableEval<VarCount>>, Defs...>;

    template <Str name>
    using add_const = Dictionary<VarCount+1, DictDef<name, ConstEval<VarCount>>, Defs...>;

    template <Str name, typename Impl>
    using add = Dictionary<VarCount, DictDef<name, Impl>, Defs...>;

    template <template <Str> typename T, Str<>... names>
    struct addT_impl;

    template <template <Str> typename T>
    struct addT_impl<T> {
        using type = Dictionary<VC, Defs...>;
    };

    template <template <Str> typename T, Str<> name, Str<>... names>
    struct addT_impl<T, name, names...> {
        using type = typename add<name, T<name>>::template addT<T, names...>;
    };

    template <template <Str> typename T, Str<>... names>
    using addT = typename addT_impl<T, names...>::type;
};

template <size_t N>
consteval std::optional<int64_t> to_number(const Str<N>& str) {
    const size_t len = str.size;
    const bool neg = len && str[0] == '-';
    if (len - neg < 1) return {};
    size_t base = 10;
    size_t begin = neg;
    if (len - begin >= 3 && str[begin] == '0' && str[begin+1] == 'x') {
        begin += 2;
        base = 16;
    }
    size_t x = 0;
    for (size_t i = begin; i < len; i++) {
        const char c = str[i];
        int64_t digit = 0;
        if (base == 16 && c >= 'A' && c <= 'F') {
            digit = 10 + (c - 'A');
        }
        else if (c >= '0' && c <= '9') {
            digit = c - '0';
        }
        else {
            return {};
        }
        x = base*x + digit;
    }
    return neg ? -x : x;
}

template <typename DICT, Str word>
struct Word_eval {
    using Impl = typename DICT::template lookup<word>;
    static void run() { Impl::run(); }
};

template <typename DICT, Str word> requires (to_number(word).has_value())
struct Word_eval<DICT, word> {
    static void run() { *sp++ = to_number(word).value(); }
};

template <Str<> name> struct Builtin { static bool run(); };
template <> struct Builtin<"."> { static void run() { std::cout << sp[-1] << ' '; sp--; } };
template <> struct Builtin<"+"> { static void run() { sp[-2] += sp[-1]; sp--; } };
template <> struct Builtin<"MOD"> { static void run() { sp[-2] %= sp[-1]; sp--; } };
template <> struct Builtin<"&"> { static void run() { sp[-2] &= sp[-1]; sp--; } };
template <> struct Builtin<"|"> { static void run() { sp[-2] |= sp[-1]; sp--; } };
template <> struct Builtin<"~"> { static void run() { sp[-1] = ~sp[-1]; } };
template <> struct Builtin<"-"> { static void run() { sp[-2] -= sp[-1]; sp--; } };
template <> struct Builtin<"/"> { static void run() { sp[-2] /= sp[-1]; sp--; } };
template <> struct Builtin<"*"> { static void run() { sp[-2] *= sp[-1]; sp--; } };
template <> struct Builtin<"="> { static void run() { sp[-2] = (sp[-2] == sp[-1]); sp--; } };
template <> struct Builtin<">"> { static void run() { sp[-2] = (sp[-2] > sp[-1]); sp--; } };
template <> struct Builtin<">="> { static void run() { sp[-2] = (sp[-2] >= sp[-1]); sp--; } };
template <> struct Builtin<"<"> { static void run() { sp[-2] = (sp[-2] < sp[-1]); sp--; } };
template <> struct Builtin<"OVER"> { static void run() { sp[0] = sp[-2]; sp++; } };
template <> struct Builtin<"DUP"> { static void run() { *sp = sp[-1]; sp++; } };
template <> struct Builtin<"ROT"> { static void run() { std::swap(sp[-1], sp[-2]); std::swap(sp[-1], sp[-3]); } };
template <> struct Builtin<"SWAP"> { static void run() { std::swap(sp[-1], sp[-2]); } };
template <> struct Builtin<"LSHIFT"> { static void run() { sp[-2] <<= sp[-1]; sp--; } };
template <> struct Builtin<"RSHIFT"> { static void run() { sp[-2] >>= sp[-1]; sp--; } };
template <> struct Builtin<"CR"> { static void run() { std::cout << '\n'; std::cout.flush(); } };
template <> struct Builtin<"DROP"> { static void run() { sp--; } };
template <> struct Builtin<">R"> { static void run() { *rp++ = *--sp; } };
template <> struct Builtin<"R>"> { static void run() { *sp++ = *--rp; } };
template <> struct Builtin<"I"> { static void run() { *sp++ = rp[-1]; } };
template <> struct Builtin<"I'"> { static void run() { *sp++ = rp[-2]; } };
template <> struct Builtin<"J"> { static void run() { *sp++ = rp[-3]; } };
template <> struct Builtin<"i64[]:new"> { static void run() { sp[-1] = (int64_t)new int64_t[sp[-1]]; } };
template <> struct Builtin<"@"> { static void run() { sp[-1] = *(int64_t*)sp[-1]; } };
template <> struct Builtin<"!"> { static void run() { *(int64_t*)sp[-1] = sp[-2]; sp -= 2; } };
template <> struct Builtin<"cin>>n"> { static void run() { std::cin >> *sp++; } };
template <> struct Builtin<"cin>>c"> { static void run() { char c; std::cin>>c; *sp++ = (int64_t)c; } };
template <> struct Builtin<"NOT"> { static void run() { sp[-1] = !sp[-1]; } };
template <> struct Builtin<"ABS"> { static void run() { sp[-1] = std::llabs(sp[-1]); } };
template <> struct Builtin<"MIN"> { static void run() { sp[-2] = std::min(sp[-2], sp[-1]); sp--; } };
template <> struct Builtin<"KTH-BIT"> { static void run() { sp[-2] = (sp[-2] >> sp[-1]) & 1; sp--; } };
template <> struct Builtin<"i64[]"> { static void run() { sp[-2] = ((int64_t*)sp[-2])[sp[-1]]; sp--; } };

template <Str<> str>
constexpr bool is_builtin = std::is_same_v<void, std::invoke_result_t<decltype(Builtin<str>::run)>>;

template <typename DICT, WordList WL, size_t IP, size_t IPEnd>
struct Forth_impl;

template <typename DICT, WordList WL, size_t IP, size_t IPEnd>
struct Forth_impl {
    static void run() {
        Word_eval<DICT, WL[IP]>::run();
        Forth_impl<DICT, WL, IP+1, IPEnd>::run();
    }
};

template <typename DICT, WordList WL, size_t IP, size_t IPEnd>
    requires (IP >= IPEnd)
struct Forth_impl<DICT, WL, IP, IPEnd> {
    static void run() { }
};

template <typename DICT, WordList WL, size_t IP, size_t IPEnd>
    requires (IP+1 < IPEnd && WL[IP] == Str<>(":"))
struct Forth_impl<DICT, WL, IP, IPEnd> {
    static constexpr size_t DefEnd = WL.find_matching(IP, IPEnd, ":", ";");
    struct def {
        static void run() {
            Forth_impl<NEW_DICT, WL, IP+2, DefEnd>::run();
        }
    };
    using NEW_DICT = typename DICT::template add<WL[IP+1], def>;
    static void run() {
        Forth_impl<NEW_DICT, WL, DefEnd+1, IPEnd>::run();
    }
};

template <typename DICT, WordList WL, size_t IP, size_t IPEnd>
    requires (IP < IPEnd && is_builtin<WL[IP]>)
struct Forth_impl<DICT, WL, IP, IPEnd> {
    static void run() {
        Builtin<WL[IP]>::run();
        Forth_impl<DICT, WL, IP+1, IPEnd>::run();
    }
};

template <typename DICT, WordList WL, size_t IP, size_t IPEnd>
    requires (IP < IPEnd && WL[IP] == Str<>("?DO"))
struct Forth_impl<DICT, WL, IP, IPEnd> {
    static constexpr size_t LoopEnd = WL.find_matching(IP, IPEnd, "?DO", "LOOP");
    static void run() {
        *rp++ = sp[-2];
        *rp++ = sp[-1];
        sp -= 2;
        while (rp[-1] != rp[-2]) {
            Forth_impl<DICT, WL, IP+1, LoopEnd>::run();
            rp[-1]++;
        }
        rp -= 2;
        Forth_impl<DICT, WL, LoopEnd+1, IPEnd>::run();
    }
};

template <typename DICT, WordList WL, size_t IP, size_t IPEnd>
    requires (IP < IPEnd && WL[IP] == Str<>("IF"))
struct Forth_impl<DICT, WL, IP, IPEnd> {
    static constexpr size_t Then = WL.find_matching(IP, IPEnd, "IF", "THEN");
    static constexpr size_t Else = WL.find_matching(IP, Then, "IF", "ELSE", "THEN");

    static void run() {
        int64_t top = sp[-1];
        sp--;
        if (top) {
            Forth_impl<DICT, WL, IP+1, std::min(Then, Else)>::run();
        }
        else {
            if constexpr (Else != IPEnd) {
                Forth_impl<DICT, WL, Else + 1, Then>::run();
            }
        }
        Forth_impl<DICT, WL, Then+1, IPEnd>::run();
    }
};

template <typename DICT, WordList WL, size_t IP, size_t IPEnd>
    requires (IP < IPEnd && WL[IP] == Str<>("BEGIN"))
struct Forth_impl<DICT, WL, IP, IPEnd> {
    static constexpr size_t End = WL.find_matching(IP, IPEnd, "BEGIN", "UNTIL");

    static void run() {
        for (;;) {
            Forth_impl<DICT, WL, IP+1, End>::run();
            if (*--sp) break;
        } 
        Forth_impl<DICT, WL, End+1, IPEnd>::run();
    }
};

template <typename DICT, WordList WL, size_t IP, size_t IPEnd>
    requires (IP+1 < IPEnd && WL[IP] == Str<>("VARIABLE"))
struct Forth_impl<DICT, WL, IP, IPEnd> {
    static void run() {
        using NEW_DICT = typename DICT::template add_var<WL[IP+1]>;
        vars[DICT::VarCount] = 0;
        Forth_impl<NEW_DICT, WL, IP+2, IPEnd>::run();
    }
};

template <typename DICT, WordList WL, size_t IP, size_t IPEnd>
    requires (IP+1 < IPEnd && WL[IP] == Str<>("CONSTANT"))
struct Forth_impl<DICT, WL, IP, IPEnd> {
    static void run() {
        using NEW_DICT = typename DICT::template add_const<WL[IP+1]>;
        vars[DICT::VarCount] = *--sp;
        Forth_impl<NEW_DICT, WL, IP+2, IPEnd>::run();
    }
};

template <typename DICT, WordList WL, size_t IP, size_t IPEnd>
    requires (IP < IPEnd && WL[IP] == Str<>("("))
struct Forth_impl<DICT, WL, IP, IPEnd> {
    static constexpr size_t CommentEnd = WL.find_matching(IP, IPEnd, "(", ")");
    static void run() {
        Forth_impl<DICT, WL, CommentEnd+1, IPEnd>::run();
    }
};

template <typename DICT, WordList WL, size_t IP, size_t IPEnd>
    requires (IP < IPEnd && WL[IP] == Str<>(".\""))
struct Forth_impl<DICT, WL, IP, IPEnd> {
    static constexpr size_t QuoteEnd = WL.find_first(IP, IPEnd, "\"");

    static void run() {
        for (size_t i = IP + 1; i < QuoteEnd; i++) {
            std::cout << WL[i].sv() << ' ';
        }
        Forth_impl<DICT, WL, QuoteEnd+1, IPEnd>::run();
    }
};

template <typename DICT, WordList WL, size_t IP, size_t IPEnd>
struct CompileDictionary {
    using type = DICT;
};

template <typename DICT, WordList WL, size_t IP, size_t IPEnd>
    requires (IP+1 < IPEnd && WL[IP] == Str<>(":"))
struct CompileDictionary<DICT, WL, IP, IPEnd> {
    static constexpr size_t DefEnd = WL.find_matching(IP, IPEnd, ":", ";");
    struct def { static void run() { Forth_impl<NEW_DICT, WL, IP+2, DefEnd>::run(); } };
    using NEW_DICT = typename DICT::template add<WL[IP+1], def>;
    using type = typename CompileDictionary<NEW_DICT, WL, DefEnd+1, IPEnd>::type;
};

template <typename DICT, WordList WL, size_t IP, size_t IPEnd>
    requires (IP+1 < IPEnd && WL[IP] == Str<>("VARIABLE"))
struct CompileDictionary<DICT, WL, IP, IPEnd> {
    using NEW_DICT = typename DICT::template add_var<WL[IP+1]>;
    using type = typename CompileDictionary<NEW_DICT, WL, IP+2, IPEnd>::type;
};

template <Str str>
using Compile = typename CompileDictionary<Dictionary<>, WordList::split(str), 0, WordList::split(str).size>::type;

using Dict = Compile<R"cses(

: kth-digit ( n k -- d )
    I 1 - SWAP -
    : go ( n k -- d )
        DUP IF
            SWAP 10 / SWAP 1 - go
        ELSE
            DROP 10 MOD
        THEN ;
    go ;

: solve ( k -- ans )
    1 -
    VARIABLE $ans 1 $ans !
    9 >R 1 >R
    BEGIN
        I I' *
        OVER OVER >= IF
            -
            $ans @ I' + $ans !
            R> R> 10 * >R 1 + >R
            0
        THEN
    UNTIL
    $ans @ OVER I / + $ans !
    $ans @ SWAP I MOD kth-digit
    R> DROP R> DROP ;

: main
    cin>>n 0 ?DO
        cin>>n solve . CR
    LOOP ;

)cses">;

template <Str str>
using Forth = Forth_impl<Dict, WordList::split(str), 0, WordList::split(str).size>;

int main() {
    std::cin.sync_with_stdio(0);
    Forth<"main">::run();
}