#![allow(unused_imports)]
#![allow(unused_macros)]
#![allow(dead_code)]
#![allow(unused_labels)]

use std::cmp::*;
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")
    };
}

use std::io::*;
use std::str::FromStr;
use std::char::*;
macro_rules! debug {($($a:expr),*) => {eprintln!(concat!($(stringify!($a), " = {:?}, "),*), $($a),*);}}

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,
    flag: bool,
    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,
            flag: true,
            vc: vec![0;n],
        }
    }

    fn dfs(&mut self, crt: usize) {
        self.f[crt] = true;
        self.c = self.e[crt].len() as i64;
        if self.c != 2 {
            self.flag = false;
        }

        for i in 0..self.e[crt].len() {
            let v = self.e[crt][i];
            if self.f[v] { continue; }
            self.dfs(v);
        }
    }
}

fn binary_search(a: &Vec<i64>) -> usize {
    let mut left = -1;
    let mut right = a.len() as i64;

    while right - left > 1 {
        let mid:usize = ((right+left)/2) as usize;
        //debug!(left,mid,right);
        if is_ok(mid) { right = mid as i64; }
        else { left = mid as i64; }
    }
    right as usize
}

fn is_ok(key: usize) -> bool {
    true
}

fn neighbors(tree: &BTreeSet<usize>, val: usize) -> (Option<&usize>, Option<&usize>) {
    use std::ops::Bound::*;

    let mut before = tree.range((Unbounded, Excluded(val)));
    let mut after = tree.range((Excluded(val), Unbounded));

    (before.next_back(), after.next())
}

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

const MAX_A:i64 = 1e16 as i64;

fn gcd(a:i64, b:i64) -> i64 {
    if b==0 {return a;}
    gcd(b, a%b)
}

fn solve() {
    let out = std::io::stdout();
    let mut out = BufWriter::new(out.lock());
    macro_rules! puts {
        ($($format:tt)*) => (let _ = write!(out,$($format)*););
    }

    input! {
        n: usize,
        a: [i64;n]
    }

    let mut ans = 0;
    for i in 0..n-1 {
        if (a[i]==1 && a[i+1]==2) || (a[i]==2 && a[i+1]==1) {
            ans += 3;
        }
        else if (a[i]==1 && a[i+1]==3) || (a[i]==3 && a[i+1]==1) {
            ans += 4;
        }
        else {
            puts!("Infinite\n");
            return;
        }
    }
    puts!("Finite\n");
    puts!("{}\n", ans);

}

/*

*/


#![allow(dead_code, unused_imports, unused_macros)]

use std::fmt::Debug;
use std::str::FromStr;

fn read_stdin() -> String {
    let mut s = String::new();
    std::io::stdin()
        .read_line(&mut s)
        .expect("cannot read stdin");
    s.trim().to_string()
}

fn read<T>() -> T
where
    T: FromStr,
    <T as FromStr>::Err: Debug,
{
    read_stdin().parse::<T>().unwrap()
}

fn read_usize() -> usize {
    read::<usize>()
}

fn read_2<A, B>() -> (A, B)
where
    A: FromStr,
    <A as FromStr>::Err: Debug,
    B: FromStr,
    <B as FromStr>::Err: Debug,
{
    let s = read_stdin();
    let mut s = s.split_whitespace();
    let a = s.next().unwrap().parse::<A>().unwrap();
    let b = s.next().unwrap().parse::<B>().unwrap();
    (a, b)
}

fn read_3<A, B, C>() -> (A, B, C)
where
    A: FromStr,
    <A as FromStr>::Err: Debug,
    B: FromStr,
    <B as FromStr>::Err: Debug,
    C: FromStr,
    <C as FromStr>::Err: Debug,
{
    let s = read_stdin();
    let mut s = s.split_whitespace();
    let a = s.next().unwrap().parse::<A>().unwrap();
    let b = s.next().unwrap().parse::<B>().unwrap();
    let c = s.next().unwrap().parse::<C>().unwrap();
    (a, b, c)
}

fn read_4<A, B, C, D>() -> (A, B, C, D)
where
    A: FromStr,
    <A as FromStr>::Err: Debug,
    B: FromStr,
    <B as FromStr>::Err: Debug,
    C: FromStr,
    <C as FromStr>::Err: Debug,
    D: FromStr,
    <D as FromStr>::Err: Debug,
{
    let s = read_stdin();
    let mut s = s.split_whitespace();
    let a = s.next().unwrap().parse::<A>().unwrap();
    let b = s.next().unwrap().parse::<B>().unwrap();
    let c = s.next().unwrap().parse::<C>().unwrap();
    let d = s.next().unwrap().parse::<D>().unwrap();
    (a, b, c, d)
}

fn read_multiple<T: FromStr>() -> Vec<T>
where
    <T as FromStr>::Err: Debug,
{
    read_stdin()
        .split_whitespace()
        .map(|x| x.parse::<T>().expect("cannot parse stdin"))
        .collect()
}

/// NOTE: sort iter beforehand if required
fn count<T>(iter: &mut impl Iterator<Item = T>) -> Vec<(T, usize)>
where
    T: std::cmp::Ord,
{
    let iter = iter.collect::<Vec<_>>();
    //iter.sort();
    let (mut v, o, c) =
        iter.into_iter()
            .fold((Vec::new(), None, 0), |(mut v, last, count), item| {
                if let Some(o) = last {
                    if item == o {
                        (v, Some(o), count + 1)
                    } else {
                        v.push((o, count));
                        (v, Some(item), 1)
                    }
                } else {
                    (v, Some(item), 1)
                }
            });
    if let Some(i) = o {
        v.push((i, c));
    }
    v
}

fn partial_sum<T>(v: impl Iterator<Item = T>) -> impl Iterator<Item = T>
where
    T: Default + std::ops::Add<Output = T> + Copy,
{
    v.scan(T::default(), |state, x| {
        *state = *state + x;
        Some(*state)
    })
}

fn partial_max<T>(v: impl Iterator<Item = T>) -> impl Iterator<Item = T>
where
    T: Default + Ord + Copy,
{
    v.scan(T::default(), |state, x| {
        *state = max(*state, x);
        Some(*state)
    })
}

fn partial_min(v: impl Iterator<Item = u64>) -> impl Iterator<Item = u64> {
    v.scan(std::u64::MAX, |state, x| {
        *state = min(*state, x);
        Some(*state)
    })
}

fn max_subarray(v: impl Iterator<Item = i64>) -> (i64, (usize, usize)) {
    //assert!(v.len() > 0);
    let mut best_sum = 0;
    let (mut best_start, mut best_end) = (0, 0);
    let mut current_sum = 0;
    let mut current_start = 0;
    for (end, val) in v.enumerate() {
        if current_sum <= 0 {
            current_start = end;
            current_sum = val;
        } else {
            current_sum += val;
        }
        if current_sum > best_sum {
            best_sum = current_sum;
            best_start = current_start;
            best_end = end + 1;
        }
    }
    (best_sum, (best_start, best_end))
}

fn gcd(mut a: u64, mut b: u64) -> u64 {
    while a != 0 {
        let old_m = a;
        a = b % a;
        b = old_m;
    }
    b
}

/// returns gcd, and pair (x, y), such that x * a + b * y == gcd
fn egcd(a: i64, b: i64) -> (i64, i64, i64) {
    if a == 0 {
        (b, 0, 1)
    } else {
        let (g, x, y) = egcd(b % a, a);
        (g, y - (b / a) * x, x)
    }
}

fn factorize(mut n: u64) -> Vec<u64> {
    if n <= 3 {
        return vec![n];
    }
    let mut v = Vec::new();
    while n % 2 == 0 {
        n /= 2;
        v.push(2);
    }
    while n % 3 == 0 {
        n /= 3;
        v.push(3);
    }
    let mut f = 6;
    while (f - 1) * (f - 1) <= n {
        while n % (f - 1) == 0 {
            n /= f - 1;
            v.push(f - 1);
        }
        while n % (f + 1) == 0 {
            n /= f + 1;
            v.push(f + 1);
        }
        f += 6;
    }
    if n > 1 {
        v.push(n);
    }
    v
}

fn compact_factors(n: u64) -> Vec<(u64, usize)> {
    count(&mut factorize(n).into_iter())
}

fn all_factors(n: u64) -> Vec<u64> {
    if n == 0 {
        return vec![0];
    } else if n == 1 {
        return vec![1];
    }
    let factors = compact_factors(n);
    let mut v = vec![1];
    for (fac, num) in factors {
        let ori = v.clone();
        for i in 1..num + 1 {
            v.append(
                &mut ori
                    .clone()
                    .into_iter()
                    .map(|f| f * fac.pow(i as u32))
                    .collect::<Vec<_>>(),
            )
        }
    }
    v.sort();
    v
}

fn abs_diff<T>(a: T, b: T) -> T
where
    T: PartialOrd + std::ops::Sub<Output = T>,
{
    if a > b {
        a - b
    } else {
        b - a
    }
}

struct Permutations<T> {
    inner: Vec<T>,
    state: Vec<usize>,
    i: usize,
    start: bool,
}

impl<T> Permutations<T> {
    fn new(inner: Vec<T>) -> Self {
        Self {
            state: vec![0; inner.len()],
            i: 0,
            start: true,
            inner,
        }
    }
}

/*impl<T, X> From<X> for Permutations<T>
where
    X: IntoIterator<Item = T>,
{
    fn from(f: X) -> Self {
        Self::new(f.into_iter().collect::<Vec<T>>())
    }
}*/

impl<T> Iterator for Permutations<T>
where
    T: Clone,
{
    type Item = Vec<T>;
    fn next(&mut self) -> Option<Self::Item> {
        if self.start {
            self.start = false;
            return Some(self.inner.clone());
        }
        while self.i < self.inner.len() {
            if self.state[self.i] < self.i {
                if self.i % 2 == 0 {
                    self.inner.swap(0, self.i)
                } else {
                    self.inner.swap(self.state[self.i], self.i)
                }
                self.state[self.i] += 1;
                self.i = 0;
                return Some(self.inner.clone());
            } else {
                self.state[self.i] = 0;
                self.i += 1;
            }
        }
        None
    }
}

use std::cmp::{max, min, Ord, Ordering};
use std::collections::{BinaryHeap, VecDeque};
use std::mem::swap;

macro_rules! max_with {
    ($x: expr, $y: expr) => {
        $x = max($x, $y)
    };
}

macro_rules! min_with {
    ($x: expr, $y: expr) => {
        $x = max($x, $y)
    };
}

fn is_prime(n: u64) -> bool {
    factorize(n).len() == 1
}

fn combination(n: u64, k: u64, m: u64) -> u64 {
    if n == 0 {
        return 1;
    }
    if k == 0 || k == n {
        return 1;
    }
    let new_k = if n - k < k { n - k } else { k };
    let mut res = 1;
    for i in ((n - new_k) + 1)..=n {
        res *= i;
        res %= m;
    }
    let mut den = 1;
    for i in 1..=(new_k) {
        den *= i;
        den %= m;
    }
    let (_one, inverse, _c) = egcd(den as i64, m as i64);
    let inverse = if inverse < 0 {
        m as i64 + inverse
    } else {
        inverse
    } as u64;
    //println!("inv: {} {}", den, inverse);
    res *= inverse;
    res %= m;
    res
}

