fn remainder(left: int, right: int) -> int #[remainder()] {}

fn int_to_string(v: int) -> string #[builtin(IntToString)] {}

fn string_push_char(str: string, value: int) -> string #[builtin(StringPushChar)] {}
fn string_char_at(str: string, index: int) -> int #[builtin(StringCharAt)] {}
fn string_length(str: string) -> int #[builtin(StringLength)] {}
fn string_to_int(v: string) -> int #[builtin(StringToInt)] {}

fn string_array_new() -> [string] #[builtin(ArrayNew)] {}
fn string_array_push(array: [string], value: string) #[builtin(ArrayPush)] {}
fn string_array_length(array: [string]) -> int #[builtin(ArrayLength)] {}
fn string_array_at(array: [string], index: int) -> string #[builtin(ArrayAt)] {}

fn int_array_new() -> [int] #[builtin(ArrayNew)] {}
fn int_array_push(array: [int], value: int) #[builtin(ArrayPush)] {}
fn int_array_length(array: [int]) -> int #[builtin(ArrayLength)] {}
fn int_array_at(array: [int], index: int) -> int #[builtin(ArrayAt)] {}

fn file_open(filename: string, mode: string) -> int #[builtin(FileOpen)] {}
fn file_close(file: int) #[builtin(FileClose)] {}
fn file_write_string(file: int, content: string) -> int #[builtin(FileWriteString)] {}
fn file_read_char(file: int) -> int #[builtin(FileReadChar)] {}
fn file_read_to_string(file: int) -> string #[builtin(FileReadToString)] {}
fn file_flush(file: int) #[builtin(FileFlush)] {}
fn file_eof(file: int) -> bool #[builtin(FileEof)] {}

fn stdin() -> int { 0 }
fn stdout() -> int { 1 }
fn stderr() -> int { 2 }

fn file_read_line(file: int) -> string {
    let line = "";
    loop {
        if file_eof(file) {
            break;
        }
        let ch = file_read_char(file);
        if ch == "\n"[0] {
            break;
        }
        line = string_push_char(line, ch);
    }
    line
}

fn print(msg: string) #[builtin(Print)] {}
fn println(msg: string) { print(msg + "\n") }

fn input(prompt: string) -> string {
    print("> ");
    file_flush(stdout());
    file_read_line(stdin())
}

//

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

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

fn sqrt(n: int) -> int {
    let low = min(1, n);
    let high = max(1, n);
    let mid = 0;

    while 100 * low * low < n {
        low = low * 10;
    }

    while (high * high) / 100 > n {
        high = high / 10;
    }

    for (let i = 0; i < 100; i += 1) {
        mid = (low + high) / 2;
        if mid * mid == n {
            return mid;
        }
        if mid * mid > n {
            high = mid;
        } else {
            low = mid;
        }
    }
    mid
}

fn is_prime(n: int) -> bool {
    if n == 0{
        return false;
    }
    if n == 1 {
        return true;
    }
    let n_root = sqrt(n);
    for (let i = 2; i < n_root; i += 1) {
        if remainder(n, i) == 0 {
            return false;
        }
    }
    true
}

fn main() {
    for (let i = 1; i <= 10000; i += 1) {
        if is_prime(i) {
            print(int_to_string(i) + " ");
        }
    }
    println("");
}