use std::collections::HashSet;
use std::iter::FromIterator;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let _n = read_usize();
    let v = read_multiple::<u8>();
    let mut points = 0;
    let mut prev = v[0];
    for a in v.into_iter().skip(1) {
        if prev == 1 {
            if a == 2 {
                points += 3
            } else {
                points += 4;
            }
        } else if prev == 2 {
            if a == 1 {
                points += 3
            } else {
                println!("Infinite");
                return Ok(());
            }
        } else {
            //prv == 3
            if a == 1 {
                points += 4
            } else {
                println!("Infinite");
                return Ok(());
            }
        }
        prev = a;
    }
    println!("Finite");
    println!("{}", points);
    Ok(())
}


#[allow(unused_imports)]
use std::cmp::{max, min, Ordering};
#[allow(unused_imports)]
use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, VecDeque};
#[allow(unused_imports)]
use std::io::{stderr, stdin, stdout, BufWriter, StdoutLock, Write};
#[allow(unused_imports)]
use std::iter::FromIterator;
#[allow(unused_imports)]
use std::{i64, u64, usize};
#[allow(unused_macros)]
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 ) * } } ; }
#[allow(unused_macros)]
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 ) * } } ; ( $ next : expr , mut $ var : ident : $ t : tt $ ( $ r : tt ) * ) => { let mut $ var = read_value ! ( $ next , $ t ) ; input_inner ! { $ next $ ( $ r ) * } } ; }
#[allow(unused_macros)]
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 , [ $ t : tt ] ) => { { let len = read_value ! ( $ next , usize ) ; ( 0 .. len ) . map ( | _ | read_value ! ( $ next , $ t ) ) . collect ::< Vec < _ >> ( ) } } ; ( $ next : expr , chars ) => { read_value ! ( $ next , String ) . chars ( ) . collect ::< Vec < char >> ( ) } ; ( $ next : expr , bytes ) => { read_value ! ( $ next , String ) . into_bytes ( ) } ; ( $ next : expr , usize1 ) => { read_value ! ( $ next , usize ) - 1 } ; ( $ next : expr , $ t : ty ) => { $ next ( ) . parse ::<$ t > ( ) . expect ( "Parse error" ) } ; }
#[allow(dead_code)]
struct Writer {
    s: String,
}
#[allow(unused_imports)]
use std::fmt::Display;
#[allow(dead_code)]
#[doc = " let mut writer = Writer::new();"]
#[doc = " writer.writeln(hoge);"]
#[doc = " writer.flush()"]
impl Writer {
    #[allow(dead_code)]
    pub fn new() -> Writer {
        Writer { s: String::new() }
    }
    #[allow(dead_code)]
    pub fn flush(&mut self) {
        print!("{}", self.s);
        self.s.clear();
    }
    pub fn write<T: Display>(&mut self, x: T) {
        self.s.push_str(&format!("{}", x));
    }
    pub fn writeln<T: Display>(&mut self, x: T) {
        self.s.push_str(&format!("{}", x));
        self.s.push('\n');
    }
    #[allow(dead_code)]
    pub fn write_vec<T: Display>(&mut self, xs: &Vec<T>) {
        if xs.len() == 0 {
            self.writeln("");
            return;
        }
        self.write(&format!("{}", xs[0]));
        for i in 1..xs.len() {
            self.write(&format!(" {}", xs[i]));
        }
        self.writeln("");
    }
}
#[allow(unused_macros)]
macro_rules ! dbg { ( $ ( $ a : expr ) ,* ) => { writeln ! ( & mut stderr ( ) , concat ! ( $ ( stringify ! ( $ a ) , " = {:?}, " ) ,* ) , $ ( $ a ) ,* ) . unwrap ( ) ; } }
#[allow(dead_code)]
const INF_U: u64 = 1_000_000_000_000_000;
#[allow(dead_code)]
const INF_I: i64 = 1_000_000_000_000_000;
#[allow(non_snake_case)]
#[allow(dead_code)]
fn main() {
    input! {
        n: usize,
        a: [usize; n]
    }
    let mut ans = 0;
    for i in 1..n {
        if a[i-1] == 1 {
            if a[i] == 2 {
                ans += 3;
            } else {
                ans += 4;
            }
        } else if a[i-1] == 2 {
            if a[i] == 1 {
                ans += 3;
            } else {
                println!("Infinite");
                return;
            }
        } else {
            if a[i] == 1 {
                ans += 4;
            } else {
                println!("Infinite");
                return;
            }
        }
    }
    println!("Finite");
    println!("{}", ans);
}


#[doc = " https://github.com/hatoo/competitive-rust-snippets"]
#[allow(unused_imports)]
use std::cmp::{max, min, Ordering};
#[allow(unused_imports)]
use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, VecDeque};
#[allow(unused_imports)]
use std::iter::FromIterator;
#[macro_export]
macro_rules ! chmax { ( $ x : expr , $ ( $ v : expr ) ,+ ) => { $ ( $ x = std :: cmp :: max ( $ x ,$ v ) ; ) + } ; }
#[macro_export]
macro_rules ! chmin { ( $ x : expr , $ ( $ v : expr ) ,+ ) => { $ ( $ x = std :: cmp :: min ( $ x ,$ v ) ; ) + } ; }
#[macro_export]
macro_rules ! max { ( $ x : expr ) => ( $ x ) ; ( $ x : expr , $ ( $ xs : expr ) ,+ ) => { std :: cmp :: max ( $ x , max ! ( $ ( $ xs ) ,+ ) ) } ; }
#[macro_export]
macro_rules ! min { ( $ x : expr ) => ( $ x ) ; ( $ x : expr , $ ( $ xs : expr ) ,+ ) => { std :: cmp :: min ( $ x , min ! ( $ ( $ xs ) ,+ ) ) } ; }
#[macro_export]
macro_rules ! dvec { ( $ t : expr ; $ len : expr ) => { vec ! [ $ t ; $ len ] } ; ( $ t : expr ; $ len : expr , $ ( $ rest : expr ) ,* ) => { vec ! [ dvec ! ( $ t ; $ ( $ rest ) ,* ) ; $ len ] } ; }
#[doc = " main"]
#[allow(unused_imports)]
use std::io::{stdin, stdout, BufWriter, Write};
#[macro_export]
macro_rules ! input { ( source = $ s : expr , $ ( $ r : tt ) * ) => { let mut parser = Parser :: from_str ( $ s ) ; input_inner ! { parser , $ ( $ r ) * } } ; ( parser = $ parser : ident , $ ( $ r : tt ) * ) => { input_inner ! { $ parser , $ ( $ r ) * } } ; ( new_stdin_parser = $ parser : ident , $ ( $ r : tt ) * ) => { let stdin = std :: io :: stdin ( ) ; let reader = std :: io :: BufReader :: new ( stdin . lock ( ) ) ; let mut $ parser = Parser :: new ( reader ) ; input_inner ! { $ parser , $ ( $ r ) * } } ; ( $ ( $ r : tt ) * ) => { input ! { new_stdin_parser = parser , $ ( $ r ) * } } ; }
#[macro_export]
macro_rules ! input_inner { ( $ parser : ident ) => { } ; ( $ parser : ident , ) => { } ; ( $ parser : ident , $ var : ident : $ t : tt $ ( $ r : tt ) * ) => { let $ var = read_value ! ( $ parser , $ t ) ; input_inner ! { $ parser $ ( $ r ) * } } ; }
#[macro_export]
macro_rules ! read_value { ( $ parser : ident , ( $ ( $ t : tt ) ,* ) ) => { ( $ ( read_value ! ( $ parser , $ t ) ) ,* ) } ; ( $ parser : ident , [ $ t : tt ; $ len : expr ] ) => { ( 0 ..$ len ) . map ( | _ | read_value ! ( $ parser , $ t ) ) . collect ::< Vec < _ >> ( ) } ; ( $ parser : ident , chars ) => { read_value ! ( $ parser , String ) . chars ( ) . collect ::< Vec < char >> ( ) } ; ( $ parser : ident , usize1 ) => { read_value ! ( $ parser , usize ) - 1 } ; ( $ parser : ident , $ t : ty ) => { $ parser . next ::<$ t > ( ) . expect ( "Parse error" ) } ; }
use std::io;
use std::io::BufRead;
use std::str;
pub struct Parser<R> {
    reader: R,
    buf: Vec<u8>,
    pos: usize,
}
impl Parser<io::Empty> {
    pub fn from_str(s: &str) -> Parser<io::Empty> {
        Parser {
            reader: io::empty(),
            buf: s.as_bytes().to_vec(),
            pos: 0,
        }
    }
}
impl<R: BufRead> Parser<R> {
    pub fn new(reader: R) -> Parser<R> {
        Parser {
            reader: reader,
            buf: vec![],
            pos: 0,
        }
    }
    pub fn update_buf(&mut self) {
        self.buf.clear();
        self.pos = 0;
        loop {
            let (len, complete) = {
                let buf2 = self.reader.fill_buf().unwrap();
                self.buf.extend_from_slice(buf2);
                let len = buf2.len();
                if len == 0 {
                    break;
                }
                (len, buf2[len - 1] <= 0x20)
            };
            self.reader.consume(len);
            if complete {
                break;
            }
        }
    }
    pub fn next<T: str::FromStr>(&mut self) -> Result<T, T::Err> {
        loop {
            let mut begin = self.pos;
            while begin < self.buf.len() && (self.buf[begin] <= 0x20) {
                begin += 1;
            }
            let mut end = begin;
            while end < self.buf.len() && (self.buf[end] > 0x20) {
                end += 1;
            }
            if begin != self.buf.len() {
                self.pos = end;
                return str::from_utf8(&self.buf[begin..end]).unwrap().parse::<T>();
            } else {
                self.update_buf();
            }
        }
    }
}
#[allow(unused_macros)]
macro_rules ! debug { ( $ ( $ a : expr ) ,* ) => { eprintln ! ( concat ! ( $ ( stringify ! ( $ a ) , " = {:?}, " ) ,* ) , $ ( $ a ) ,* ) ; } }
#[doc = " https://github.com/hatoo/competitive-rust-snippets"]
const BIG_STACK_SIZE: bool = true;
#[allow(dead_code)]
fn main() {
    use std::thread;
    if BIG_STACK_SIZE {
        thread::Builder::new()
            .stack_size(32 * 1024 * 1024)
            .name("solve".into())
            .spawn(solve)
            .unwrap()
            .join()
            .unwrap();
    } else {
        solve();
    }
}
fn solve() {
    let out = stdout();
    let mut out = BufWriter::new(out.lock());
    input!{
        n:usize,
        a:[usize;n]
    }
    let mut tot = 0;
    for i in 1..n {
        let x = i-1;
        let y = i;
        match (a[x],a[y]) {
            (1,2) | (2,1) => {
                if tot != -1 {
                    tot += 3
                }
            },
            (2,3) | (3,2) => {
                tot = -1
            },
            (1,3) | (3,1) => {
                if tot != -1 {
                    tot += 4
                }
            },
            (_,_) => {

            }
        }
    }
    if tot == -1 {
        writeln!(out,"Infinite");
    } else {
        writeln!(out,"Finite");
        writeln!(out,"{}",tot);
    }
}


#[allow(unused_imports)]
use std::io::{ BufWriter, stdin, stdout, Write, Stdout };

#[derive(Default)]
struct Scanner {
    buffer: Vec<String>
}
impl Scanner {
    fn next<T: std::str::FromStr>(&mut self) -> T {
        loop {
            if let Some(token) = self.buffer.pop() {
                return token.parse().ok().expect("Failed parse");
            }
            let mut input = String::new();
            stdin().read_line(&mut input).expect("Failed read");
            self.buffer = input.split_whitespace().rev().map(String::from).collect();
        }
    }
}

const DIG: [&'static str; 10] = [
    "O-|-OOOO",
    "O-|O-OOO",
    "O-|OO-OO",
    "O-|OOO-O",
    "O-|OOOO-",
    "-O|-OOOO",
    "-O|O-OOO",
    "-O|OO-OO",
    "-O|OOO-O",
    "-O|OOOO-",
];

fn main() {
    let out = &mut BufWriter::new(stdout());
    let mut n: usize = (Scanner::default()).next();
    let mut nums = vec![];
    while n != 0 {
        nums.push(n % 10);
        n = n/10;
    }
    nums.iter().for_each(|d| {
        writeln!(out, "{}", DIG[*d]).ok();
    });
}


use std::io::*;
use std::str::FromStr;

fn main() {
    let stdin = stdin();
    let mut sc = Scanner::new(stdin.lock());
    let n = sc.next::<u32>();
    let s = sc.next::<String>();
    let zeros = s.chars().filter(|&c| c == '0').count() as u32;
    let result = std::iter::repeat("0")
        .take(zeros as usize)
        .collect::<String>();
    println!("1{}", result);
}

pub struct Scanner<B> {
    reader: B,
    buffer: Vec<String>,
}

impl<B: BufRead> Scanner<B> {
    pub fn new(reader: B) -> Self {
        Self {
            reader,
            buffer: Vec::new(),
        }
    }

    pub fn next<T: FromStr>(&mut self) -> T
    where
        T::Err: ::std::fmt::Debug,
    {
        if let Some(front) = self.buffer.pop() {
            front.parse::<T>().expect(&front)
        } else {
            let mut input = String::new();
            self.reader.read_line(&mut input).expect("Line not read");
            self.buffer = input.split_whitespace().rev().map(String::from).collect();
            self.next()
        }
    }
}


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

fn main() {
    let s = getline();
    let inp:Vec<_> = s.trim().split(' ').collect();
    let mut n: i32 = inp[0].parse().unwrap();
    let k: usize = inp[1].parse().unwrap();
    let mut ans = vec![];
    for i in 2..n-1 {
        while n%i == 0 {
            if ans.len() == k-1 {
                break;
            }
            ans.push(i);
            n /= i;
        }
    }
    if ans.len() == k-1 {
        for e in &ans {
            print!("{} ",e);
        }
        println!("{}",n);
    }else{
        println!("-1");
    }
}


use std::io;
use std::io::prelude::*;

const PRIMES: [u128; 8] = [2, 3, 5, 7, 11, 13, 17, 19];
const WEIGHTS: [u128; 9] = [
    2 * 7 * 17,
    2 * 11,
    2 * 13 * 19,
    7 * 3,
    11 * 3 * 19 * 17,
    3 * 13,
    5 * 7 * 19,
    5 * 11,
    5 * 13 * 17,
];

fn count_powers_of(x: u128, y: u128) -> u128 {
    let mut x = x;
    let mut n = 0;
    while x != 0 && x % y == 0 {
        n += 1;
        x /= y;
    }
    n
}

fn ix(c: char) -> usize {
    match c {
        'X' => 1,
        _ => 0,
    }
}

fn main() {
    let stdin = io::stdin();
    let lines = stdin.lock().lines();
    let board = lines.map(|r| r.unwrap()).take(3).collect::<String>();
    let mut count = vec![0, 0];
    let mut prod = vec![1u128, 1];
    let mut wins = vec![0, 0];
    for (i, c) in board.chars().enumerate().filter(|p| p.1 != '.') {
        count[ix(c)] += 1;
        prod[ix(c)] *= WEIGHTS[i];
    }
    for i in 0..2 {
        for p in PRIMES.iter() {
            if count_powers_of(prod[i], *p) == 3 {
                wins[i] += 1;
            }
        }
    }
    if count[0] != count[1] && count[0] != count[1] - 1
        || wins[0] > 1
        || wins[1] > 1
        || wins[0] * wins[1] != 0
        || wins[0] == 1 && count[0] != count[1]
        || wins[1] == 1 && count[0] != count[1] - 1
    {
        println!("illegal");
    } else if count[0] == 4 && count[1] == 5 && wins[0] + wins[1] == 0 {
        println!("draw");
    } else if wins[0] == 1 {
        println!("the second player won");
    } else if wins[1] == 1 {
        println!("the first player won");
    } else if count[0] == count[1] {
        println!("first");
    } else {
        println!("second");
    }
}


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

fn main() {
    let mut input = String::new();
    io::stdin().read_to_string(&mut input).unwrap();
    let mut input = input.split_whitespace();
    macro_rules! read(
        ([$tt:tt; $n:expr]) => ((0..$n).map(|_| read!($tt)));
        ($ty:ty) => (input.next().unwrap().parse::<$ty>().unwrap());
    );

    let board = read!([String; 3])
        .map(|x| x.as_bytes().to_vec())
        .collect::<Vec<_>>();
    let p1 = b'X';
    let p2 = b'0';
    let p1_count = count(&board, p1);
    let p2_count = count(&board, p2);
    let p1_win = win(&board, p1);
    let p2_win = win(&board, p2);
    if p1_count < p2_count || p1_count > p2_count + 1 || p1_win && p2_win {
        println!("illegal");
    } else if p1_win {
        println!("the first player won");
    } else if p2_win {
        println!("the second player won");
    } else if count(&board, b'.') == 0 {
        println!("draw");
    } else if p1_count == p2_count {
        println!("first");
    } else {
        println!("second");
    }
}

fn count(board: &Vec<Vec<u8>>, c: u8) -> usize {
    board
        .iter()
        .map(|xs| xs.iter().filter(|&&x| x == c).count())
        .sum()
}

fn win(board: &Vec<Vec<u8>>, c: u8) -> bool {
    (0..3).any(|i| (0..3).all(|j| board[i][j] == c))
        || (0..3).any(|j| (0..3).all(|i| board[i][j] == c))
        || (0..3).all(|i| board[i][i] == c)
        || (0..3).all(|i| board[i][2 - i] == c)
}


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

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

fn solve() {
    let field = [
        parse_line!(String).bytes().collect::<Vec<_>>(),
        parse_line!(String).bytes().collect::<Vec<_>>(),
        parse_line!(String).bytes().collect::<Vec<_>>(),
    ];
    let mut xs = 0;
    let mut os = 0;
    for i in 0..3 {
        for j in 0..3 {
            if field[i][j] == b'X' {
                xs += 1;
            }
            if field[i][j] == b'0' {
                os += 1;
            }
        }
    }
    let ok = xs == os || xs == os + 1;
    if !ok {
        return println!("illegal");
    }
    let mut xts = false;
    let mut ots = false;
    for i in 0..3 {
        let mut xcol = true;
        let mut xrow = true;
        let mut ocol = true;
        let mut orow = true;
        for j in 0..3 {
            xcol &= field[j][i] == b'X';
            xrow &= field[i][j] == b'X';
            ocol &= field[j][i] == b'0';
            orow &= field[i][j] == b'0';
        }
        xts |= xcol | xrow;
        ots |= ocol | orow;
    }
    let mut xd1 = true;
    let mut xd2 = true;
    let mut od1 = true;
    let mut od2 = true;
    for i in 0..3 {
        xd1 &= field[i][i] == b'X';
        xd2 &= field[i][2 - i] == b'X';
        od1 &= field[i][i] == b'0';
        od2 &= field[i][2 - i] == b'0';
    }
    xts |= xd1 | xd2;
    ots |= od1 | od2;
    if xts && ots {
        return println!("illegal");
    }
    if xts {
        return println!("the first player won");
    }
    if ots {
        return println!("the second player won");
    }
    if xs + os == 9 {
        return println!("draw");
    }
    if xs == os {
        return println!("first");
    }
    println!("second");
}

fn main() {
    let tests = 1; // parse_line!(usize);
    for _ in 0..tests {
        solve();
    }
}


use std::io;
use std::io::Stdin;

const DIMENSION : usize = 3;
const NUM_SQUARES : usize = DIMENSION * DIMENSION;
const BLANK : u64 = 0;
const X : u64 = 1;
const O : u64 = 10;

fn read_line(stdin : &Stdin, line : &mut String) {
    match stdin.read_line(line) {
        Ok(_) => return,
        Err(msg) => panic!("Could not read line! Message: {}.", msg),
    }
}

fn read_board(stdin : &Stdin, board : &mut [[u64; DIMENSION]; DIMENSION]) {
    for i in 0 .. DIMENSION {
        let mut row = String::new();
        read_line(stdin, &mut row);
        let mut j = 0;
        for c in row.trim().chars() {
            if c == '.' {
                board[i][j] = BLANK;
            } else if c == 'X' {
                board[i][j] = X;
            } else if c == '0' {
                board[i][j] = O;
            } else {
                panic!("Unknown square on board: {}", c);
            }
            j = j + 1;
        }
    }
}

fn has_player_won(board: &[[u64; DIMENSION]; DIMENSION], player : u64) -> bool {
    let three_p = 3 * player;
    let row_0 = (board[0][0] + board[0][1] + board[0][2]) == three_p;
    let row_1 = (board[1][0] + board[1][1] + board[1][2]) == three_p;
    let row_2 = (board[2][0] + board[2][1] + board[2][2]) == three_p;
    let col_0 = (board[0][0] + board[1][0] + board[2][0]) == three_p;
    let col_1 = (board[0][1] + board[1][1] + board[2][1]) == three_p;
    let col_2 = (board[0][2] + board[1][2] + board[2][2]) == three_p;
    let dia_1 = (board[0][0] + board[1][1] + board[2][2]) == three_p;
    let dia_2 = (board[0][2] + board[1][1] + board[2][0]) == three_p;
    row_0 || row_1 || row_2 || col_0 || col_1 || col_2 || dia_1 || dia_2
}

fn has_first_player_won(board : &[[u64; DIMENSION]; DIMENSION]) -> bool {
    has_player_won(board, X)
}

fn has_second_player_won(board : &[[u64; DIMENSION]; DIMENSION]) -> bool {
    has_player_won(board, O)
}

fn print_board_state(board : &[[u64; DIMENSION]; DIMENSION]) {
    let mut num_x : i64 = 0;
    let mut num_o : i64 = 0;
    for i in 0 .. DIMENSION {
        for j in 0 .. DIMENSION {
            if board[i][j] == X {
                num_x = num_x + 1;
            } else if board[i][j] == O {
                num_o = num_o + 1;
            } else {
                // Do nothing ...
            }
        }
    }
    let sum = (num_x + num_o) as usize;
    let diff = num_x - num_o;
    let first_player_won = has_first_player_won(&board);
    let second_player_won = has_second_player_won(&board);
    if diff == 0 {
        if first_player_won {
            println!("illegal");
        } else if second_player_won {
            println!("the second player won");
        } else {
            if sum == NUM_SQUARES {
                println!("draw");
            } else {
                println!("first");
            }
        }
    } else if diff == 1 {
        if second_player_won {
            println!("illegal");
        } else if first_player_won {
            println!("the first player won");
        } else {
            println!("second");
        }
    } else {
        println!("illegal");
    }
}

fn main() {
    let stdin = io::stdin();
    let mut board = [[BLANK; DIMENSION]; DIMENSION];
    read_board(&stdin, &mut board);
    print_board_state(&board);
    // println!("{:?}", board);
}


// use std::collections::BTreeSet;
// use std::collections::BTreeMap;
// use std::collections::HashSet;
// use std::collections::HashMap;
use std::convert::TryInto;
use std::io::Write;

struct Scanner<R> {
    reader: R,
    buf_str: Vec<u8>,
    buf_iter: std::str::SplitAsciiWhitespace<'static>,
}

impl<R: std::io::BufRead> Scanner<R> {
    fn new(reader: R) -> Self {
        Self {
            reader,
            buf_str: Vec::new(),
            buf_iter: "".split_ascii_whitespace(),
        }
    }
    fn next<T: std::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 = std::str::from_utf8_unchecked(&self.buf_str);
                std::mem::transmute(slice.split_ascii_whitespace())
            }
        }
    }
}

enum Answer {
    Illegal,
    First,
    Second,
    FirstWon,
    SecondWon,
    Draw,
}

fn solve(b: [[u8; 3]; 3]) -> Answer {
    let mut cnt1 = 0;
    let mut cnt2 = 0;
    for i in 0..3 {
        for j in 0..3 {
            if b[i][j] == 'X' as u8 {
                cnt1 += 1;
            } else if b[i][j] == '0' as u8 {
                cnt2 += 1;
            }
        }
    }

    if !(cnt1 == cnt2 || cnt1 == cnt2 + 1) {
        return Answer::Illegal;
    }

    let win_check = |p: u8| {
        for i in 0..3 {
            if b[i][0] == p && b[i][1] == p && b[i][2] == p {
                return true;
            }
            if b[0][i] == p && b[1][i] == p && b[2][i] == p {
                return true;
            }
        }
        return b[1][1] == p && ((b[0][0] == p && b[2][2] == p) || (b[0][2] == p && b[2][0] == p));
    };
    let first_won = win_check('X' as u8);
    let second_won = win_check('0' as u8);
    if first_won && second_won {
        return Answer::Illegal;
    }
    if first_won {
        return Answer::FirstWon;
    }
    if second_won {
        return Answer::SecondWon;
    }

    let mut is_finished = true;
    for i in 0..3 {
        for j in 0..3 {
            if b[i][j] == '.' as u8 {
                is_finished = false;
            }
        }
    }

    if is_finished {
        return Answer::Draw;
    }

    if cnt1 == cnt2 {
        Answer::First
    } else {
        Answer::Second
    }
}

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

    let mut a: Vec<String> = vec![];
    a.push(scan.next());
    a.push(scan.next());
    a.push(scan.next());

    let mut b: [[u8; 3]; 3] = [[0; 3]; 3];
    for i in 0..3 {
        b[i] = a[i].as_bytes().try_into().unwrap();
    }

    writeln!(
        out,
        "{}",
        match solve(b) {
            Answer::Illegal => "illegal",
            Answer::First => "first",
            Answer::Second => "second",
            Answer::FirstWon => "the first player won",
            Answer::SecondWon => "the second player won",
            Answer::Draw => "draw",
        }
    )?;

    Ok(())
}


struct Scan {
    buffer: std::collections::VecDeque<String>,
}

impl Scan {
    fn new() -> Scan {
        Scan {
            buffer: std::collections::VecDeque::new(),
        }
    }

    fn next_line(&self) -> String {
        let mut line = String::new();
        std::io::stdin().read_line(&mut line).expect("Fail to read");
        line
    }

    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 line = self.next_line();
            self.buffer = line.split_whitespace().map(String::from).collect();
        }
    }
}

fn _main() {
    let mut scan = Scan::new();
    let mut r: u64 = scan.next();
    let mut g: u64 = scan.next();
    let mut b: u64 = scan.next();
    let mut result = r.min(g).min(b);
    r -= result;
    g -= result;
    b -= result;
    result += r / 3 + g / 3 + b / 3;
    println!("{}", result);
}

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


use std::io::{self, Write};
use std::vec::Vec;
use std::string::String;

fn get_input() -> String {
    let mut buffer = String::new();
    io::stdin().read_line(&mut buffer).expect("Failed");
    return buffer.trim().to_string();
}

fn main() {
    let input: String = get_input();
    let numbers: Vec<i8> = input.split_whitespace().map(
        |n| n.parse().unwrap()
    ).collect();

    let mut result: i8 = 1;
    for i in 0..(numbers.len()) {
        result *= numbers[i];
    }
    result >>= 1;
    print!("{}", result);
    io::stdout().flush().unwrap();
}


use std::io;

fn readline() -> Vec<usize>{
    let mut buffer = String::new();
    io::stdin().read_line(&mut buffer).unwrap();
    buffer.split_whitespace().map(|x| x.parse::<usize>().unwrap()).collect()
}

fn main() {
    let input = readline();
    println!("{:?}", input);
    let rowcount = input[0];
    let columncount = input[1];
    let mut dominoarray = vec![vec![0; columncount]; rowcount];

    let mut numberofpossibilities = 0;
    for col in 0..columncount{
        for row in 0..rowcount{
            if dominoarray[row][col] == 0 && col + 1 < columncount && dominoarray[row][col+1] == 0 {
                dominoarray[row][col] = 1;
                dominoarray[row][col+1] = 1;
                numberofpossibilities = numberofpossibilities + 1;
            } else if dominoarray[row][col] == 0 && row + 1 < rowcount && dominoarray[row+1][col] == 0 {
                dominoarray[row][col] = 1;
                dominoarray[row+1][col] = 1;
                numberofpossibilities = numberofpossibilities + 1;
            }
        }
    }
    println!("{:?}", dominoarray);
    println!("{}", numberofpossibilities);
}


fn main() {
    let mut input = String::new();
    std::io::stdin().read_line(&mut input).unwrap();
    let (m, n) = {
        let split: Vec<u8> = input
            .split_whitespace()
            .take(2)
            .map(|num| num.parse().unwrap())
            .collect();
        (split[0], split[1])
    };
    println!("{}", m * n / 2);
}


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

fn solve(input: &mut Read, output: &mut Write) {
    let mut sin = String::new();
    input.read_to_string(&mut sin).unwrap();
    let mut s = sin.lines();
    let l1 = s.next().unwrap().trim().split(' ').map(|x| x.parse().unwrap()).collect::<Vec<i32>>();

    let mut m = l1[0];
    let mut n = l1[1];

    let mut res = 0;
    while m > 1 && n > 1 {
        res += m + n - 2;
        m -= 2;
        n -= 2;
    }
    if m > 0 && n > 0 {
        res += std::cmp::min(m, n) / 2;
    }

    output.write(res.to_string().trim().as_bytes()).unwrap();
}

fn main() {
    solve(&mut io::stdin(), &mut io::stdout());
}

#[cfg(test)]
mod tests {
    use std::fs::File;
    use std::io::Read;
    use solve;

    #[test]
    fn test() {
        (1..2 + 1).map(|x| {
            println!("test #{}", x);
            let mut fin = File::open("./src/in".to_string() + &x.to_string() + ".txt").unwrap();
            let mut buf: Vec<u8> = Vec::new();
            solve(&mut fin, &mut buf);
            let res = String::from_utf8(buf).unwrap();

            let mut fout = File::open("./src/out".to_string() + &x.to_string() + ".txt").unwrap();
            let mut sout = String::new();
            fout.read_to_string(&mut sout).unwrap();
            assert_eq!(res, sout.trim());

        }).count();

    }
}


use std::io::*;

fn reads<T: std::str::FromStr>(i: &mut StdinLock) -> Vec<T> {
    let mut s = String::new();
    i.by_ref().read_line(&mut s).ok();
    s.trim()
        .split_whitespace()
        .map(|e| e.parse().ok().unwrap())
        .collect()
}

fn main() {
    // initialize stdin
    let sin = std::io::stdin();
    let mut sin = sin.lock();
    let sin = &mut sin;

    let inputs: Vec<f64> = reads(sin);
    let m = inputs[0];
    let n = inputs[1];

    let case1 = (m / 2.).floor() as u64 * n as u64;
    let case2 = (n / 2.).floor() as u64 * m as u64;
    let mut other = 0;

    let ans = if case1 < case2 {
        other = m as u64;
        case2
    } else {
        other = n as u64;
        case1
    };

    if m as u64 % 2 == 0 && n as u64 % 2 == 0 {
        println!("{}", ans);
        return;
    }

    let remain = (other as f64 / 2.).floor() as u64;

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


use std::io;

fn read() -> String{
    let mut inp=String::new();
    io::stdin().read_line(&mut inp).expect("failed to read from stdin");
    inp
}

fn main() {
    let inp=read().trim().parse::<String>().unwrap();
    let list: Vec<&str>=inp.split_whitespace().collect();
    let first=&list[0].parse::<i32>().unwrap();
    let second=&list[1].parse::<i32>().unwrap();
    println!("{}",first/2*second  + second%2*first/2);

}

//fn input1() {
//  let mut x = String::new();
//    io::stdin().read_line(&mut x).expect("Error reading input");
//    let x: f32 = x.trim().parse().expect("Error parsing number");
//    println!("{}",x)
//}


fn read_str() -> String {
    let mut buffer: String = String::new();
    std::io::stdin().read_line(&mut buffer).expect("Error");
    buffer.trim().to_string()
}

fn read_vec() -> Vec<u8> {
    read_str()
        .split_whitespace()
        .map(|value| value.parse::<u8>().expect("Error"))
        .collect()
}

fn main() {
    let m: u8;
    let n: u8;
    {
        let mn: Vec<u8> = read_vec();
        m = mn[0];
        n = mn[1];
    }
    println!("{}", (m * n) / 2);
}


use std::cmp::{max, min};
use std::io::{Read, Write, stdin, stdout};

pub struct Scanner<U: Sized + Read> {
    pub buffer: Vec<String>,
    pub reader: U,
}
impl<U: Sized + Read> Scanner<U> {
    pub fn next<T: std::str::FromStr>(&mut self) -> T {
        loop {
            if let Some(token) = self.buffer.pop() {
                return token.parse().ok().expect("Failed parse");
            }
            let mut input = String::new();
            self.reader.read_to_string(&mut input).expect("Failed read");
            self.buffer = input.lines().rev().map(String::from).collect();
        }
    }

    pub fn new(reader: U) -> Self {
        return Scanner {
            buffer: vec![],
            reader,
        };
    }
}

// the maxium ways to cover a mxn rectangle using 1x2 bricks
pub fn get_cover_num(m: usize, n: usize) -> usize {
    let smaller = min(m, n);
    let bigger = max(m, n);
    if smaller == 0 {
        return 0;
    } else if smaller == 1 {
        return bigger / 2;
    } else if smaller == 2 {
        return bigger;
    }
    let q = smaller / 2;
    return q * bigger + bigger / 2;
}
pub fn solution_of_p50a(input: &mut Read, out: &mut Write) {
    let mut scanner = Scanner::new(input);
    let arr: Vec<usize> = scanner
        .next::<String>()
        .split(' ')
        .map(|e| {
            return e.parse::<usize>().unwrap();
        })
        .collect();
    let m = arr[0];
    let n = arr[1];

    let res = get_cover_num(m, n);
    writeln!(out, "{}\n", res).ok();
}

fn main() {
    solution_of_p50a(&mut stdin(), &mut stdout());
}


#![allow(unused)]

use std::io::{self, prelude::*};

fn main() {
    let mut lines = io::BufReader::new(io::stdin()).lines();

    let mut line = lines.next().unwrap().unwrap();
    let mut iter = line.split(' ');
    let m: u8 = iter.next().unwrap().parse().unwrap();
    let n: u8 = iter.next().unwrap().parse().unwrap();

    if m % 2 == 0 {
        let x = m / 2;
        println!("{}", x * n);
    } else {
        let x = n / 2;
        println!("{}", x * m);
    }
}


#![allow(unused_macros, unused_variables, dead_code, clippy::many_single_char_names)]
use std::io::{stdin, stdout, StdinLock, StdoutLock, BufWriter, prelude::*};

macro_rules! read {
    ($s: ident) => {
        {
            $s.read()
        }
    };
    ($s: ident, $t: ty) => {
        {
            let mut v: $t = 0;
            let num = $s.read();
            let l = num.len();

            if num[0] == b'-' {
                for d in &num[1..l] {
                    v = v*10 - (*d as $t) + (b'0' as $t);
                }
            } else {
                for d in &num[..l] {
                    v = v*10 + (*d as $t) - (b'0' as $t);
                }
            }
            v
        }
    }
}

macro_rules! to_str {
    ($v: expr) => {
        {
            let mut s = String::new();
            for x in $v {
                s.push(*x as char);
            }
            s
        }
    };
    ($v: expr, $l: expr) => {
        {
            let mut s = String::with_capacity($l);
            for x in $v {
                s.push(*x as char);
            }
            s
        }
    }
}

macro_rules! read_vec {
    ($s: ident, $l: expr) => {
        {
            let mut v = Vec::with_capacity($l);
            for _ in 0..$l {
                v.push(to_str!(read!($s)));
            }
            v
        }
    };
    ($s: ident, $t: ty, $l: expr) => { // for ints
        {
            let mut v = Vec::with_capacity($l);
            for _ in 0..$l {
                v.push(read!($s, $t));
            }
            v
        }
    };
}

macro_rules! void {
    ($s: ident, $l: expr) => {
        if $l > 0 {
            let mut n = 0;
            let mut first = true;

            while n < $l {
                if $s.pos != 0 {
                    $s.stdin.consume($s.pos);
                }

                let buf = $s.stdin.fill_buf().unwrap();

                let mut resume = true;

                for (i, x) in buf.iter().enumerate() {
                    if x == &b' ' || x == &b'\n' {
                        if i == 0 && first {
                            continue;
                        }

                        n += 1;

                        if n == $l {
                            $s.pos = i+1;
                            resume = false;
                            break;
                        }
                    }
                }

                if resume {
                    $s.pos = buf.len();
                    first = false;
                }
            }
        }
    };
}

macro_rules! pipe {
    ($s: ident, $t: ty, $($x: ident),*) => {
        $(
            $x = read!($s, $t);
        )*
    };
    ($s: ident, $( ($x: ident, $t: ty) ),*) => {
        $(
            $x = read!($s, $t);
        )*
    };
    ($s: ident, $($x: ident),*) => {
        $(
            $x = read!($s);
        )*
    };
}

struct Reader<'a> {
    stdin: StdinLock<'a>,
    pos: usize,
    v_temp: Vec<u8>
}

impl<'a> Reader<'a> {
    fn new(stdin: StdinLock<'a>)/*'*/ -> Self {
        Reader {stdin, pos: 0, v_temp: vec![]}
    }

    fn read(&mut self) -> &[u8] {
        if self.pos != 0 {
            self.stdin.consume(self.pos);
        }
        let mut s = 0;
        let mut i = 0;

        let buf = self.stdin.fill_buf().unwrap();

        loop {
            if unsafe {buf.get_unchecked(i)} < &33 {
                if i > buf.len() {
                    let b_len = buf.len();
                    let mut idx_char = 0;

                    loop {
                        if unsafe {buf.get_unchecked(idx_char)} > &33 || idx_char == b_len {
                            break;
                        }
                        idx_char += 1;
                    }
                    let mut v1;
                    if b_len != idx_char {
                        v1 = vec![0; b_len-idx_char];
                        v1[..].copy_from_slice(&buf[idx_char..]);
                    } else {
                        v1 = vec![];
                    }

                    let new_buf = {
                        self.stdin.consume(b_len);
                        let buf = self.stdin.fill_buf().unwrap();
                        let mut i = 0;

                        loop {
                            if unsafe {buf.get_unchecked(i)} < &33 {
                                break if i == 0 {
                                    &[]
                                } else {
                                    &buf[..=i]
                                }
                            }
                            i += 1;
                        }
                    };
                    if !new_buf.is_empty() {
                        self.pos = new_buf.len();
                        v1.extend(new_buf.iter());
                    } else {
                        self.pos = 0;
                    }

                    self.v_temp = v1;

                    return &self.v_temp[..];
                } else if s == i {
                    s += 1;
                } else {
                    break;
                }
            }
            i += 1;
        }
        self.pos = i+1;

        if s == i {
            self.read()
        } else {
            &self.stdin.fill_buf().unwrap()[s..i]
        }
    }
}

fn main() {
    let stdin = stdin();
    let stdout = stdout();
    solve(&mut Reader::new(stdin.lock()), &mut BufWriter::new(stdout.lock()));
}

fn solve(r: &mut Reader, w: &mut BufWriter<StdoutLock>) {
    writeln!(w, "{}", (read!(r, u8)*read!(r, u8))>>1);
}


fn sieve_of_eratosthene(n: usize) -> Vec<bool> {
    let mut is_prime = vec![true; std::cmp::max(n, 2)];

    is_prime[0] = false;
    is_prime[1] = false;

    let mut i = 2;
    loop {
        while i < n && !is_prime[i] {
            i += 1;
        }

        let cur_prime = i;

        let mut q = 2;
        while q * cur_prime < n {
            is_prime[q * cur_prime] = false;
            q += 1;
        }

        i += 1;
        if i >= n {
            return is_prime;
        }
    }
}

fn primes(is_prime: &Vec<bool>) -> Vec<usize> {
    let mut primes = Vec::new();
    for i in 0..is_prime.len() {
        if is_prime[i] {
            primes.push(i);
        }
    }

    primes
}

fn is_number_good(prime: &Vec<usize>, n: usize) -> bool {
    let mut firstmultiplier = 0;

    for i in 0..prime.len() {
        if n % prime[i] == 0 {
            firstmultiplier = prime[i];
        }
    }

    for i in 0..prime.len() {
        if n % prime[i] == 0 && prime[i] != firstmultiplier {
            return true;
        }
    }

    false
}

fn main() {
    let mut str = String::new();

    std::io::stdin().read_line(&mut str).unwrap();

    let n = str.trim().parse::<usize>().unwrap();

    let is_prime = sieve_of_eratosthene(n);

    let mut c = 0;
    for i in 2..=n {
        if is_number_good(&primes(&is_prime), i) {
            c += 1;
        }
    }

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


//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! a {
    ($c: tt, $x: expr, $y: expr) => {{
        let b = $y; let a = &mut $x;
        if b $c *a { *a = b; true } else { false }
    }};
}
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 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()
    }
}

#[allow(dead_code)]
fn build_counting_hashmap<K: Eq + std::hash::Hash, T>(i: T) -> HashMap<K,usize>
    where T: Iterator<Item = K> {
    let mut m = HashMap::new();
    for k in i {
        let n = 1 + if let Some(&n) = m.get(&k) { n } else { 0 };
        m.insert(k, n);
    }
    m
}

fn gcd(a: i32, b: i32) -> i32 {
    if b == 0 {
        a
    } else {
        gcd(b, a % b)
    }
}

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

    let a = input.i();
    let b = input.i();
    let c = input.i();
    println!("{}", c / gcd(a,b));
}


#[allow(unused_imports)]
use std::cmp::{max,min,Ordering};
#[allow(unused_imports)]
use std::collections::{HashMap,HashSet,VecDeque};

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

#[allow(unused_macros)]
macro_rules! readvec {
    ( $t:ty ) => {{
        let input = readln!();
        let mut input = input.split_whitespace();
        let mut result = Vec::new();
        for elem in input {
            result.push(elem.parse::<$t>().unwrap());
        }
        result
    }}
}

fn main() {
  let (n,m,z) = readln!(i32,i32,i32);
  let mut res = 0;
  for i in 1..((z+n+n-1)/n) {
    if (i*n)%m == 0 {
      res += 1;
    }
  }
  println!("{}",res);
}


#[allow(unused_imports)]
use std::cmp::*;
#[allow(unused_imports)]
use std::collections::*;
use std::io::Read;
#[allow(dead_code)]
fn getline() -> String {
    let mut ret = String::new();
    std::io::stdin().read_line(&mut ret).ok().unwrap();
    ret
}
fn get_word() -> String {
    let mut stdin = std::io::stdin();
    let mut u8b: [u8; 1] = [0];
    loop {
        let mut buf: Vec<u8> = Vec::with_capacity(16);
        loop {
            let res = stdin.read(&mut u8b);
            if res.unwrap_or(0) == 0 || u8b[0] <= b' ' {
                break;
            } else {
                buf.push(u8b[0]);
            }
        }
        if buf.len() >= 1 {
            let ret = String::from_utf8(buf).unwrap();
            return ret;
        }
    }
}

#[allow(dead_code)]
fn get<T: std::str::FromStr>() -> T { get_word().parse().ok().unwrap() }

fn solve() {
    let mut n: i64 = get();
    let k: i32 = get();
    let mut cnt = 0;
    let mut kk = k;
    while kk > 0 {
        if n == 0 {
            cnt = cnt + k - kk - 1;
            break;
        }
        if n % 10 != 0 {
            cnt += 1;
        } else {
            kk -= 1;
        }
        n /= 10;
    }
    println!("{}", cnt);
}

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


fn main() {
    let mut input = String::new();
    use std::io::prelude::*;
    std::io::stdin().read_to_string(&mut input).unwrap();
    let mut it = input.split_whitespace();

    let n: u64 = it.next().unwrap().parse().unwrap();

    let mut max_nine_count = 0;
    let mut k = 2 * n;
    while k >= 10 {
        max_nine_count += 1;
        k /= 10;
    }

    let mut ans = 0;

    for mut i in 1..k + 1 {
        for _ in 0..max_nine_count {
            i *= 10;
        }
        let j = i / 2;
        let p = std::cmp::min(i - 2, n) - j + 1;
        ans += p;
    }

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


#![allow(unused_imports)]
use std::io;
use std::cmp::*;
use std::collections::*;
#[allow(dead_code)]
const M: i64 = 1e9 as i64 + 7;

fn read_line() -> String {
    let stdin = io::stdin();
    let mut buf = String::new();
    stdin.read_line(&mut buf).unwrap();
    buf
}
#[allow(dead_code)]
fn read<T>() -> T where T: std::str::FromStr, T::Err : std::fmt::Debug {
    read_line().trim().parse().unwrap()
}
#[allow(dead_code)]
fn readv<T>() -> Vec<T> where T: std::str::FromStr, T::Err : std::fmt::Debug {
    read_line().split(' ').map(|a| a.trim().parse().unwrap()).collect()
}

fn main() {
    let input = readv::<i64>();
    let (n, s) = (input[0], input[1]);
    let mut num = n;
    let mut diff = n;
    for i in 0..19 {
        diff -= num / 10i64.pow(i) % 10;
    }
    if diff < s {
        println!("{}", 0);
        return;
    }
    for i in (1..19).rev() {
        let p = 10i64.pow(i);
        while diff - (p - 1) >= s {
            diff -= p - 1;
            num -= p;
        }
    }
    num = num / 10 * 10;
    #[cfg(local)] println!("{}: {:?}", "(num, diff)", (num, diff));
    println!("{}", n - num + 1);
}


/**
 * https://codeforces.com/contest/1154/problem/B
 */
macro_rules! parse_line {
    ($($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"),
            )+
        )
    })
}

pub fn main() {
    let _ = parse_line!(i32);
    let mut buffer = String::new();
    std::io::stdin().read_line(&mut buffer).expect("n not esist");
    let mut nums: Vec<i32> = buffer.split_whitespace().map(|x| x.parse().expect("error")).collect();
    nums.sort();
    nums.dedup();
    let res = match nums.len() {
        1 => 0,
        2 => nums[1] - nums[0],
        3 => {
            if nums[2] - nums[1] == nums[1] - nums[0] {
                nums[2] - nums[1]
            } else {
                -1
            }
        }
        _ => -1,
    };
    println!("{}", res);
}


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

fn main() {
    let _ = read_one::<usize>();
    let mut an = read::<isize>();
    an.sort();
    an.dedup();

    if an.len() > 3 { println!("-1"); return; }
    if an.len() == 1 { println!("{}", an[0]); return; }
    if an.len() == 2 {
        if (an[1] - an[0]) % 2 == 0 {
            println!("{}", cmp::min((an[1] - an[0]) / 2, an[1] - an[0]));
        } else {
            println!("{}", an[1] - an[0]);
        }
        return;
    }
    if an.len() == 3 {
        if an[2] - an[1] == an[1] - an[0] {
            println!("{}", an[1] - an[0]);
        } else {
            println!("-1");
        }
    }
}

#[allow(dead_code)]
fn read<T>() -> Vec<T>
where T:
std::str::FromStr,
T::Err: std::fmt::Debug {

    let mut buf = String::new();
    io::stdin().read_line(&mut buf).unwrap();
    buf.split_whitespace()
        .map(|s| s.trim().parse().unwrap())
        .collect()
}

#[allow(dead_code)]
fn read_one<T>() -> T
where T:
std::str::FromStr,
T::Err: std::fmt::Debug {

    let mut buf = String::new();
    io::stdin().read_line(&mut buf).unwrap();
    buf.trim().parse().unwrap()
}


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

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

    //'outer: for _ in 0..t {
        let n:usize = read();
        let a:Vec<i64> = (0..n).map(|_| read()).collect();

        let mut ans = 10000;
        for e in -1000..1000 {
            let d = (a[0]-e).abs();
            let mut f = true;
            for i in 1..n {
                if (a[i]-e).abs() == 0 { continue; }
                if d != (a[i]-e).abs() {
                    f = false;
                }
            }
            if f {
                ans = min(ans, d);
            }
        }
        println!("{}", if ans==10000 {-1} else {ans});
    //}
}

/*

*/


#![allow(dead_code, unused_imports, unused_macros)]

use std::fmt::Debug;
use std::str::FromStr;

fn read_stdin() -> String {
    let mut s = String::new();
    std::io::stdin()
        .read_line(&mut s)
        .expect("cannot read stdin");
    s.trim().to_string()
}

fn read<T>() -> T
where
    T: FromStr,
    <T as FromStr>::Err: Debug,
{
    read_stdin().parse::<T>().unwrap()
}

fn read_usize() -> usize {
    read::<usize>()
}

fn read_2<A, B>() -> (A, B)
where
    A: FromStr,
    <A as FromStr>::Err: Debug,
    B: FromStr,
    <B as FromStr>::Err: Debug,
{
    let s = read_stdin();
    let mut s = s.split_whitespace();
    let a = s.next().unwrap().parse::<A>().unwrap();
    let b = s.next().unwrap().parse::<B>().unwrap();
    (a, b)
}

fn read_3<A, B, C>() -> (A, B, C)
where
    A: FromStr,
    <A as FromStr>::Err: Debug,
    B: FromStr,
    <B as FromStr>::Err: Debug,
    C: FromStr,
    <C as FromStr>::Err: Debug,
{
    let s = read_stdin();
    let mut s = s.split_whitespace();
    let a = s.next().unwrap().parse::<A>().unwrap();
    let b = s.next().unwrap().parse::<B>().unwrap();
    let c = s.next().unwrap().parse::<C>().unwrap();
    (a, b, c)
}

fn read_4<A, B, C, D>() -> (A, B, C, D)
where
    A: FromStr,
    <A as FromStr>::Err: Debug,
    B: FromStr,
    <B as FromStr>::Err: Debug,
    C: FromStr,
    <C as FromStr>::Err: Debug,
    D: FromStr,
    <D as FromStr>::Err: Debug,
{
    let s = read_stdin();
    let mut s = s.split_whitespace();
    let a = s.next().unwrap().parse::<A>().unwrap();
    let b = s.next().unwrap().parse::<B>().unwrap();
    let c = s.next().unwrap().parse::<C>().unwrap();
    let d = s.next().unwrap().parse::<D>().unwrap();
    (a, b, c, d)
}

fn read_multiple<T: FromStr>() -> Vec<T>
where
    <T as FromStr>::Err: Debug,
{
    read_stdin()
        .split_whitespace()
        .map(|x| x.parse::<T>().expect("cannot parse stdin"))
        .collect()
}

/// NOTE: sort iter beforehand if required
fn count<T>(iter: &mut impl Iterator<Item = T>) -> Vec<(T, usize)>
where
    T: std::cmp::Ord,
{
    let iter = iter.collect::<Vec<_>>();
    //iter.sort();
    let (mut v, o, c) =
        iter.into_iter()
            .fold((Vec::new(), None, 0), |(mut v, last, count), item| {
                if let Some(o) = last {
                    if item == o {
                        (v, Some(o), count + 1)
                    } else {
                        v.push((o, count));
                        (v, Some(item), 1)
                    }
                } else {
                    (v, Some(item), 1)
                }
            });
    if let Some(i) = o {
        v.push((i, c));
    }
    v
}

fn partial_sum<T>(v: impl Iterator<Item = T>) -> impl Iterator<Item = T>
where
    T: Default + std::ops::Add<Output = T> + Copy,
{
    v.scan(T::default(), |state, x| {
        *state = *state + x;
        Some(*state)
    })
}

fn partial_max<T>(v: impl Iterator<Item = T>) -> impl Iterator<Item = T>
where
    T: Default + Ord + Copy,
{
    v.scan(T::default(), |state, x| {
        *state = max(*state, x);
        Some(*state)
    })
}

fn partial_min(v: impl Iterator<Item = u64>) -> impl Iterator<Item = u64> {
    v.scan(std::u64::MAX, |state, x| {
        *state = min(*state, x);
        Some(*state)
    })
}

fn max_subarray(v: impl Iterator<Item = i64>) -> (i64, (usize, usize)) {
    //assert!(v.len() > 0);
    let mut best_sum = 0;
    let (mut best_start, mut best_end) = (0, 0);
    let mut current_sum = 0;
    let mut current_start = 0;
    for (end, val) in v.enumerate() {
        if current_sum <= 0 {
            current_start = end;
            current_sum = val;
        } else {
            current_sum += val;
        }
        if current_sum > best_sum {
            best_sum = current_sum;
            best_start = current_start;
            best_end = end + 1;
        }
    }
    (best_sum, (best_start, best_end))
}

fn gcd(mut a: u64, mut b: u64) -> u64 {
    while a != 0 {
        let old_m = a;
        a = b % a;
        b = old_m;
    }
    b
}

/// returns gcd, and pair (x, y), such that x * a + b * y == gcd
fn egcd(a: i64, b: i64) -> (i64, i64, i64) {
    if a == 0 {
        (b, 0, 1)
    } else {
        let (g, x, y) = egcd(b % a, a);
        (g, y - (b / a) * x, x)
    }
}

fn factorize(mut n: u64) -> Vec<u64> {
    if n <= 3 {
        return vec![n];
    }
    let mut v = Vec::new();
    while n % 2 == 0 {
        n /= 2;
        v.push(2);
    }
    while n % 3 == 0 {
        n /= 3;
        v.push(3);
    }
    let mut f = 6;
    while (f - 1) * (f - 1) <= n {
        while n % (f - 1) == 0 {
            n /= f - 1;
            v.push(f - 1);
        }
        while n % (f + 1) == 0 {
            n /= f + 1;
            v.push(f + 1);
        }
        f += 6;
    }
    if n > 1 {
        v.push(n);
    }
    v
}

fn compact_factors(n: u64) -> Vec<(u64, usize)> {
    count(&mut factorize(n).into_iter())
}

fn all_factors(n: u64) -> Vec<u64> {
    if n == 0 {
        return vec![0];
    } else if n == 1 {
        return vec![1];
    }
    let factors = compact_factors(n);
    let mut v = vec![1];
    for (fac, num) in factors {
        let ori = v.clone();
        for i in 1..num + 1 {
            v.append(
                &mut ori
                    .clone()
                    .into_iter()
                    .map(|f| f * fac.pow(i as u32))
                    .collect::<Vec<_>>(),
            )
        }
    }
    v.sort();
    v
}

fn abs_diff<T>(a: T, b: T) -> T
where
    T: PartialOrd + std::ops::Sub<Output = T>,
{
    if a > b {
        a - b
    } else {
        b - a
    }
}

struct Permutations<T> {
    inner: Vec<T>,
    state: Vec<usize>,
    i: usize,
    start: bool,
}

impl<T> Permutations<T> {
    fn new(inner: Vec<T>) -> Self {
        Self {
            state: vec![0; inner.len()],
            i: 0,
            start: true,
            inner,
        }
    }
}

/*impl<T, X> From<X> for Permutations<T>
where
    X: IntoIterator<Item = T>,
{
    fn from(f: X) -> Self {
        Self::new(f.into_iter().collect::<Vec<T>>())
    }
}*/

impl<T> Iterator for Permutations<T>
where
    T: Clone,
{
    type Item = Vec<T>;
    fn next(&mut self) -> Option<Self::Item> {
        if self.start {
            self.start = false;
            return Some(self.inner.clone());
        }
        while self.i < self.inner.len() {
            if self.state[self.i] < self.i {
                if self.i % 2 == 0 {
                    self.inner.swap(0, self.i)
                } else {
                    self.inner.swap(self.state[self.i], self.i)
                }
                self.state[self.i] += 1;
                self.i = 0;
                return Some(self.inner.clone());
            } else {
                self.state[self.i] = 0;
                self.i += 1;
            }
        }
        None
    }
}

use std::cmp::{max, min, Ord, Ordering};
use std::collections::{BinaryHeap, VecDeque};
use std::mem::swap;

macro_rules! max_with {
    ($x: expr, $y: expr) => {
        $x = max($x, $y)
    };
}

macro_rules! min_with {
    ($x: expr, $y: expr) => {
        $x = max($x, $y)
    };
}

fn is_prime(n: u64) -> bool {
    factorize(n).len() == 1
}

fn combination(n: u64, k: u64, m: u64) -> u64 {
    if n == 0 {
        return 1;
    }
    if k == 0 || k == n {
        return 1;
    }
    let new_k = if n - k < k { n - k } else { k };
    let mut res = 1;
    for i in ((n - new_k) + 1)..=n {
        res *= i;
        res %= m;
    }
    let mut den = 1;
    for i in 1..=(new_k) {
        den *= i;
        den %= m;
    }
    let (_one, inverse, _c) = egcd(den as i64, m as i64);
    let inverse = if inverse < 0 {
        m as i64 + inverse
    } else {
        inverse
    } as u64;
    //println!("inv: {} {}", den, inverse);
    res *= inverse;
    res %= m;
    res
}

use std::collections::HashSet;
use std::iter::FromIterator;

fn n_to_vec(n: u64, l: usize) -> Vec<u8> {
    let mut res = vec![0; l];
    let mut n = n;
    for i in (0..l).rev() {
        if n % 2 == 1 {
            res[i] = 1;
        }
        n /= 2;
    }
    res
}

fn vec_to_n(v: Vec<u8>) -> u64 {
    let mut res = 0;
    for i in 0..v.len() {
        res *= 2;
        if v[i] == 1 {
            res += 1;
        }
    }
    res
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let _n = read_usize();
    let a_vec = read_multiple::<u32>();
    let mut v = Vec::new();
    let mut flag = false;
    'f: for a in a_vec {
        if !v.contains(&a) {
            v.push(a)
        }
        if v.len() > 3 {
            flag = true;
            break 'f;
        }
    }
    if flag {
        println!("-1")
    } else {
        v.sort_unstable();
        if v.len() == 1 {
            println!("0")
        } else if v.len() == 2 {
            if (v[1] - v[0] % 2) == 0 {
                println!("{}", (v[1] - v[0]) / 2)
            } else {
                println!("{}", v[1] - v[0])
            }
        } else {
            //v.len() == 3
            if v[2] - v[1] != v[1] - v[0] {
                println!("-1")
            } else {
                println!("{}", v[2] - v[1])
            }
        }
    }
    Ok(())
}


#[allow(unused_imports)]
use std::cmp::{max, min, Ordering};
#[allow(unused_imports)]
use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, VecDeque};
#[allow(unused_imports)]
use std::io::prelude::BufRead;
#[allow(unused_imports)]
use std::io::{stdin, stdout, BufReader, BufWriter, Write};
#[allow(unused_imports)]
use std::mem::swap;
#[allow(unused_imports)]
use std::str::FromStr;

fn main() {
	let _n = read::<usize>();
	let arr = read_vector::<i64>();
	for i in 1..101 {
		for &x in [arr[0], arr[0] + i, arr[0] - i].iter() {
			let mut possible = true;
			for &val in arr.iter() {
				if val != x && val + i != x && val - i != x {
					possible = false;
					break;
				}
			}
			if possible {
				println!("{}", i);
				return;
			}
		}
	}
	println!("{}", -1);
}

#[allow(dead_code)]
fn read<T>() -> T
where
    T: std::str::FromStr,
    T::Err: std::fmt::Debug,
{
    let mut buf = String::new();
    stdin().read_line(&mut buf).unwrap();
    return buf.trim().parse().unwrap();
}

#[allow(dead_code)]
fn read_vector<T>() -> Vec<T>
where
    T: std::str::FromStr,
    T::Err: std::fmt::Debug,
{
    let mut buf = String::with_capacity(100);
    stdin().read_line(&mut buf).unwrap();
    return buf.split_whitespace().map(|s| s.parse().unwrap()).collect();
}

#[allow(dead_code)]
fn read_matrix<T>() -> Vec<Vec<T>>
where
    T: std::str::FromStr,
    T::Err: std::fmt::Debug,
{
    use std::io::prelude::*;
    let stdin = stdin();
    let mut reader = BufReader::with_capacity(100 * 1024, stdin);
    let mut line = String::with_capacity(100);
    let mut matrix: Vec<Vec<T>> = Vec::new();

    while reader.read_line(&mut line).unwrap() > 0 {
        matrix.push(
            line.trim()
                .split_whitespace()
                .map(|s| s.parse().unwrap())
                .collect(),
        );
        line.clear();
    }

    return matrix;
}

#[allow(dead_code)]
fn read_chars() -> Vec<char> {
    let stdin = stdin();
    let mut buf = String::new();
    let _bytes = stdin.read_line(&mut buf).unwrap();
    return buf.trim().chars().collect();
}


#[allow(unused_imports)]
use std::cmp::{min,max};
use std::collections::HashMap;
use std::io::{BufWriter, stdin, stdout, Write};
const BITS: usize = 19;

#[derive(Default)]
struct Scanner {
    buffer: Vec<String>
}
impl Scanner {
    fn next<T: std::str::FromStr>(&mut self) -> T {
        loop {
            if let Some(token) = self.buffer.pop() {
                return token.parse().ok().expect("Failed parse");
            }
            let mut input = String::new();
            stdin().read_line(&mut input).expect("Failed read");
            self.buffer = input.split_whitespace().rev().map(String::from).collect();
        }
    }
}

fn solvea () -> () {
    let mut scan = Scanner::default();
    let mut arr = [0; 4];
    arr[0] = scan.next::<i64> ();
    arr[1] = scan.next::<i64> ();
    arr[2] = scan.next::<i64> ();
    arr[3] = scan.next::<i64> ();
    arr.sort ();
    //a+b
    //b+c
    //c+a
    //a+b+c
    println! ("{} {} {}", arr[3]-arr[0], arr[3]-arr[1], arr[3]-arr[2]);
}
fn solve () {
    let mut scan = Scanner::default();
    let n = scan.next::<usize> ();
    let mut arr: Vec<i64> = Vec::new ();
    for i in 0..n {
        let x = scan.next::<i64> ();
        arr.push (x);
    }
    let mut ds: Vec<i64> = Vec::new ();
    for ss in 1..300 {
        let prevd = if arr[0] > ss {arr[0]-ss} else {ss-arr[0]};
        let mut not_possible = false;
        for i in 1..n {
            if arr[i] == ss {continue;}
            if ss + prevd == arr[i] || ss - prevd == arr[i] {
                continue;
            } else {
                not_possible=true;
                break;
            }
        }
        if !not_possible {
            ds.push (prevd);
        }
    }
    if ds.is_empty () {
        println! ("-1");
    } else {
        ds.sort ();
        println! ("{}", ds[0]);
    }
}
fn main () {
    let mut scan = Scanner::default();
    // let t = scan.next::<u64> ();
    let t = 1;
    for _ in 0..t {
        solve ();
    }
}


//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 gcd(a: u64, b: u64) -> u64 {
    if b == 0 {
        a
    } else {
        gcd(b, a % b)
    }
}

fn lcm(a: u64, b: u64) -> u64 {
    if a == 0 || b == 0 {
        a + b
    } else {
        a / gcd(a, b) * b
    }
}

fn run() {
    input! {
        w: u64,
        c: [u64; 8],
    }
    let m = (1..=8).fold(0, |s, a| lcm(s, a));
    let mut ans = 0;
    let mut w = w;
    let mut c = c;
    for (i, c) in c.iter_mut().enumerate() {
        let k = (i + 1) as u64;
        let v = m / k;
        let q = *c / v;
        *c %= v;
        let d = std::cmp::min(w / m * m, q * v * k);
        ans += d;
        w -= d;
    }
    if w >= 8 * m {
        ans += c.iter().enumerate().fold(0, |s, (i, c)| s + (i + 1) as u64 * c);
    } else {
        let w = w as usize;
        let mut dp = vec![false; w + 1];
        dp[0] = true;
        for (i, &c) in c.iter().enumerate() {
            let k = i + 1;
            for _ in 0..c {
                for j in (k..=w).rev() {
                    dp[j] |= dp[j - k];
                }
            }
        }
        ans += dp.iter().rposition(|p| *p).unwrap() as u64;
    }
    println!("{}", ans);
}

fn main() {
    run();
}


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 = parse_line!(usize);
    let a = parse_line_to_vec!(u32);
    let mut dp = vec![vec![[n, n]; n + 1]; n + 1];
    dp[0][0][0] = 0;
    dp[0][0][1] = 0;
    for i in 0..n {
        if a[i] != 0 {
            if a[i] % 2 == 0 {
                for i in (1..=n).rev() {
                    for j in 0..=n {
                        dp[i][j][0] = std::cmp::min(dp[i][j][0],
                                    std::cmp::min(dp[i - 1][j][0], dp[i - 1][j][1] + 1));
                    }
                }
            }else{
                for i in 0..=n {
                    for j in (1..=n).rev() {
                        dp[i][j][1] = std::cmp::min(dp[i][j][1],
                                    std::cmp::min(dp[i][j - 1][1], dp[i][j - 1][0] + 1));
                    }
                }
            }
            continue;
        }
        for i in (0..=n).rev() {
            for j in (0..=n).rev() {
                if i > 0 {
                    dp[i][j][0] = std::cmp::min(dp[i][j][0],
                                std::cmp::min(dp[i - 1][j][0], dp[i - 1][j][1] + 1));
                }
                if j > 0 {
                    dp[i][j][1] = std::cmp::min(dp[i][j][0],
                                std::cmp::min(dp[i][j - 1][1], dp[i][j - 1][0] + 1));
                }
            }
        }
    }
    writeln!(writer, "{}", dp[n / 2][n - n / 2].iter().min().unwrap()).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);
    }
}


// ---------- begin ModInt ----------
const MOD: u32 = 1_000_000_007;

#[derive(Clone, Copy)]
struct ModInt(u32);

impl std::ops::Add for ModInt {
    type Output = ModInt;
    fn add(self, rhs: ModInt) -> Self::Output {
        let mut d = self.0 + rhs.0;
        if d >= MOD {
            d -= MOD;
        }
        ModInt(d)
    }
}

impl std::ops::AddAssign for ModInt {
    fn add_assign(&mut self, rhs: ModInt) {
        *self = *self + rhs;
    }
}

impl std::ops::Sub for ModInt {
    type Output = ModInt;
    fn sub(self, rhs: ModInt) -> Self::Output {
        let mut d = self.0 + MOD - rhs.0;
        if d >= MOD {
            d -= MOD;
        }
        ModInt(d)
    }
}

impl std::ops::SubAssign for ModInt {
    fn sub_assign(&mut self, rhs: ModInt) {
        *self = *self - rhs;
    }
}

impl std::ops::Mul for ModInt {
    type Output = ModInt;
    fn mul(self, rhs: ModInt) -> Self::Output {
        ModInt((self.0 as u64 * rhs.0 as u64 % MOD as u64) as u32)
    }
}

impl std::ops::MulAssign for ModInt {
    fn mul_assign(&mut self, rhs: ModInt) {
        *self = *self * rhs;
    }
}

impl std::ops::Neg for ModInt {
    type Output = ModInt;
    fn neg(self) -> Self::Output {
        ModInt(if self.0 == 0 {0} else {MOD - self.0})
    }
}

impl std::fmt::Display for ModInt {
    fn fmt<'a>(&self, f: &mut std::fmt::Formatter<'a>) -> std::fmt::Result {
        write!(f, "{}", self.0)
    }
}

impl std::str::FromStr for ModInt {
    type Err = std::num::ParseIntError;
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        let val = s.parse::<u32>()?;
        Ok(ModInt::new(val))
    }
}

impl From<usize> for ModInt {
    fn from(val: usize) -> ModInt {
        ModInt((val % MOD as usize) as u32)
    }
}

#[allow(dead_code)]
impl ModInt {
    pub fn new(n: u32) -> ModInt {
        ModInt(n % MOD)
    }
    pub fn zero() -> ModInt {
        ModInt(0)
    }
    pub fn one() -> ModInt {
        ModInt(1)
    }
    pub fn pow(self, mut n: u32) -> ModInt {
        let mut t = ModInt::one();
        let mut s = self;
        while n > 0 {
            if n & 1 == 1 {
                t *= s;
            }
            s *= s;
            n >>= 1;
        }
        t
    }
    pub fn inv(self) -> ModInt {
        assert!(self.0 > 0);
        self.pow(MOD - 2)
    }
}
// ---------- end ModInt ----------

fn run() {
    let mut s = String::new();
    std::io::stdin().read_line(&mut s).unwrap();
    let mut it = s.trim().split_whitespace();
    let n: u32 = it.next().unwrap().parse().unwrap();
    let k: usize = it.next().unwrap().parse().unwrap();
    let mut is_prime = vec![true; k + 1];
    for i in 2.. {
        if i * i > k {
            break;
        }
        if is_prime[i] {
            let mut j = i * i;
            while let Some(p) = is_prime.get_mut(j) {
                *p = false;
                j += i;
            }
        }
    }
    let mut mobius = vec![ModInt::one(); k + 1];
    for (i, p) in is_prime.into_iter().enumerate().skip(2) {
        if !p {
            continue;
        }
        let mut j = i;
        while let Some(x) = mobius.get_mut(j) {
            *x = -*x;
            j += i;
        }
        let k = i.saturating_mul(i);
        let mut j = k;
        while let Some(x) = mobius.get_mut(j) {
            *x = ModInt::zero();
            j += k;
        }
    }
    let mut imos = vec![ModInt::zero(); 2 * k + 1];
    for (i, v) in mobius.into_iter().enumerate().skip(2) {
        if v.0 == 0 {
            continue;
        }
        for x in 1.. {
            if x * i > k {
                break;
            }
            let v = v * ModInt::from(x).pow(n);
            let l = x * i;
            let r = (x + 1) * i;
            imos[l] += v;
            imos[r] -= v;
        }
    }
    let mut ans = ModInt::zero();
    for i in 1..=k {
        imos[i] = imos[i] + imos[i - 1];
        let way = ModInt::from(i).pow(n) + imos[i];
        ans += ModInt::new(way.0 ^ i as u32);
    }
    println!("{}", ans);
}

fn main() {
    run();
}


use std::str::FromStr;
use std::io::stdin;

fn get_vals<T>(count: usize) -> Vec<T> where
    T: FromStr,
    <T as std::str::FromStr>::Err: std::fmt::Debug {
    let mut val = String::new();
    stdin().read_line(&mut val).expect("Failed to read line");
    val.split_whitespace()
        .map(|x|
            x.parse::<T>().expect("Failed to parse value"))
        .take(count).collect()
}

pub fn mashmokh() {
    let mut ins = get_vals::<usize>(2);
    let (n, k) = (ins.remove(0), ins.remove(0));
    let mut dp = vec![vec![0 as u32; k]; n];
    for x in dp[0].iter_mut() {
        *x = 1;
    }
    for i in dp.iter_mut() {
        i[0] = 1;
    }
    for i in 1..dp.len() {
        for j in 1..dp[i].len() {
            dp[i][j] = factor(i as i64 + 1)
                .into_iter()
                .map(|x| dp[x as usize - 1][j - 1])
                .sum()
        }
    }
    let ans: u32 = dp.iter_mut().map(|x| x[(k - 1) as usize]).sum();
    for i in dp {
        for j in i {
            print!("{0: <2}", j);
        }
        println!();
    }
    println!("{}", ans % 1000000007)
}

pub fn factor(input: i64) -> Vec<i64> {
    let mut vector = vec![];

    for count in 1..(input + 1) {
        if input % count == 0 {
            vector.push(count);
        }
    }

    return vector;
}


use std::str::FromStr;
use std::io::stdin;

fn get_vals<T>(count: usize) -> Vec<T> where
    T: FromStr,
    <T as std::str::FromStr>::Err: std::fmt::Debug {
    let mut val = String::new();
    stdin().read_line(&mut val).expect("Failed to read line");
    val.split_whitespace()
        .map(|x|
            x.parse::<T>().expect("Failed to parse value"))
        .take(count).collect()
}

fn main() {
    let mut ins = get_vals::<usize>(2);
    let (n, k) = (ins.remove(0), ins.remove(0));
    let mut dp = vec![vec![0 as u32; k]; n];
    for x in dp[0].iter_mut() {
        *x = 1;
    }
    for i in dp.iter_mut() {
        i[0] = 1;
    }
    for i in 1..dp.len() {
        for j in 1..dp[i].len() {
            dp[i][j] = factor(i as i64 + 1)
                .into_iter()
                .map(|x| dp[x as usize - 1][j - 1])
                .sum()
        }
    }
    let ans: u32 = dp.iter_mut().map(|x| x[(k - 1) as usize]).sum();
    // for i in dp {
    //     for j in i {
    //         print!("{0: <2}", j);
    //     }
    //     println!();
    // }
    println!("{}", ans % 1000000007)
}

pub fn factor(input: i64) -> Vec<i64> {
    let mut vector = vec![];

    for count in 1..(input + 1) {
        if input % count == 0 {
            vector.push(count);
        }
    }

    return vector;
}


use std::str::FromStr;
use std::io::stdin;

fn get_vals<T>(count: usize) -> Vec<T> where
    T: FromStr,
    <T as std::str::FromStr>::Err: std::fmt::Debug {
    let mut val = String::new();
    stdin().read_line(&mut val).expect("Failed to read line");
    val.split_whitespace()
        .map(|x|
            x.parse::<T>().expect("Failed to parse value"))
        .take(count).collect()
}

fn main() {
    let mut ins = get_vals::<usize>(2);
    let (n, k) = (ins.remove(0), ins.remove(0));
    let mut dp = vec![vec![0 as u64; k]; n];
    for x in dp[0].iter_mut() {
        *x = 1;
    }
    for i in dp.iter_mut() {
        i[0] = 1;
    }
    for i in 1..dp.len() {
        for j in 1..dp[i].len() {
            dp[i][j] = factor((i as u64) + 1)
                .into_iter()
                .map(|x| dp[(x as usize) - 1][j - 1])
                .sum()
        }
    }
    let ans: u64 = dp.iter_mut().map(|x| x[k - 1] as u64).sum();
    println!("{}", ans % 1000000007)
}

pub fn factor(input: u64) -> Vec<u64> {
    let mut vector = vec![];

    // for count in 1..(input + 1) {
    //     if input % count == 0 {
    //         vector.push(count);
    //     }
    // }

    let mut i = 1;
    while i * i <= input {
        if input % i == 0 {
            vector.push(i);
            if i != input / i {
                vector.push(input / i);
            }
        }
        i += 1;
    }

    vector
}


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 read_line_vec() -> Vec<u32> {
    return read_line().split(' ')
        .map(|s| s.parse().unwrap())
        .collect();
}

fn resolve(n: u32) -> String {
    let s = match n {
        0 => "zero",
        10 => "ten",
        1 => "one",
        11 => "eleven",
        2 => "two",
        12 => "twelve",
        20 => "twenty",
        3 => "three",
        13 => "thirteen",
        30 => "thirty",
        4 => "four",
        14 => "fourteen",
        40 => "forty",
        5 => "five",
        15 => "fifteen",
        50 => "fifty",
        6 => "six",
        16 => "sixteen",
        60 => "sixty",
        7 => "seven",
        17 => "seventeen",
        70 => "seventy",
        8 => "eight",
        18 => "eighteen",
        80 => "eighty",
        9 => "nine",
        19 => "nineteen",
        90 => "ninety",
        _ => panic!("WHAAAAT")
    };
    return String::from(s);
}

fn main() {
    let n: u32 = read_line().parse().unwrap();
    if n <= 20 {
        let s = resolve(n);
        println!("{}", s);
    } else {
        let s2 = resolve(n % 10);
        let s1 = resolve(10 * (n / 10));
        println!("{}-{}", s1, s2);
    }
}


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

fn solution(input: String) {
    let max_fits = input.len() / 11;
    let possible_fits = input.chars().filter_map(|x| {
        if x == '8' {
            Some(1)
        } else {
            None
        }
    }).sum();
    println!("{:?}", cmp::min(possible_fits, max_fits));
}

pub fn main() {
    let mut input = String::new();
    io::stdin().read_line(&mut input);
    input.clear();
    match io::stdin().read_line(&mut input) {
        Ok(n) => {
            solution(input)
        }
        Err(error) => println!("error: {}", error),
    }
}


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

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 : Vec<&str> = buffer.split_whitespace().collect();
    let mut num_8 = 0;
    let mut tot = 0;
    for i in arr[1].chars() {
        let d = i as u8 - '0' as u8;
        if d == 8 {
            num_8 += 1;
        }
        tot += 1;
    }

    let mut ans = -1;
    for i in 1..num_8+1 {
        let m = (tot-i)/10;
        use std::cmp;
        let h = cmp::min(m,i);
        if ans == -1 {
            ans = h;
        } else {
            ans = cmp::max(h,ans);
        }
    }

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


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

use std::collections::*;
use std::io::*;
use std::cmp::{min, max};
use std::f64::consts::*;
use std::mem::swap;
use std::fs::File;
use std::rc::*;
use std::ascii::*;
use std::ops::*;

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

#[derive(PartialEq, PartialOrd, Eq, Ord, Copy, Clone)]
struct Pair<A: Eq + Ord + Copy + Clone, B: Eq + Ord + Copy + Clone>(A, B);

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

impl<Buf: BufRead> Input<Buf>
{
	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()
	}
	#[inline]
	fn read_int(&mut self) -> i32 {
		self.read_word().parse::<i32>().expect("Parsing error")
	}
	#[inline]
	fn read_long(&mut self) -> i64 {
		self.read_word().parse::<i64>().expect("Parsing error")
	}
	#[inline]
	fn read_usize(&mut self) -> usize {
		self.read_word().parse::<usize>().expect("Parsing error")
	}
	#[inline]
	fn read_double(&mut self) -> f64 {
		self.read_word().parse::<f64>().expect("Parsing error")
	}
}
macro_rules! read {
    () => {};
	($inf:ident,$($t:ty),*) => ({($({$inf.read_word().parse::<$t>().expect("Parsing error")}),*)});
}
fn gcd<T: RemAssign + Ord + From<i32> + Copy + Clone>(x: T, y: T) -> T {
	let (mut a, mut b) = (x, y);
	while b > T::from(0) {
		a %= b;
		swap(&mut a, &mut b);
	}
	a
}

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 mut ouf = BufWriter::new(stdout());
			solve(&mut inf, &mut ouf);
		}
		Err(_e) => {
			let mut inf = Input { buffer: BufReader::new(stdin()) };
			let mut ouf = BufWriter::new(stdout());
			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 w = vec![0usize; 2 * n];
	for i in 0..2 * n {
		w[i] = read!(inf,usize);
	}
	w.sort();
	let mut ans = MOD;
	for i in 0..3 {
		let mut pos = i;
		let mut p = 0;
		while pos < 2 * n - 2 + i {
			p += w[pos + 1] - w[pos];
			pos += 2;
		}
		ans = min(ans, p);
	}
	writeln!(ouf, "{}", ans);
}


use std::io;
use std::str::FromStr;

use std::io::prelude::*;
use std::io::BufReader;
use std::cmp::{max, min};

fn get_line() -> String {
    let mut input = String::new();
    io::stdin().read_line(&mut input).unwrap();
    input
}

fn get_vec<T>() -> Vec<T>
    where T: FromStr,
          <T as FromStr>::Err: std::fmt::Debug,
{
    get_line().split_whitespace().map(|k| k.parse().unwrap()).collect()
}

fn main() {
    let n: usize = get_line().trim().parse().unwrap();

    let mut w: Vec<i32> = get_vec();

    w.sort();

    let ans = (0..3).map(|i| {
        w.iter().cloned().skip(i).take(2 * (n - 1)).fold((0, false), |acc, x| {
            (if acc.1 {
                acc.0 + x
            } else {
                acc.0 - x
            }, !acc.1)
        }).0
    }).min().unwrap();

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


use std::io;

fn main() {
	let mut players = String::new();
	io::stdin().read_line(&mut players).unwrap();

	let mut same_player_count = 0;
	let mut prev_player = 'a';
	let mut out = "NO";
	for player in players.trim().chars() {
		if player == prev_player {
			same_player_count += 1;
		} else {
			same_player_count = 0;
		}
		if same_player_count == 7 {
			out = "YES";
			break
		}
		prev_player = player;
	}
	println!("{}", out);
}


fn main() {
    let mut buf = String::new();
    std::io::stdin().read_line(&mut buf).unwrap();

    let line = buf.trim_end();

    if line.len() < 7 {
        println!("NO");
        return;
    }

    for index in 0..(line.len() - 7) {
        let substr: String = line.chars().skip(index).take(7).collect();

        if substr == "0000000" || substr == "1111111" {
            println!("YES");
            return;
        }
    }

    println!("NO");
}