//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")
    };
}

//

const MOD: u64 = 1_000_000_007;

fn mod_pow(r: u64, mut n: u64) -> u64 {
    let mut t = 1;
    let mut s = r % MOD;
    while n > 0 {
        if n & 1 == 1 {
            t = t * s % MOD;
        }
        s = s * s % MOD;
        n >>= 1;
    }
    t
}

fn run() {
    input! {
        n: u64,
        m: u64,
        k: i32,
    }
    let mut ans = if k == 1 {
        1 + (mod_pow(2, n - 1) - 1) * (mod_pow(2, m - 1) - 1)
    } else {
        mod_pow(2, n - 1) * mod_pow(2, m - 1)
    };
    ans %= MOD;
    println!("{}", ans);
}

fn main() {
    run();
}


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

const p: i64 = 1_000_000_007;

fn main() {
    let (n, m, k) = {
        let input = get_line();
        let mut it = input.split_whitespace().map(|x| x.parse::<i64>().unwrap());
        (
            it.next().unwrap(),
            it.next().unwrap(),
            it.next().unwrap(),
            )
    };

    // (2^{n - 1})^{m - 1}
    // 2^{n + m - 2}

    if k == -1 && (n + m) % 2 != 0 {
        println!("0");
        return;
    }

    let n0 = ((n - 1) % p) * ((m - 1) % p) % p;

    let mut two_pow_two_pow = Vec::new();

    let mul = |a, b| {
        ((a % p) * (b % p)) % p
    };

    let mut i = 2;
    for _ in 0..40 {
        two_pow_two_pow.push(i);
        i = mul(i, i);
    }

    let mut ans = 1;

    for i in 0..40 {
        if n0 & (1 << i) != 0 {
            ans = mul(ans, two_pow_two_pow[i]);
        }
    }

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


fn read_line() -> String {
    let stdin = std::io::stdin();
    let mut line = String::new();
    stdin.read_line(&mut line).unwrap();
    String::from(line.trim())
}

macro_rules! scan_line {
    ($($ty: ty),*) => {{
        let line = read_line();
        let mut tok = line.split_whitespace();
        ($(tok.next().unwrap().parse::<$ty>().unwrap()),*)
    }}
}

const MOD: i64 = 1_000_000_007;

fn pow_with_mod(mut a: i64, mut n: i64) -> i64 {
    let mut acc = 1;
    a = a % MOD;
    while n > 0 {
        if n & 1 == 1 {
            acc = (acc * a) % MOD;
        }
        a = (a * a) % MOD;
        n >>= 1;
    }
    acc
}

fn main() {
    let (n, m, _) = scan_line!(i64, i64, i32);
    let ans = if n % 2 != m % 2 {
        0
    } else {
        pow_with_mod(pow_with_mod(2, n - 1), m - 1)
    };
    println!("{}", ans);
}


// ---------- begin Matrix ----------
#[allow(dead_code)]
mod matrix {
    use std::ops::{Add, Mul};
    pub trait SemiRing: Add<Output = Self> + Mul<Output = Self> + Copy {
        fn zero() -> Self;
        fn one() -> Self;
    }
    pub const SIZE: usize = 128;
    #[derive(Clone)]
    pub struct SquareMatrix<T: SemiRing> {
        buf: [[T; SIZE]; SIZE],
    }
    impl<T: SemiRing> SquareMatrix<T> {
        pub fn zero() -> Self {
            let z = T::zero();
            SquareMatrix {
                buf: [[z; SIZE]; SIZE],
            }
        }
        pub fn identity() -> Self {
            let mut m = Self::zero();
            for i in 0..SIZE {
                m.buf[i][i] = T::one();
            }
            m
        }
        pub fn get_mut(&mut self, i: usize, j: usize) -> &mut T {
            &mut self.buf[i][j]
        }
        pub fn get(&self, i: usize, j: usize) -> &T {
            &self.buf[i][j]
        }
        pub fn matmul(&self, rhs: &Self) -> Self {
            let mut res = Self::zero();
            for (x, a) in res.buf.iter_mut().zip(self.buf.iter()) {
                for (a, b) in a.iter().zip(rhs.buf.iter()) {
                    for (x, b) in x.iter_mut().zip(b.iter()) {
                        *x = *x + *a * *b;
                    }
                }
            }
            res
        }
        pub fn matadd(&self, rhs: &Self) -> Self {
            let mut c = Self::zero();
            for (c, (a, b)) in c.buf.iter_mut().zip(self.buf.iter().zip(rhs.buf.iter())) {
                for (c, (a, b)) in c.iter_mut().zip(a.iter().zip(b.iter())) {
                    *c = *a + *b;
                }
            }
            c
        }
        pub fn matpow(&self, mut n: usize) -> Self {
            let mut t = Self::identity();
            let mut s = self.clone();
            while n > 0 {
                if n & 1 == 1 {
                    t = t.matmul(&s);
                }
                s = s.matmul(&s);
                n >>= 1;
            }
            t
        }
    }
}
// ---------- end Matrix ----------
// ---------- begin ModInt ----------
mod modint {

    #[allow(dead_code)]
    pub struct Mod;
    impl ConstantModulo for Mod {
        const MOD: u32 = 1_000_000_007;
    }

    #[allow(dead_code)]
    pub struct StaticMod;
    static mut STATIC_MOD: u32 = 0;
    impl Modulo for StaticMod {
        fn modulo() -> u32 {
            unsafe { STATIC_MOD }
        }
    }

    #[allow(dead_code)]
    impl StaticMod {
        pub fn set_modulo(p: u32) {
            unsafe {
                STATIC_MOD = p;
            }
        }
    }

    use std::marker::*;
    use std::ops::*;

    pub trait Modulo {
        fn modulo() -> u32;
    }

    pub trait ConstantModulo {
        const MOD: u32;
    }

    impl<T> Modulo for T
    where
        T: ConstantModulo,
    {
        fn modulo() -> u32 {
            T::MOD
        }
    }

    pub struct ModInt<T>(pub u32, PhantomData<T>);

    impl<T> Clone for ModInt<T> {
        fn clone(&self) -> Self {
            ModInt::new_unchecked(self.0)
        }
    }

    impl<T> Copy for ModInt<T> {}

    impl<T: Modulo> Add for ModInt<T> {
        type Output = ModInt<T>;
        fn add(self, rhs: Self) -> Self::Output {
            let mut d = self.0 + rhs.0;
            if d >= T::modulo() {
                d -= T::modulo();
            }
            ModInt::new_unchecked(d)
        }
    }

    impl<T: Modulo> AddAssign for ModInt<T> {
        fn add_assign(&mut self, rhs: Self) {
            *self = *self + rhs;
        }
    }

    impl<T: Modulo> Sub for ModInt<T> {
        type Output = ModInt<T>;
        fn sub(self, rhs: Self) -> Self::Output {
            let mut d = T::modulo() + self.0 - rhs.0;
            if d >= T::modulo() {
                d -= T::modulo();
            }
            ModInt::new_unchecked(d)
        }
    }

    impl<T: Modulo> SubAssign for ModInt<T> {
        fn sub_assign(&mut self, rhs: Self) {
            *self = *self - rhs;
        }
    }

    impl<T: Modulo> Mul for ModInt<T> {
        type Output = ModInt<T>;
        fn mul(self, rhs: Self) -> Self::Output {
            let v = self.0 as u64 * rhs.0 as u64 % T::modulo() as u64;
            ModInt::new_unchecked(v as u32)
        }
    }

    impl<T: Modulo> MulAssign for ModInt<T> {
        fn mul_assign(&mut self, rhs: Self) {
            *self = *self * rhs;
        }
    }

    impl<T: Modulo> Neg for ModInt<T> {
        type Output = ModInt<T>;
        fn neg(self) -> Self::Output {
            if self.0 == 0 {
                Self::zero()
            } else {
                Self::new_unchecked(T::modulo() - self.0)
            }
        }
    }

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

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

    impl<T: Modulo> From<usize> for ModInt<T> {
        fn from(val: usize) -> ModInt<T> {
            ModInt::new_unchecked((val % T::modulo() as usize) as u32)
        }
    }

    impl<T: Modulo> From<u64> for ModInt<T> {
        fn from(val: u64) -> ModInt<T> {
            ModInt::new_unchecked((val % T::modulo() as u64) as u32)
        }
    }

    impl<T: Modulo> From<i64> for ModInt<T> {
        fn from(val: i64) -> ModInt<T> {
            let m = T::modulo() as i64;
            ModInt::new((val % m + m) as u32)
        }
    }

    #[allow(dead_code)]
    impl<T> ModInt<T> {
        pub fn new_unchecked(d: u32) -> Self {
            ModInt(d, PhantomData)
        }
        pub fn zero() -> Self {
            ModInt::new_unchecked(0)
        }
        pub fn one() -> Self {
            ModInt::new_unchecked(1)
        }
        pub fn is_zero(&self) -> bool {
            self.0 == 0
        }
    }

    #[allow(dead_code)]
    impl<T: Modulo> ModInt<T> {
        pub fn new(d: u32) -> Self {
            ModInt::new_unchecked(d % T::modulo())
        }
        pub fn pow(&self, mut n: u64) -> Self {
            let mut t = Self::one();
            let mut s = *self;
            while n > 0 {
                if n & 1 == 1 {
                    t *= s;
                }
                s *= s;
                n >>= 1;
            }
            t
        }
        pub fn inv(&self) -> Self {
            assert!(self.0 != 0);
            self.pow(T::modulo() as u64 - 2)
        }
    }

    #[allow(dead_code)]
    pub fn mod_pow(r: u64, mut n: u64, m: u64) -> u64 {
        let mut t = 1 % m;
        let mut s = r % m;
        while n > 0 {
            if n & 1 == 1 {
                t = t * s % m;
            }
            s = s * s % m;
            n >>= 1;
        }
        t
    }
}
// ---------- end ModInt ----------
// ---------- begin Precalc ----------
mod precalc {
    use super::modint::*;
    #[allow(dead_code)]
    pub struct Precalc<T> {
        inv: Vec<ModInt<T>>,
        fact: Vec<ModInt<T>>,
        ifact: Vec<ModInt<T>>,
    }
    #[allow(dead_code)]
    impl<T: Modulo> Precalc<T> {
        pub fn new(n: usize) -> Precalc<T> {
            let mut inv = vec![ModInt::one(); n + 1];
            let mut fact = vec![ModInt::one(); n + 1];
            let mut ifact = vec![ModInt::one(); n + 1];
            for i in 2..(n + 1) {
                fact[i] = fact[i - 1] * ModInt::new_unchecked(i as u32);
            }
            ifact[n] = fact[n].inv();
            if n > 0 {
                inv[n] = ifact[n] * fact[n - 1];
            }
            for i in (1..n).rev() {
                ifact[i] = ifact[i + 1] * ModInt::new_unchecked((i + 1) as u32);
                inv[i] = ifact[i] * fact[i - 1];
            }
            Precalc {
                inv: inv,
                fact: fact,
                ifact: ifact,
            }
        }
        pub fn inv(&self, n: usize) -> ModInt<T> {
            assert!(n > 0);
            self.inv[n]
        }
        pub fn fact(&self, n: usize) -> ModInt<T> {
            self.fact[n]
        }
        pub fn ifact(&self, n: usize) -> ModInt<T> {
            self.ifact[n]
        }
        pub fn perm(&self, n: usize, k: usize) -> ModInt<T> {
            if k > n {
                return ModInt::zero();
            }
            self.fact[n] * self.ifact[n - k]
        }
        pub fn comb(&self, n: usize, k: usize) -> ModInt<T> {
            if k > n {
                return ModInt::zero();
            }
            self.fact[n] * self.ifact[k] * self.ifact[n - k]
        }
    }
}
// ---------- end Precalc ----------
// ---------- begin input macro ----------
// reference: 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, bytes) => {
        read_value!($iter, String).bytes().collect::<Vec<u8>>()
    };
    ($iter:expr, usize1) => {
        read_value!($iter, usize) - 1
    };
    ($iter:expr, $t:ty) => {
        $iter.next().unwrap().parse::<$t>().expect("Parse error")
    };
}
// ---------- end input macro ----------

use modint::*;
type M = ModInt<Mod>;

use matrix::*;
type Mat = SquareMatrix<M>;

impl SemiRing for M {
    fn zero() -> Self {
        M::zero()
    }
    fn one() -> Self {
        M::one()
    }
}

fn run() {
    input! {
        w: [usize; 7],
    }
    // 0: 置いてok
    // 1: おいたらダメ
    let mut mat = vec![];
    for i in 1..=7 {
        let mut m = Mat::zero();
        for j in 0..(1 << i) {
            for k in 0..(1 << (2 * i - 1)) {
                if j & k > 0 {
                    continue;
                }
                let mut next = 0;
                for x in 0..i {
                    let left = x == 0 || (k >> (i + x - 1)) & 1 == 1;
                    let down = k >> x & 1 == 1;
                    let right = x == i - 1 || (k >> (i + x)) & 1 == 1;
                    if left && down && right {
                        next |= 1 << x;
                    }
                }
                *m.get_mut(next, j) += M::one();
            }
        }
        mat.push(m);
        let mut m = Mat::zero();
        for j in 0..(1 << i) {
            *m.get_mut(j, j) = M::one();
        }
        mat.push(m);
    }
    let mul = |m: &Mat, b: &[M]| -> Vec<M> {
        let mut res = vec![M::zero(); b.len()];
        for i in 0..b.len() {
            for j in 0..b.len() {
                res[i] += *m.get(i, j) * b[j];
            }
        }
        res
    };
    let mut b = vec![M::zero(); 1 << 7];
    let mut ini = false;
    let mut w = w;
    for (i, (w, mat)) in w.iter_mut().zip(mat.chunks(2)).enumerate().rev() {
        if !ini && *w > 0 {
            *w -= 1;
            ini = true;
            let i = i + 1;
            for k in 0..(1 << (i - 1)) {
                let mut bit = 0;
                for x in 0..i {
                    let left = x == 0 || k >> (x - 1) & 1 == 1;
                    let down = true;
                    let right = x == i - 1 || k >> x & 1 == 1;
                    if left && right && down {
                        bit |= 1 << x;
                    }
                }
                b[bit] += M::one();
            }
        }
        b = mul(&mat[1], &b);
        b = mul(&mat[0].matpow(*w), &b);
    }
    let ans = b[0];
    println!("{}", ans);
}

fn main() {
    run();
}


// ---------- begin Matrix ----------
mod matrix {
    use std::ops::*;
    pub trait SemiRing: Add<Output = Self> + Mul<Output = Self> + Copy {
        fn zero() -> Self;
        fn one() -> Self;
    }
    #[derive(Clone)]
    pub struct SquareMatrix<R> {
        size: usize,
        buf: Box<[R]>,
    }
    #[allow(dead_code)]
    impl<R: SemiRing> SquareMatrix<R> {
        pub fn zero(size: usize) -> Self {
            SquareMatrix {
                size: size,
                buf: vec![R::zero(); size * size].into_boxed_slice(),
            }
        }
        pub fn identity(size: usize) -> Self {
            let mut e = Self::zero(size);
            for i in 0..size {
                e.buf[i * size + i] = R::one();
            }
            e
        }
        pub fn get(&self, x: usize, y: usize) -> &R {
            assert!(x < self.size && y < self.size);
            &self.buf[x * self.size + y]
        }
        pub fn get_mut(&mut self, x: usize, y: usize) -> &mut R {
            assert!(x < self.size && y < self.size);
            &mut self.buf[x * self.size + y]
        }
        pub fn matadd(&self, rhs: &Self) -> Self {
            assert!(self.size == rhs.size);
            let buf: Vec<R> = self
                .buf
                .iter()
                .zip(rhs.buf.iter())
                .map(|p| *p.0 + *p.1)
                .collect();
            SquareMatrix {
                size: self.size,
                buf: buf.into_boxed_slice(),
            }
        }
        pub fn matmul(&self, rhs: &Self) -> Self {
            let size = self.size;
            assert!(size == rhs.size);
            let mut res = Self::zero(size);
            for (x, a) in res.buf.chunks_mut(size).zip(self.buf.chunks(size)) {
                for (a, b) in a.iter().zip(rhs.buf.chunks(size)) {
                    for (x, b) in x.iter_mut().zip(b.iter()) {
                        *x = *x + *a * *b;
                    }
                }
            }
            res
        }
        pub fn mat_pow(&self, mut n: usize) -> Self {
            let size = self.size;
            let mut t = Self::identity(size);
            let mut s = self.clone();
            while n > 0 {
                if n & 1 == 1 {
                    t = t.matmul(&s);
                }
                s = s.matmul(&s);
                n >>= 1;
            }
            t
        }
    }
    #[allow(dead_code)]
    impl<R: SemiRing + Sub<Output = R>> SquareMatrix<R> {
        pub fn matsub(&self, rhs: &Self) -> Self {
            assert!(self.size == rhs.size);
            let buf: Vec<R> = self
                .buf
                .iter()
                .zip(rhs.buf.iter())
                .map(|p| *p.0 - *p.1)
                .collect();
            SquareMatrix {
                size: self.size,
                buf: buf.into_boxed_slice(),
            }
        }
    }
}
// ---------- end Matrix ----------
// ---------- begin ModInt ----------
mod modint {

    #[allow(dead_code)]
    pub struct Mod;
    impl ConstantModulo for Mod {
        const MOD: u32 = 1_000_000_007;
    }

    #[allow(dead_code)]
    pub struct StaticMod;
    static mut STATIC_MOD: u32 = 0;
    impl Modulo for StaticMod {
        fn modulo() -> u32 {
            unsafe { STATIC_MOD }
        }
    }

    #[allow(dead_code)]
    impl StaticMod {
        pub fn set_modulo(p: u32) {
            unsafe {
                STATIC_MOD = p;
            }
        }
    }

    use std::marker::*;
    use std::ops::*;

    pub trait Modulo {
        fn modulo() -> u32;
    }

    pub trait ConstantModulo {
        const MOD: u32;
    }

    impl<T> Modulo for T
    where
        T: ConstantModulo,
    {
        fn modulo() -> u32 {
            T::MOD
        }
    }

    pub struct ModInt<T>(pub u32, PhantomData<T>);

    impl<T> Clone for ModInt<T> {
        fn clone(&self) -> Self {
            ModInt::new_unchecked(self.0)
        }
    }

    impl<T> Copy for ModInt<T> {}

    impl<T: Modulo> Add for ModInt<T> {
        type Output = ModInt<T>;
        fn add(self, rhs: Self) -> Self::Output {
            let mut d = self.0 + rhs.0;
            if d >= T::modulo() {
                d -= T::modulo();
            }
            ModInt::new_unchecked(d)
        }
    }

    impl<T: Modulo> AddAssign for ModInt<T> {
        fn add_assign(&mut self, rhs: Self) {
            *self = *self + rhs;
        }
    }

    impl<T: Modulo> Sub for ModInt<T> {
        type Output = ModInt<T>;
        fn sub(self, rhs: Self) -> Self::Output {
            let mut d = T::modulo() + self.0 - rhs.0;
            if d >= T::modulo() {
                d -= T::modulo();
            }
            ModInt::new_unchecked(d)
        }
    }

    impl<T: Modulo> SubAssign for ModInt<T> {
        fn sub_assign(&mut self, rhs: Self) {
            *self = *self - rhs;
        }
    }

    impl<T: Modulo> Mul for ModInt<T> {
        type Output = ModInt<T>;
        fn mul(self, rhs: Self) -> Self::Output {
            let v = self.0 as u64 * rhs.0 as u64 % T::modulo() as u64;
            ModInt::new_unchecked(v as u32)
        }
    }

    impl<T: Modulo> MulAssign for ModInt<T> {
        fn mul_assign(&mut self, rhs: Self) {
            *self = *self * rhs;
        }
    }

    impl<T: Modulo> Neg for ModInt<T> {
        type Output = ModInt<T>;
        fn neg(self) -> Self::Output {
            if self.0 == 0 {
                Self::zero()
            } else {
                Self::new_unchecked(T::modulo() - self.0)
            }
        }
    }

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

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

    impl<T: Modulo> From<usize> for ModInt<T> {
        fn from(val: usize) -> ModInt<T> {
            ModInt::new_unchecked((val % T::modulo() as usize) as u32)
        }
    }

    impl<T: Modulo> From<u64> for ModInt<T> {
        fn from(val: u64) -> ModInt<T> {
            ModInt::new_unchecked((val % T::modulo() as u64) as u32)
        }
    }

    impl<T: Modulo> From<i64> for ModInt<T> {
        fn from(val: i64) -> ModInt<T> {
            let m = T::modulo() as i64;
            ModInt::new((val % m + m) as u32)
        }
    }

    #[allow(dead_code)]
    impl<T> ModInt<T> {
        pub fn new_unchecked(d: u32) -> Self {
            ModInt(d, PhantomData)
        }
        pub fn zero() -> Self {
            ModInt::new_unchecked(0)
        }
        pub fn one() -> Self {
            ModInt::new_unchecked(1)
        }
        pub fn is_zero(&self) -> bool {
            self.0 == 0
        }
    }

    #[allow(dead_code)]
    impl<T: Modulo> ModInt<T> {
        pub fn new(d: u32) -> Self {
            ModInt::new_unchecked(d % T::modulo())
        }
        pub fn pow(&self, mut n: u64) -> Self {
            let mut t = Self::one();
            let mut s = *self;
            while n > 0 {
                if n & 1 == 1 {
                    t *= s;
                }
                s *= s;
                n >>= 1;
            }
            t
        }
        pub fn inv(&self) -> Self {
            assert!(self.0 != 0);
            self.pow(T::modulo() as u64 - 2)
        }
    }

    #[allow(dead_code)]
    pub fn mod_pow(r: u64, mut n: u64, m: u64) -> u64 {
        let mut t = 1 % m;
        let mut s = r % m;
        while n > 0 {
            if n & 1 == 1 {
                t = t * s % m;
            }
            s = s * s % m;
            n >>= 1;
        }
        t
    }
}
// ---------- end ModInt ----------
// ---------- begin Precalc ----------
mod precalc {
    use super::modint::*;
    #[allow(dead_code)]
    pub struct Precalc<T> {
        inv: Vec<ModInt<T>>,
        fact: Vec<ModInt<T>>,
        ifact: Vec<ModInt<T>>,
    }
    #[allow(dead_code)]
    impl<T: Modulo> Precalc<T> {
        pub fn new(n: usize) -> Precalc<T> {
            let mut inv = vec![ModInt::one(); n + 1];
            let mut fact = vec![ModInt::one(); n + 1];
            let mut ifact = vec![ModInt::one(); n + 1];
            for i in 2..(n + 1) {
                fact[i] = fact[i - 1] * ModInt::new_unchecked(i as u32);
            }
            ifact[n] = fact[n].inv();
            if n > 0 {
                inv[n] = ifact[n] * fact[n - 1];
            }
            for i in (1..n).rev() {
                ifact[i] = ifact[i + 1] * ModInt::new_unchecked((i + 1) as u32);
                inv[i] = ifact[i] * fact[i - 1];
            }
            Precalc {
                inv: inv,
                fact: fact,
                ifact: ifact,
            }
        }
        pub fn inv(&self, n: usize) -> ModInt<T> {
            assert!(n > 0);
            self.inv[n]
        }
        pub fn fact(&self, n: usize) -> ModInt<T> {
            self.fact[n]
        }
        pub fn ifact(&self, n: usize) -> ModInt<T> {
            self.ifact[n]
        }
        pub fn perm(&self, n: usize, k: usize) -> ModInt<T> {
            if k > n {
                return ModInt::zero();
            }
            self.fact[n] * self.ifact[n - k]
        }
        pub fn comb(&self, n: usize, k: usize) -> ModInt<T> {
            if k > n {
                return ModInt::zero();
            }
            self.fact[n] * self.ifact[k] * self.ifact[n - k]
        }
    }
}
// ---------- end Precalc ----------
// ---------- begin input macro ----------
// reference: 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, bytes) => {
        read_value!($iter, String).bytes().collect::<Vec<u8>>()
    };
    ($iter:expr, usize1) => {
        read_value!($iter, usize) - 1
    };
    ($iter:expr, $t:ty) => {
        $iter.next().unwrap().parse::<$t>().expect("Parse error")
    };
}
// ---------- end input macro ----------

use modint::*;
type M = ModInt<Mod>;

use matrix::*;
type Mat = SquareMatrix<M>;

impl SemiRing for M {
    fn zero() -> Self {
        M::zero()
    }
    fn one() -> Self {
        M::one()
    }
}

fn run() {
    input! {
        w: [usize; 7],
    }
    // 0: 置いてok
    // 1: おいたらダメ
    let mut mat = vec![];
    for i in 1..=7 {
        let mut m = Mat::zero(1 << 7);
        for j in 0..(1 << i) {
            for k in 0..(1 << (2 * i - 1)) {
                if j & k > 0 {
                    continue;
                }
                let mut next = 0;
                for x in 0..i {
                    let left = x == 0 || (k >> (i + x - 1)) & 1 == 1;
                    let down = k >> x & 1 == 1;
                    let right = x == i - 1 || (k >> (i + x)) & 1 == 1;
                    if left && down && right {
                        next |= 1 << x;
                    }
                }
                *m.get_mut(next, j) += M::one();
            }
        }
        mat.push(m);
        let mut m = Mat::zero(1 << 7);
        for j in 0..(1 << i) {
            *m.get_mut(j, j) = M::one();
        }
        mat.push(m);
    }
    let mul = |m: &Mat, b: &[M]| -> Vec<M> {
        let mut res = vec![M::zero(); b.len()];
        for i in 0..b.len() {
            for j in 0..b.len() {
                res[i] += *m.get(i, j) * b[j];
            }
        }
        res
    };
    let mut b = vec![M::zero(); 1 << 7];
    let mut ini = false;
    let mut w = w;
    for (i, (w, mat)) in w.iter_mut().zip(mat.chunks(2)).enumerate().rev() {
        if !ini && *w > 0 {
            *w -= 1;
            ini = true;
            let i = i + 1;
            for k in 0..(1 << (i - 1)) {
                let mut bit = 0;
                for x in 0..i {
                    let left = x == 0 || k >> (x - 1) & 1 == 1;
                    let down = true;
                    let right = x == i - 1 || k >> x & 1 == 1;
                    if left && right && down {
                        bit |= 1 << x;
                    }
                }
                b[bit] += M::one();
            }
        }
        b = mul(&mat[1], &b);
        b = mul(&mat[0].mat_pow(*w), &b);
    }
    let ans = b[0];
    println!("{}", ans);
}

fn main() {
    run();
}


// ---------- begin ModInt ----------
mod modint {

    #[allow(dead_code)]
    pub struct Mod;
    impl Modulo for Mod {
        fn modulo() -> u32 {
            1_000_000_007
        }
        fn rem() -> u32 {
            2226617417
        }
        fn ini() -> u64 {
            582344008
        }
    }

    use std::marker::*;
    use std::ops::*;

    pub trait Modulo {
        fn modulo() -> u32;
        fn rem() -> u32;
        fn ini() -> u64;
    }

    pub struct ModInt<T>(pub u32, PhantomData<T>);

    impl<T: Modulo> Clone for ModInt<T> {
        fn clone(&self) -> Self {
            Self::new_unchecked(self.0)
        }
    }

    impl<T: Modulo> Copy for ModInt<T> {}

    impl<T: Modulo> Add for ModInt<T> {
        type Output = ModInt<T>;
        fn add(self, rhs: Self) -> Self::Output {
            let mut d = self.0 + rhs.0;
            if d >= T::modulo() {
                d -= T::modulo();
            }
            Self::new_unchecked(d)
        }
    }

    impl<T: Modulo> AddAssign for ModInt<T> {
        fn add_assign(&mut self, rhs: Self) {
            *self = *self + rhs;
        }
    }

    impl<T: Modulo> Sub for ModInt<T> {
        type Output = ModInt<T>;
        fn sub(self, rhs: Self) -> Self::Output {
            let mut d = T::modulo() + self.0 - rhs.0;
            if d >= T::modulo() {
                d -= T::modulo();
            }
            ModInt::new_unchecked(d)
        }
    }

    impl<T: Modulo> SubAssign for ModInt<T> {
        fn sub_assign(&mut self, rhs: Self) {
            *self = *self - rhs;
        }
    }

    impl<T: Modulo> Mul for ModInt<T> {
        type Output = ModInt<T>;
        fn mul(self, rhs: Self) -> Self::Output {
            ModInt::new_unchecked(Self::reduce(self.0 as u64 * rhs.0 as u64))
        }
    }

    impl<T: Modulo> MulAssign for ModInt<T> {
        fn mul_assign(&mut self, rhs: Self) {
            *self = *self * rhs;
        }
    }

    impl<T: Modulo> Neg for ModInt<T> {
        type Output = ModInt<T>;
        fn neg(self) -> Self::Output {
            if self.0 == 0 {
                Self::zero()
            } else {
                Self::new_unchecked(T::modulo() - self.0)
            }
        }
    }

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

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

    impl<T: Modulo> From<usize> for ModInt<T> {
        fn from(val: usize) -> ModInt<T> {
            ModInt::new_unchecked((val % T::modulo() as usize) as u32)
        }
    }

    impl<T: Modulo> From<u64> for ModInt<T> {
        fn from(val: u64) -> ModInt<T> {
            ModInt::new_unchecked((val % T::modulo() as u64) as u32)
        }
    }

    impl<T: Modulo> From<i64> for ModInt<T> {
        fn from(val: i64) -> ModInt<T> {
            let m = T::modulo() as i64;
            ModInt::new((val % m + m) as u32)
        }
    }

    #[allow(dead_code)]
    impl<T: Modulo> ModInt<T> {
        fn reduce(x: u64) -> u32 {
            let b = (x as u32 * T::rem()) as u64;
            let t = x + b * T::modulo() as u64;
            let mut c = (t >> 32) as u32;
            if c >= T::modulo() {
                c -= T::modulo();
            }
            c as u32
        }
        fn new_unchecked(d: u32) -> Self {
            Self(d, PhantomData)
        }
        pub fn is_zero(&self) -> bool {
            self.0 == 0
        }
        pub fn new(d: u32) -> Self {
            Self::new_unchecked(Self::reduce(d as u64 * T::ini()))
        }
        pub fn zero() -> Self {
            Self::new(0)
        }
        pub fn one() -> Self {
            Self::new(1)
        }
        pub fn get(&self) -> u32 {
            Self::reduce(self.0 as u64)
        }
        /*
        pub fn pow(&self, mut n: u64) -> Self {
            let mut t = Self::one();
            let mut s = *self;
            while n > 0 {
                if n & 1 == 1 {
                    t *= s;
                }
                s *= s;
                n >>= 1;
            }
            t
        }
        pub fn inv(&self) -> Self {
            assert!(self.0 != 0);
            self.pow(T::modulo() as u64 - 2)
        }
        */
    }

    #[allow(dead_code)]
    pub fn mod_pow(r: u64, mut n: u64, m: u64) -> u64 {
        let mut t = 1 % m;
        let mut s = r % m;
        while n > 0 {
            if n & 1 == 1 {
                t = t * s % m;
            }
            s = s * s % m;
            n >>= 1;
        }
        t
    }
}
// ---------- end ModInt ----------
// ---------- begin Matrix ----------
mod matrix {
    use std::ops::*;
    pub trait SemiRing: Add<Output = Self> + Mul<Output = Self> + Copy {
        fn zero() -> Self;
        fn one() -> Self;
    }
    #[derive(Clone)]
    pub struct SquareMatrix<R> {
        size: usize,
        buf: Box<[R]>,
    }
    #[allow(dead_code)]
    impl<R: SemiRing> SquareMatrix<R> {
        pub fn zero(size: usize) -> Self {
            SquareMatrix {
                size: size,
                buf: vec![R::zero(); size * size].into_boxed_slice(),
            }
        }
        pub fn identity(size: usize) -> Self {
            let mut e = Self::zero(size);
            for i in 0..size {
                e.buf[i * size + i] = R::one();
            }
            e
        }
        pub fn get(&self, x: usize, y: usize) -> &R {
            assert!(x < self.size && y < self.size);
            &self.buf[x * self.size + y]
        }
        pub fn get_mut(&mut self, x: usize, y: usize) -> &mut R {
            assert!(x < self.size && y < self.size);
            &mut self.buf[x * self.size + y]
        }
        pub fn matadd(&self, rhs: &Self) -> Self {
            assert!(self.size == rhs.size);
            let buf: Vec<R> = self
                .buf
                .iter()
                .zip(rhs.buf.iter())
                .map(|p| *p.0 + *p.1)
                .collect();
            SquareMatrix {
                size: self.size,
                buf: buf.into_boxed_slice(),
            }
        }
        pub fn matmul(&self, rhs: &Self) -> Self {
            let size = self.size;
            assert!(size == rhs.size);
            let mut res = Self::zero(size);
            for (x, a) in res.buf.chunks_mut(size).zip(self.buf.chunks(size)) {
                for (a, b) in a.iter().zip(rhs.buf.chunks(size)) {
                    for (x, b) in x.iter_mut().zip(b.iter()) {
                        *x = *x + *a * *b;
                    }
                }
            }
            res
        }
        pub fn mat_pow(&self, mut n: usize) -> Self {
            let size = self.size;
            let mut t = Self::identity(size);
            let mut s = self.clone();
            while n > 0 {
                if n & 1 == 1 {
                    t = t.matmul(&s);
                }
                s = s.matmul(&s);
                n >>= 1;
            }
            t
        }
    }
    #[allow(dead_code)]
    impl<R: SemiRing + Sub<Output = R>> SquareMatrix<R> {
        pub fn matsub(&self, rhs: &Self) -> Self {
            assert!(self.size == rhs.size);
            let buf: Vec<R> = self
                .buf
                .iter()
                .zip(rhs.buf.iter())
                .map(|p| *p.0 - *p.1)
                .collect();
            SquareMatrix {
                size: self.size,
                buf: buf.into_boxed_slice(),
            }
        }
    }
}
// ---------- end Matrix ----------
// ---------- begin input macro ----------
// reference: 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, bytes) => {
        read_value!($iter, String).bytes().collect::<Vec<u8>>()
    };
    ($iter:expr, usize1) => {
        read_value!($iter, usize) - 1
    };
    ($iter:expr, $t:ty) => {
        $iter.next().unwrap().parse::<$t>().expect("Parse error")
    };
}
// ---------- end input macro ----------

use modint::*;
type M = ModInt<Mod>;

use matrix::*;
type Mat = SquareMatrix<M>;

impl SemiRing for M {
    fn zero() -> Self {
        M::zero()
    }
    fn one() -> Self {
        M::one()
    }
}

fn run() {
    input! {
        w: [usize; 7],
    }
    // 0: 置いてok
    // 1: おいたらダメ
    let mut mat = vec![];
    for i in 1..=7 {
        let mut m = Mat::zero(1 << i);
        for j in 0..(1 << i) {
            for k in 0..(1 << (2 * i - 1)) {
                if j & k > 0 {
                    continue;
                }
                let mut next = 0;
                for x in 0..i {
                    let left = x == 0 || (k >> (i + x - 1)) & 1 == 1;
                    let down = k >> x & 1 == 1;
                    let right = x == i - 1 || (k >> (i + x)) & 1 == 1;
                    if left && down && right {
                        next |= 1 << x;
                    }
                }
                *m.get_mut(next, j) += M::one();
            }
        }
        mat.push(m);
        let mut m = Mat::zero(1 << i);
        for j in 0..(1 << i) {
            *m.get_mut(j, j) = M::one();
        }
        mat.push(m);
    }
    let mul = |m: &Mat, b: &[M]| -> Vec<M> {
        let mut res = vec![M::zero(); b.len()];
        for i in 0..b.len() {
            for j in 0..b.len() {
                res[i] += *m.get(i, j) * b[j];
            }
        }
        res
    };
    let mut b = vec![M::zero(); 1 << 7];
    let mut ini = false;
    let mut w = w;
    for (i, (w, mat)) in w.iter_mut().zip(mat.chunks(2)).enumerate().rev() {
        if !ini && *w > 0 {
            *w -= 1;
            ini = true;
            let i = i + 1;
            for k in 0..(1 << (i - 1)) {
                let mut bit = 0;
                for x in 0..i {
                    let left = x == 0 || k >> (x - 1) & 1 == 1;
                    let down = true;
                    let right = x == i - 1 || k >> x & 1 == 1;
                    if left && right && down {
                        bit |= 1 << x;
                    }
                }
                b[bit] += M::one();
            }
        }
        b = mul(&mat[1], &b);
        b = mul(&mat[0].mat_pow(*w), &b);
        b.truncate(1 << i);
    }
    let ans = b[0];
    println!("{}", ans);
}

fn main() {
    run();
}


// ---------- begin ModInt ----------
// モンゴメリ乗算を用いる
// ほぼCodeforces用
// 素数のみ
mod modint {

    use std::marker::*;
    use std::ops::*;

    pub trait Modulo {
        fn modulo() -> u32;
        fn rem() -> u32;
        fn ini() -> u64;
    }

    pub enum Mod1_000_000_007 {}

    impl Modulo for Mod1_000_000_007 {
        fn modulo() -> u32 {
            1_000_000_007
        }
        fn rem() -> u32 {
            2226617417
        }
        fn ini() -> u64 {
            582344008
        }
    }

    #[allow(dead_code)]
    pub enum Mod998_244_353 {}

    impl Modulo for Mod998_244_353 {
        fn modulo() -> u32 {
            998_244_353
        }
        fn rem() -> u32 {
            998244351
        }
        fn ini() -> u64 {
            932051910
        }
    }

    #[allow(dead_code)]
    pub fn generate_umekomi_modulo(p: u32) {
        assert!(p < (1 << 31) && p > 2 && p & 1 == 1 && (2u32..).take_while(|v| v * v <= p).all(|k| p % k != 0));
        let mut t = 1u32;
        let mut s = !p + 1;
        let mut n = !0u32 >> 2;
        while n > 0 {
            if n & 1 == 1 {
                t *= s;
            }
            s *= s;
            n >>= 1;
        }
        let mut ini = (1u64 << 32) % p as u64;
        ini = (ini << 32) % p as u64;
        assert!(t * p == !0);
        println!("pub enum Mod{} {{}}", p);
        println!("impl Modulo for Mod_{} {{", p);
        println!("    fn modulo() -> u32 {{");
        println!("        {}", p);
        println!("    }}");
        println!("    fn rem() -> u32 {{");
        println!("        {}", t);
        println!("    }}");
        println!("    fn ini() -> u32 {{");
        println!("        {}", ini);
        println!("    }}");
    }

    pub struct ModInt<T>(pub u32, PhantomData<T>);

    impl<T> Clone for ModInt<T> {
        fn clone(&self) -> Self {
            ModInt::build(self.0)
        }
    }

    impl<T> Copy for ModInt<T> {}

    impl<T: Modulo> Add for ModInt<T> {
        type Output = ModInt<T>;
        fn add(self, rhs: Self) -> Self::Output {
            let mut d = self.0 + rhs.0;
            if d >= T::modulo() {
                d -= T::modulo();
            }
            Self::build(d)
        }
    }

    impl<T: Modulo> AddAssign for ModInt<T> {
        fn add_assign(&mut self, rhs: Self) {
            *self = *self + rhs;
        }
    }

    impl<T: Modulo> Sub for ModInt<T> {
        type Output = ModInt<T>;
        fn sub(self, rhs: Self) -> Self::Output {
            let mut d = T::modulo() + self.0 - rhs.0;
            if d >= T::modulo() {
                d -= T::modulo();
            }
            Self::build(d)
        }
    }

    impl<T: Modulo> SubAssign for ModInt<T> {
        fn sub_assign(&mut self, rhs: Self) {
            *self = *self - rhs;
        }
    }

    impl<T: Modulo> Mul for ModInt<T> {
        type Output = ModInt<T>;
        fn mul(self, rhs: Self) -> Self::Output {
            Self::build(Self::reduce(self.0 as u64 * rhs.0 as u64))
        }
    }

    impl<T: Modulo> MulAssign for ModInt<T> {
        fn mul_assign(&mut self, rhs: Self) {
            *self = *self * rhs;
        }
    }

    impl<T: Modulo> Neg for ModInt<T> {
        type Output = ModInt<T>;
        fn neg(self) -> Self::Output {
            if self.0 == 0 {
                Self::zero()
            } else {
                Self::build(T::modulo() - self.0)
            }
        }
    }

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

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

    impl<T: Modulo> From<usize> for ModInt<T> {
        fn from(val: usize) -> ModInt<T> {
            ModInt::new_unchecked((val % T::modulo() as usize) as u32)
        }
    }

    impl<T: Modulo> From<u64> for ModInt<T> {
        fn from(val: u64) -> ModInt<T> {
            ModInt::new_unchecked((val % T::modulo() as u64) as u32)
        }
    }

    impl<T: Modulo> From<i64> for ModInt<T> {
        fn from(val: i64) -> ModInt<T> {
            let m = T::modulo() as i64;
            ModInt::new((val % m + m) as u32)
        }
    }

    #[allow(dead_code)]
    impl<T> ModInt<T> {
        fn build(d: u32) -> Self {
            ModInt(d, PhantomData)
        }
        pub fn zero() -> Self {
            Self::build(0)
        }
        pub fn is_zero(&self) -> bool {
            self.0 == 0
        }
    }

    #[allow(dead_code)]
    impl<T: Modulo> ModInt<T> {
        fn reduce(x: u64) -> u32 {
            let b = (x as u32 * T::rem()) as u64;
            let t = x + b * T::modulo() as u64;
            let mut c = (t >> 32) as u32;
            if c >= T::modulo() {
                c -= T::modulo();
            }
            c as u32
        }
        pub fn new_unchecked(d: u32) -> Self {
            Self::build(Self::reduce(d as u64 * T::ini()))
        }
        pub fn new(d: u32) -> Self {
            Self::new_unchecked(d % T::modulo())
        }
        pub fn one() -> Self {
            Self::new_unchecked(0)
        }
        pub fn get(&self) -> u32 {
            Self::reduce(self.0 as u64)
        }
        pub fn pow(&self, mut n: u64) -> Self {
            let mut t = Self::one();
            let mut s = *self;
            while n > 0 {
                if n & 1 == 1 {
                    t *= s;
                }
                s *= s;
                n >>= 1;
            }
            t
        }
        pub fn inv(&self) -> Self {
            assert!(!self.is_zero());
            self.pow(T::modulo() as u64 - 2)
        }
    }
}
// ---------- end ModInt ----------
// ---------- begin Precalc ----------
mod precalc {
    use super::modint::*;
    #[allow(dead_code)]
    pub struct Precalc<T> {
        inv: Vec<ModInt<T>>,
        fact: Vec<ModInt<T>>,
        ifact: Vec<ModInt<T>>,
    }
    #[allow(dead_code)]
    impl<T: Modulo> Precalc<T> {
        pub fn new(n: usize) -> Precalc<T> {
            let mut inv = vec![ModInt::one(); n + 1];
            let mut fact = vec![ModInt::one(); n + 1];
            let mut ifact = vec![ModInt::one(); n + 1];
            for i in 2..(n + 1) {
                fact[i] = fact[i - 1] * ModInt::new_unchecked(i as u32);
            }
            ifact[n] = fact[n].inv();
            if n > 0 {
                inv[n] = ifact[n] * fact[n - 1];
            }
            for i in (1..n).rev() {
                ifact[i] = ifact[i + 1] * ModInt::new_unchecked((i + 1) as u32);
                inv[i] = ifact[i] * fact[i - 1];
            }
            Precalc {
                inv: inv,
                fact: fact,
                ifact: ifact,
            }
        }
        pub fn inv(&self, n: usize) -> ModInt<T> {
            assert!(n > 0);
            self.inv[n]
        }
        pub fn fact(&self, n: usize) -> ModInt<T> {
            self.fact[n]
        }
        pub fn ifact(&self, n: usize) -> ModInt<T> {
            self.ifact[n]
        }
        pub fn perm(&self, n: usize, k: usize) -> ModInt<T> {
            if k > n {
                return ModInt::zero();
            }
            self.fact[n] * self.ifact[n - k]
        }
        pub fn comb(&self, n: usize, k: usize) -> ModInt<T> {
            if k > n {
                return ModInt::zero();
            }
            self.fact[n] * self.ifact[k] * self.ifact[n - k]
        }
    }
}
// ---------- end Precalc ----------
// ---------- begin Matrix ----------
mod matrix {
    use std::ops::*;
    pub trait SemiRing: Add<Output = Self> + Mul<Output = Self> + Copy {
        fn zero() -> Self;
        fn one() -> Self;
    }
    #[derive(Clone)]
    pub struct SquareMatrix<R> {
        size: usize,
        buf: Box<[R]>,
    }
    #[allow(dead_code)]
    impl<R: SemiRing> SquareMatrix<R> {
        pub fn zero(size: usize) -> Self {
            SquareMatrix {
                size: size,
                buf: vec![R::zero(); size * size].into_boxed_slice(),
            }
        }
        pub fn identity(size: usize) -> Self {
            let mut e = Self::zero(size);
            for i in 0..size {
                e.buf[i * size + i] = R::one();
            }
            e
        }
        pub fn get(&self, x: usize, y: usize) -> &R {
            assert!(x < self.size && y < self.size);
            &self.buf[x * self.size + y]
        }
        pub fn get_mut(&mut self, x: usize, y: usize) -> &mut R {
            assert!(x < self.size && y < self.size);
            &mut self.buf[x * self.size + y]
        }
        pub fn matadd(&self, rhs: &Self) -> Self {
            assert!(self.size == rhs.size);
            let buf: Vec<R> = self
                .buf
                .iter()
                .zip(rhs.buf.iter())
                .map(|p| *p.0 + *p.1)
                .collect();
            SquareMatrix {
                size: self.size,
                buf: buf.into_boxed_slice(),
            }
        }
        pub fn matmul(&self, rhs: &Self) -> Self {
            let size = self.size;
            assert!(size == rhs.size);
            let mut res = Self::zero(size);
            for (x, a) in res.buf.chunks_mut(size).zip(self.buf.chunks(size)) {
                for (a, b) in a.iter().zip(rhs.buf.chunks(size)) {
                    for (x, b) in x.iter_mut().zip(b.iter()) {
                        *x = *x + *a * *b;
                    }
                }
            }
            res
        }
        pub fn mat_pow(&self, mut n: usize) -> Self {
            let size = self.size;
            let mut t = Self::identity(size);
            let mut s = self.clone();
            while n > 0 {
                if n & 1 == 1 {
                    t = t.matmul(&s);
                }
                s = s.matmul(&s);
                n >>= 1;
            }
            t
        }
    }
    #[allow(dead_code)]
    impl<R: SemiRing + Sub<Output = R>> SquareMatrix<R> {
        pub fn matsub(&self, rhs: &Self) -> Self {
            assert!(self.size == rhs.size);
            let buf: Vec<R> = self
                .buf
                .iter()
                .zip(rhs.buf.iter())
                .map(|p| *p.0 - *p.1)
                .collect();
            SquareMatrix {
                size: self.size,
                buf: buf.into_boxed_slice(),
            }
        }
    }
}
// ---------- end Matrix ----------
// ---------- begin input macro ----------
// reference: 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, bytes) => {
        read_value!($iter, String).bytes().collect::<Vec<u8>>()
    };
    ($iter:expr, usize1) => {
        read_value!($iter, usize) - 1
    };
    ($iter:expr, $t:ty) => {
        $iter.next().unwrap().parse::<$t>().expect("Parse error")
    };
}
// ---------- end input macro ----------

use modint::*;
type M = ModInt<Mod1_000_000_007>;

use matrix::*;
type Mat = SquareMatrix<M>;

impl SemiRing for M {
    fn zero() -> Self {
        M::zero()
    }
    fn one() -> Self {
        M::one()
    }
}

fn run() {
    input! {
        w: [usize; 7],
    }
    // 0: 置いてok
    // 1: おいたらダメ
    let mut mat = vec![];
    for i in 1..=7 {
        let mut m = Mat::zero(1 << 7);
        for j in 0..(1 << i) {
            for k in 0..(1 << (2 * i - 1)) {
                if j & k > 0 {
                    continue;
                }
                let mut next = 0;
                for x in 0..i {
                    let left = x == 0 || (k >> (i + x - 1)) & 1 == 1;
                    let down = k >> x & 1 == 1;
                    let right = x == i - 1 || (k >> (i + x)) & 1 == 1;
                    if left && down && right {
                        next |= 1 << x;
                    }
                }
                *m.get_mut(next, j) += M::one();
            }
        }
        mat.push(m);
        let mut m = Mat::zero(1 << 7);
        for j in 0..(1 << i) {
            *m.get_mut(j, j) = M::one();
        }
        mat.push(m);
    }
    let mul = |m: &Mat, b: &[M]| -> Vec<M> {
        let mut res = vec![M::zero(); b.len()];
        for i in 0..b.len() {
            for j in 0..b.len() {
                res[i] += *m.get(i, j) * b[j];
            }
        }
        res
    };
    let mut b = vec![M::zero(); 1 << 7];
    let mut ini = false;
    let mut w = w;
    for (i, (w, mat)) in w.iter_mut().zip(mat.chunks(2)).enumerate().rev() {
        if !ini && *w > 0 {
            *w -= 1;
            ini = true;
            let i = i + 1;
            for k in 0..(1 << (i - 1)) {
                let mut bit = 0;
                for x in 0..i {
                    let left = x == 0 || k >> (x - 1) & 1 == 1;
                    let down = true;
                    let right = x == i - 1 || k >> x & 1 == 1;
                    if left && right && down {
                        bit |= 1 << x;
                    }
                }
                b[bit] += M::one();
            }
        }
        b = mul(&mat[1], &b);
        b = mul(&mat[0].mat_pow(*w), &b);
    }
    let ans = b[0].get();
    println!("{}", ans);
}

fn main() {
    run();
}


//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, bytes) => {
        read_value!($iter, String).bytes().collect::<Vec<u8>>()
    };
    ($iter:expr, usize1) => {
        read_value!($iter, usize) - 1
    };
    ($iter:expr, $t:ty) => {
        $iter.next().unwrap().parse::<$t>().expect("Parse error")
    };
}

//

use std::cmp::*;

fn run() {
    input! {
        n: usize,
        p: [(chars, i32, i32); n],
    }
    let p = p
        .into_iter()
        .map(|p| ((p.0[0] == 'B') as usize, p.1, p.2))
        .collect::<Vec<_>>();
    let mut sum = vec![([0, 0], 0, 0)];
    for &(x, y, z) in p.iter() {
        for i in 0..sum.len() {
            let (mut a, mut b, mut c) = sum[i];
            a[x] += 1;
            b += y;
            c += z;
            sum.push((a, b, c));
        }
    }
    let inf = std::i32::MAX / 2;
    let mut now = vec![(0, 0, 0, 0)];// bit, Rのヒット、Bのヒット、最小値
    for _ in 0..n {
        let mut next = std::collections::BTreeMap::new();
        for (bit, x, y, v) in now {
//            println!("{} {} {} {}", bit, x, y, v);
            let rem_a = v - sum[bit].1 + x;
            let rem_b = v - sum[bit].2 + y;
            for (i, &(_, a, b)) in p.iter().enumerate() {
                if bit >> i & 1 == 1 {
                    continue;
                }
                let mut x = x;
                let mut y = y;
                let mut add = 0;
                let mut p = max(0, a - rem_a);
                if p > 0 {
                    x += std::cmp::min(p, sum[bit].0[0]);
                    p -= sum[bit].0[0];
                }
                add = max(add, p);
                let mut p = max(0, b - rem_b);
                if p > 0 {
                    y += std::cmp::min(p, sum[bit].0[1]);
                    p -= sum[bit].0[1];
                }
                add = max(add, p);
                let v = v + add;
                let po = next.entry((bit | (1 << i), x, y)).or_insert(v);
                *po = std::cmp::min(*po, v);
            }
        }
        let mut a = vec![];
        for ((bit, x, y), v) in next {
            a.push((bit, x, y, v));
        }
        now = a;
    }
    let ans = now.into_iter().map(|p| p.3).min().unwrap() + n as i32;
    println!("{}", ans);
}

fn main() {
    run();
}


//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, bytes) => {
        read_value!($iter, String).bytes().collect::<Vec<u8>>()
    };
    ($iter:expr, usize1) => {
        read_value!($iter, usize) - 1
    };
    ($iter:expr, $t:ty) => {
        $iter.next().unwrap().parse::<$t>().expect("Parse error")
    };
}

//

// ---------- begin chmin, chmax ----------
trait ChangeMinMax {
    fn chmin(&mut self, x: Self) -> bool;
    fn chmax(&mut self, x: Self) -> bool;
}

impl<T: PartialOrd> ChangeMinMax for T {
    fn chmin(&mut self, x: Self) -> bool {
        if *self > x {
            *self = x;
            true
        } else {
            false
        }
    }
    fn chmax(&mut self, x: Self) -> bool {
        if *self < x {
            *self = x;
            true
        } else {
            false
        }
    }
}
// ---------- end chmin, chmax ----------

use std::cmp::*;

fn run() {
    input! {
        n: usize,
        p: [(chars, i32, i32); n],
    }
    let mut p = p
        .into_iter()
        .map(|p| ((p.0[0] == 'B') as usize, p.1, p.2))
        .collect::<Vec<_>>();
    let mut add = 0;
    for p in p.iter_mut() {
        let n = n as i32;
        let mut v = 0;
        v.chmax(p.1 - n);
        v.chmax(p.2 - n);
        add += v;
        p.1.chmin(n);
        p.2.chmin(n);
    }
    let mut sum = vec![[0i32; 2]];
    for &(x, _, _) in p.iter() {
        for i in 0..sum.len() {
            let mut a = sum[i];
            a[x] += 1;
            sum.push(a);
        }
    }
    let inf = std::i32::MAX / 2;
    let mut dp_a = std::collections::BTreeMap::new();
    let mut dp_b = std::collections::BTreeMap::new();
    dp_a.insert((0, 0), 0);
    dp_b.insert((0, 0), 0);
    for _ in 0..n {
        let mut next_a = std::collections::BTreeMap::new();
        let mut next_b = std::collections::BTreeMap::new();
        for ((bit, rem), v) in dp_a {
            let sum = sum[bit];
            for (i, &(_, a, b)) in p.iter().enumerate() {
                if bit >> i & 1 == 1 {
                    continue;
                }
                let k = bit | (1 << i);
                let a = max(0, a - sum[0]);
                let b = max(0, b - sum[1]);
                if rem + b >= a {
                    let x = rem + b - a;
                    let po = next_a.entry((k, x)).or_insert(inf);
                    po.chmin(v + b);
                } else {
                    let x = a - (rem + b);
                    let po = next_b.entry((k, x)).or_insert(inf);
                    po.chmin(v + b + x);
                }
            }
        }
        for ((bit, rem), v) in dp_b {
            let sum = sum[bit];
            for (i, &(_, a, b)) in p.iter().enumerate() {
                if bit >> i & 1 == 1 {
                    continue;
                }
                let k = bit | (1 << i);
                let a = max(0, a - sum[0]);
                let b = max(0, b - sum[1]);
                if rem + a >= b {
                    let x = rem + a - b;
                    let po = next_b.entry((k, x)).or_insert(inf);
                    po.chmin(v + a);
                } else {
                    let x = b - (rem + a);
                    let po = next_a.entry((k, x)).or_insert(inf);
                    po.chmin(v + a + x);
                }
            }
        }
        dp_a = next_a;
        dp_b = next_b;
    }
    let ans = add + dp_a.values().chain(dp_b.values()).cloned().min().unwrap() + n as i32;
    println!("{}", ans);
}

fn main() {
    run();
}


//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, bytes) => {
        read_value!($iter, String).bytes().collect::<Vec<u8>>()
    };
    ($iter:expr, usize1) => {
        read_value!($iter, usize) - 1
    };
    ($iter:expr, $t:ty) => {
        $iter.next().unwrap().parse::<$t>().expect("Parse error")
    };
}

//

// ---------- begin chmin, chmax ----------
trait ChangeMinMax {
    fn chmin(&mut self, x: Self) -> bool;
    fn chmax(&mut self, x: Self) -> bool;
}

impl<T: PartialOrd> ChangeMinMax for T {
    fn chmin(&mut self, x: Self) -> bool {
        if *self > x {
            *self = x;
            true
        } else {
            false
        }
    }
    fn chmax(&mut self, x: Self) -> bool {
        if *self < x {
            *self = x;
            true
        } else {
            false
        }
    }
}
// ---------- end chmin, chmax ----------

use std::cmp::*;

fn run() {
    input! {
        n: usize,
        p: [(chars, [i32; 2]); n],
    }
    let mut p = p
        .into_iter()
        .map(|p| ((p.0[0] == 'B') as usize, [p.1[0], p.1[1]]))
        .collect::<Vec<_>>();
    let mut need = [0; 2];
    for p in p.iter_mut() {
        let n = n as i32;
        for (need, v) in need.iter_mut().zip(p.1.iter_mut()) {
            *need += max(0, *v - n + 1);
            v.chmin(n - 1);
        }
    }
    let mut sum = vec![[0i32; 2]];
    for &(x, _) in p.iter() {
        for i in 0..sum.len() {
            let mut a = sum[i];
            a[x] += 1;
            sum.push(a);
        }
    }
    let inf = std::i32::MAX / 2;
    let sup = (n - 1) * (n - 1);
    let mut dp = vec![vec![vec![inf; 1 << n]; sup + 1]; 2];
    let abs = (need[1] - need[0]).abs() as usize;
    dp[(need[0] >= need[1]) as usize][min(sup, abs)][0] = 0;
    for bit in 0..(1 << n) {
        let sum = sum[bit];
        for rem in 0..=n.pow(2) {
            for i in 0..2 {
                let v = dp[i][rem][bit];
                if v == inf {
                    continue;
                }
                for (j, &(_, p)) in p.iter().enumerate() {
                    let k = bit | (1 << j);
                    if k == bit {
                        continue;
                    }
                    let p = [max(0, p[0] - sum[0]), max(0, p[1] - sum[1])];
                    if rem as i32 + p[i ^ 1] >= p[i] {
                        let x = rem as i32 + p[i ^ 1] - p[i];
                        let v = v + p[i ^ 1];
                        dp[i][min(x as usize, sup)][k].chmin(v);
                    } else {
                        let x = p[i] - rem as i32 - p[i ^ 1];
                        let v = v + p[i] - rem as i32;
                        dp[i ^ 1][min(x as usize, sup)][k].chmin(v);
                    }
                }
            }
        }
    }
    let add = need.iter().copied().max().unwrap() + n as i32;
    let ans = add + dp.into_iter().flatten().map(|dp| dp[(1 << n) - 1]).min().unwrap();
    println!("{}", ans);
}

fn main() {
    run();
}


use std::io;

macro_rules! parse_line {
    ($($t: ty),+) => ({
        let mut a_str = String::new();
        io::stdin().read_line(&mut a_str).unwrap();
        let mut a_iter = a_str.split_whitespace();
        (
            $(
            a_iter.next().unwrap().parse::<$t>().unwrap(),
            )+
        )
    })
}

fn main() {
    let (mut r, mut g, mut b) = parse_line!(u32, u32, u32);
    if r > g {
        std::mem::swap(&mut r, &mut g)
    }
    if g > b {
        std::mem::swap(&mut g, &mut b)
    }
    let s = r + g + b;
    let v = r + g;
    println!("{:?}", if s / 3 < v { s / 3 } else { v });
}


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() -> std::io::Result<()> {
    let mut scan = Scan::new();
    let n: usize = scan.next();
    let mut oddeven = false;
    let mut parx = 0usize;
    let mut pary = 0usize;
    for _ in 0..n {
        let x: usize = scan.next();
        let y: usize = scan.next();
        parx = (parx + x) & 1;
        pary = (pary + y) & 1;
        if (x & 1) ^ (y & 1) == 1 {
            oddeven = true;
        }
    }
    if parx == 0 && pary == 0 {
        println!("0");
    } else if n > 1 && oddeven {
        println!("1");
    } else {
        println!("-1");
    }
    Ok(())
}

fn main() -> std::io::Result<()> {
    std::thread::Builder::new()
        .stack_size(1 << 23)
        .spawn(_main)
        .unwrap()
        .join()
        .unwrap()?;
    Ok(())
}


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

fn main() {
    let mut buf = String::new();
    stdin().read_to_string(&mut buf).unwrap();
    let mut tok = buf.split_whitespace();
    let mut get = || tok.next().unwrap();
    macro_rules! get {
        ($t:ty) => (get().parse::<$t>().unwrap());
        () => (get!(i64));
    }

    let _n = get!();
    let k = get!();
    let mut a = get!();

    for _ in 0..k {
        if a % 10 == 0 {
            a /= 10;
        } else {
            a -= 1;
        }
    }

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


use std::io;

fn main(){
    let mut buffer = String::new();
    io::stdin().read_line(&mut buffer).expect("Failed to read input");

    let mut iter = buffer.split_whitespace();
    let mut first_number: i32 = iter.next().unwrap()
        .trim().parse().unwrap();
    let second_number: i32 = iter.next().unwrap()
        .trim().parse().unwrap();

    for k in 0..second_number {
        if first_number % 10 == 0 {
            first_number = first_number / 10;
        } else {
            first_number = first_number - 1;
        }
    }

    println!("The input is {} and {}", first_number, second_number);
}


use std::io;

fn subtract(n: u32) -> u32{
    if n % 10 == 0{
        n / 10
    }
    else{
        n - 1
    }
}

fn main(){
    let mut line = String::new();
    io::stdin().read_line(&mut line).expect("Failed to read line");
    let mut line = line.trim().split(" ");

    let n = line.next().expect("Not enough input")
                .parse::<u32>.expect("Not an integer");
    let k = line.next().expect("Not enough input")
                .parse::<u32>.expect("Not an integer");

    for _i in 0..k{
        let n = subtract(n);
    }

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


use std::io;

fn get_input(buffer: &mut String) -> io::Result<()> {
	io::stdin().read_line(buffer)?;
	Ok(())
}

fn main() -> io::Result<()> {
	let mut buffer = String::new();
	get_input(&mut buffer)?;
	let input: Vec<_> = buffer.split_whitespace().collect();
	if input.len() != 2 {
		return Err(io::Error::new(
			io::ErrorKind::Other,
			"Bad input !".to_string(),
		));
	}
	let mut n = input[0].parse::<i32>().unwrap();
	let mut k = input[1].parse::<i32>().unwrap();
	println!("{} {}", n, k);
	while k > 0 {
		if n % 10 == 0 {
			n /= 10;
		} else {
			n -= 1;
		}
		k -= 1;
	}
	print!("{}", n);
	Ok(())
}


use std::env;

fn main() {
    let args: Vec<String> = env::args().collect();
    let mut n: usize = args[1].parse().unwrap();
    let k: usize = args[2].parse().unwrap();

    for _ in 1..=k {
        if n % 10 == 0 {
            n = n / 10;
        }
        else {
            n = n - 1;
        }
    }
    println!("{}", n);
}


use std::io::{self, Read};
use std::collections::HashMap;

struct Node {
    white: bool,
    black: bool,
    left: bool,
    right: bool,
    count: u32,
}

fn update_tree(tree: &mut Vec<Node>, index: usize, l: usize, r: usize, left: usize, right: usize) {
    let mid :usize = (l + r) / 2;
    if tree[index].black && !tree[index].white {
        return;
    }
    if l == left && r == right {
        tree[index].black = true;
        tree[index].white = false;
        tree[index].left = true;
        tree[index].right = true;
        tree[index].count = 1;
        return;
    } else if mid >= right {
        update_tree(tree, index * 2 + 1, l, mid, left, right);
    } else if mid + 1 <= left {
        update_tree(tree, index * 2 + 2, mid + 1, r, left, right);
    } else {
        update_tree(tree, index * 2 + 1, l, mid, left, mid);
        update_tree(tree, index * 2 + 2, mid + 1, r, mid + 1, right);
    }
    tree[index].white = tree[index * 2 + 1].white & tree[index * 2 + 2].white;
    tree[index].black = tree[index * 2 + 1].black & tree[index * 2 + 2].black;
    tree[index].left = tree[index * 2 + 1].left;
    tree[index].right = tree[index * 2 + 2].right;
    if tree[index * 2 + 1].right && tree[index * 2 + 2].left {
        tree[index].count = tree[index * 2 + 1].count + tree[index * 2 + 2].count - 1;
    } else {
        tree[index].count = tree[index * 2 + 1].count + tree[index * 2 + 2].count;
    }
    return;
}

fn main() {
    let stdin = io::stdin();
    let mut handle = stdin.lock();
    let mut buf :String = String::new();

    match handle.read_to_string(&mut buf) {
        Ok(_v) => (),
        Err(e) => panic!("{}", e),
    }
    let lines: Vec<&str> = buf.split("\r\n").collect();

    let n :usize = lines[0].parse().unwrap();

    let mut points = HashMap::new();
    let mut query: Vec<(u32,u32)> = Vec::new();

    for i in 1..(n+1) {
        let pair: Vec<&str> = lines[i].split(" ").collect();
        let l :u32 = pair[0].parse().unwrap();
        let r :u32 = pair[1].parse().unwrap();
        points.insert(l, 0);
        points.insert(r, 0);
        query.push((l,r));
    }
    let mut v :Vec<u32> = Vec::new();
    for (point, _v) in points.iter() {
        v.push(*point);
    }
    v.sort();
    for i in 0..v.len() {
        points.insert(v[i], i);
    }
    let mut tree: Vec<Node> = Vec::new();
    for _i in 0..(2*v.len()) {
        tree.push(Node {count: 0, black: false, white: true, left: false, right: false});
    }
    for i in 0..n {
        let l :usize = *points.get(&query[i].0).unwrap();
        let r :usize = *points.get(&query[i].1).unwrap();
        update_tree(&mut tree, 0, 0, v.len() - 2, l, r - 1);
        print!("{} ", tree[0].count);
    }
}


fn main() {
    let mut n: u16 = {
        let mut buf = String::new();
        std::io::stdin().read_line(&mut buf).unwrap();
        buf.trim().parse().unwrap()
    };
    let (mut level, mut level_blocks) = (0, 1);
    while level_blocks <= n {
        level += 1;
        level_blocks = level * (level + 1) / 2;
        n -= level_blocks;
    }
    println!("{}", level);
}


/*input
1
*/
fn main() {
    let mut input = format!("");
    std::io::stdin().read_line(&mut input).expect("");
    let mut input_num: i16 = input.trim().parse::<i16>().unwrap();
    let mut substractor: i16 = 0;
    let mut iter: i16 = 1;
    loop {
        substractor = substractor + iter;
        input_num = input_num - substractor;
        iter = iter + 1;
        if input_num - substractor <= 0 {
            break;
        }
    }
    println!("{}", iter - 1);
}


fn main() {
    let areas: Vec<u32> = get_input().split_ascii_whitespace().map(|v| v.parse().unwrap()).collect();
    let sum: u32 = areas.iter().sum();
    let result = 4 * sum;

    println!("{}", result);

}

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

fn get_input_usize() -> usize {
    get_input().parse().unwrap()
}


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 (a, b): (u64, u64) = {
        let input = get_line();
        let mut it = input.split_whitespace().map(|x| x.parse().unwrap());
        (
            it.next().unwrap(),
            it.next().unwrap(),
            )
    };

    let ans = (a..b).fold(1, |acc, k| ((k + 1) * acc) % 10);

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


#![allow(dead_code, unused_imports)]

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 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;

#[derive(Clone)]
struct Graph {
    nodes: usize,
    edges: Vec<Vec<(usize, u64)>>,
}

impl Graph {
    fn new(n: usize) -> Self {
        Self {
            nodes: n,
            edges: vec![Vec::new(); n + 1],
        }
    }

    fn add_edge(&mut self, x: usize, y: usize, cost: u64) {
        self.edges[x].push((y, cost));
        self.edges[y].push((x, cost));
    }

    fn dijkstra(&mut self, start: usize, end: usize) -> u64 {
        let mut dist = vec![None; self.nodes + 1];
        let mut prev = vec![None; self.nodes + 1];
        dist[start] = Some(0);
        let mut queue = (1..=self.nodes).collect::<Vec<_>>();
        queue.sort_unstable_by_key(|node| dist[*node].unwrap_or(std::u64::MAX));
        queue.reverse();
        while let Some(next_node) = queue.pop() {
            if next_node == end {
                return dist[next_node].unwrap();
            }
            for (neighbour, cost) in self.edges[next_node].iter() {
                let alt = dist[next_node].unwrap() + cost;
                if dist[*neighbour].is_none() {
                    dist[*neighbour] = Some(alt);
                    prev[*neighbour] = Some(next_node);
                } else {
                    if alt < dist[*neighbour].unwrap() {
                        dist[*neighbour] = Some(alt);
                        prev[*neighbour] = Some(next_node);
                    }
                }
            }
            //println!("{:?} {:?}", dist, prev);
            queue.sort_unstable_by_key(|node| dist[*node].unwrap_or(std::u64::MAX));
            queue.reverse();
        }
        0
    }

    fn set_cost(&mut self, x: usize, y: usize, cost: u64) {
        for i in 0..self.edges[x].len() {
            if self.edges[x][i].0 == y {
                self.edges[x][i].1 = cost
            }
        }
        for i in 0..self.edges[y].len() {
            if self.edges[y][i].0 == x {
                self.edges[y][i].1 = cost
            }
        }
    }
}

const MODULO: u64 = 1_000_000_007;

#[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
struct BigPrimeRing {
    inner: u64,
}

impl<T> From<T> for BigPrimeRing
where
    T: Into<u64>,
{
    fn from(n: T) -> Self {
        Self {
            inner: n.into() % MODULO,
        }
    }
}

impl<T> std::ops::Add<T> for BigPrimeRing
where
    T: Into<Self>,
{
    type Output = BigPrimeRing;
    fn add(self, rhs: T) -> Self::Output {
        Self {
            inner: (self.inner + rhs.into().inner) % MODULO,
        }
    }
}

impl<T> std::ops::AddAssign<T> for BigPrimeRing
where
    T: Into<Self>,
{
    fn add_assign(&mut self, rhs: T) {
        self.inner += rhs.into().inner;
        self.inner %= MODULO;
    }
}

impl<T> std::ops::Sub<T> for BigPrimeRing
where
    T: Into<Self>,
{
    type Output = BigPrimeRing;
    fn sub(self, rhs: T) -> Self::Output {
        Self {
            inner: (self.inner + MODULO - rhs.into().inner) % MODULO,
        }
    }
}

impl<T> std::ops::SubAssign<T> for BigPrimeRing
where
    T: Into<Self>,
{
    fn sub_assign(&mut self, rhs: T) {
        self.inner += MODULO;
        self.inner -= rhs.into().inner;
        self.inner %= MODULO;
    }
}

impl<T> std::ops::Mul<T> for BigPrimeRing
where
    T: Into<Self>,
{
    type Output = BigPrimeRing;
    fn mul(self, rhs: T) -> Self::Output {
        Self {
            inner: (self.inner * rhs.into().inner) % MODULO,
        }
    }
}

impl<T> std::ops::MulAssign<T> for BigPrimeRing
where
    T: Into<Self>,
{
    fn mul_assign(&mut self, rhs: T) {
        self.inner *= rhs.into().inner;
        self.inner %= MODULO;
    }
}

impl BigPrimeRing {
    fn inverse(self) -> Self {
        if self.inner == 0 {
            return self;
        }
        let (_g, mut x, _y) = egcd(self.inner as i64, MODULO as i64);
        if x < 0 {
            x += MODULO as i64;
        }
        Self { inner: x as u64 }
    }
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let (a, b) = read_2::<u64, u64>();
    let mut res = 1;
    for i in (a + 1)..=b {
        res *= i;
        res %= 10;
    }
    println!("{}", res);
    Ok(())
}


// Basics

#![allow(unused_imports)]

use std::mem;
use std::io;
use std::string;
use std::cmp::*;
use std::collections::*;

fn load() -> Vec<i32> {
    let mut line = String::new();
    io::stdin().read_line(&mut line).expect("Failed to read line");
    let vec: Vec<&str> = line.split(" ").collect();
    let mut data: Vec<i32> = Vec::new();
    for i in vec {
        let el: i32 = i.trim().parse().unwrap();
        data.push(el);
    }
    data
}

fn main() {
    let w = load();
    let (a, b) = (w[0], w[1]);
    if b - a >= 10 {
        println!("0");
    } else {
        let mut end = 1;
        for i in (a + 1)..(b + 1) {
            end *= i;
        }
        println!("{}", (end % 10));
    }
}

//
//mod strings;
//
//fn main() {
//    strings_sample();
//}


fn read_line() -> String {
    let stdin = std::io::stdin();
    let mut line = String::new();
    stdin.read_line(&mut line).unwrap();
    String::from(line.trim())
}

macro_rules! scan_line {
    ($($ty: ty),*) => {{
        let line = read_line();
        let mut tok = line.split_whitespace();
        ($(tok.next().unwrap().parse::<$ty>().unwrap()),*)
    }}
}

fn main() {
    let (a, b) = scan_line!(u64, u64);
    let mut acc = 1;
    for i in (a + 1)..(b + 1) {
        acc = (acc * i % 10) % 10;
    }
    println!("{}", acc);
}


use std::io;

fn main() {
    let mut buf = String::new();
    io::stdin().read_line(&mut buf).unwrap();
    let s: usize = usize::from_str_radix(buf.trim(), 2).unwrap();

    let mut k = 0;
    while 4usize.pow(k) < s {
        k += 1;
    }

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


//spnauti-rusT
use std::io::*;
use std::str::{self,*};
use std::fmt::Debug;
#[allow(unused_imports)] use std::cmp::Ordering::{self,*};
#[allow(unused_imports)] use std::ops::{self,*};
#[allow(unused_imports)] use std::iter::{self,*};
#[allow(unused_imports)] use std::collections::*;
#[allow(unused_macros)]
macro_rules! m {
    ($c:tt, $x:expr, $y:expr) => {{
        let b = $y; let a = &mut $x;
        if b $c *a { *a = b; true } else { false }
    }};
}
#[allow(unused_macros)]
macro_rules! l {
    ($($v:ident),* = $i:ident.$f:ident $a:tt) => {
        $( let $v = $i.$f$a; )*
    };
    ($($v:ident),*:$t:ty = $i:ident.$f:ident $a:tt) => {
        $( let $v:$t = $i.$f$a; )*
    };
}
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 f(&mut self) ->    f64 { self.p()                }
    fn u(&mut self) ->  usize { self.p()                }
    fn sk(&mut self, n: usize) { self.it.nth(n - 1); }
    fn ii(&mut self, n: usize) -> impl Iterator<Item=i32> {
        self.ip(n).into_iter()
    }
    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 ip<T: FromStr>(&mut self, n: usize) -> impl Iterator<Item=T> where T::Err: Debug {
        self.vp(n).into_iter()
    }
    fn vp<T: FromStr>(&mut self, n: usize) -> Vec<T> where T::Err: Debug {
        (0..n).map(|_| self.p()).collect()
    }
}
//------------------- End rusT

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

    let n = input.u();
    for _ in 0..n {
        let mut a: i64 = input.p();
        let mut sol = 0;
        while a % 2 == 0 {
            a /= 2;
            sol += 1;
        }
        while a % 3 == 0 {
            a /= 3;
            sol += 2;
        }
        while a % 5 == 0 {
            a /= 5;
            sol += 3;
        }
        if a != 1 {
            sol = -1;
        }
        writeln!(bout, "{}", sol).ok();
    }
}


//spnauti-rusT
use std::io::*;
use std::str::{self,*};
use std::fmt::Debug;
#[allow(unused_imports)] use std::cmp::Ordering::{self,*};
#[allow(unused_imports)] use std::ops::{self,*};
#[allow(unused_imports)] use std::iter::{self,*};
#[allow(unused_imports)] use std::collections::*;
#[allow(unused_macros)]
macro_rules! m {
    ($c:tt, $x:expr, $y:expr) => {{
        let b = $y; let a = &mut $x;
        if b $c *a { *a = b; true } else { false }
    }};
}
#[allow(unused_macros)]
macro_rules! l {
    ($($v:ident),* = $i:ident.$f:ident $a:tt) => {
        $( let $v = $i.$f$a; )*
    };
    ($($v:ident),*:$t:ty = $i:ident.$f:ident $a:tt) => {
        $( let $v:$t = $i.$f$a; )*
    };
}
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 f(&mut self) ->    f64 { self.p()                }
    fn u(&mut self) ->  usize { self.p()                }
    fn sk(&mut self, n: usize) { self.it.nth(n - 1); }
    fn ii(&mut self, n: usize) -> impl Iterator<Item=i32> {
        self.ip(n).into_iter()
    }
    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 ip<T: FromStr>(&mut self, n: usize) -> impl Iterator<Item=T> where T::Err: Debug {
        self.vp(n).into_iter()
    }
    fn vp<T: FromStr>(&mut self, n: usize) -> Vec<T> where T::Err: Debug {
        (0..n).map(|_| self.p()).collect()
    }
}
//------------------- End rusT

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

    let s = input.bs();
    let n = s.len();
    let sol = n / 2 + (if s[1..].iter().any(|x| *x == b'1') {1} else {0});
    println!("{}", sol);
}


#![allow(unused_variables)]
#![allow(unused_must_use)]

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

fn main() {
    let stdin = io::stdin();
    let stdout = io::stdout();
    let mut input = Input::new(stdin.lock());
    let mut output = io::BufWriter::new(stdout.lock());
    macro_rules! puts {
        ($($format:tt)*) => (write!(output ,$($format)*).unwrap());
    }
    let s: String = input.next();
    let s = s.into_bytes();
    let mut s2: Vec<u8> = s
        .as_slice()
        .rchunks(2)
        .map(|chunk| {
            if chunk.len() == 1 {
                chunk[0] - b'0'
            } else {
                (chunk[0] - b'0') * 2 + chunk[1] - b'0'
            }
        })
        .collect();
    s2.as_mut_slice().reverse();
    if s2[0] != 1 || s2[1..].iter().any(|&c| c != 0) {
        puts!("{}\n", s2.len());
        return;
    }
    puts!("{}\n", s2.len() - 1);
}

struct Input<R> {
    lines: io::Lines<R>,
    cur: String,
    split: std::str::SplitAsciiWhitespace<'static>, //'
}

impl<R: BufRead> Input<R> {
    fn new(reader: R) -> Input<R> {
        use std::mem::transmute;

        let mut lines = reader.lines();
        let cur = lines.next().unwrap().unwrap();
        let split = unsafe { transmute(cur.split_ascii_whitespace()) };
        Input { lines, cur, split }
    }
    fn update(&mut self) {
        use std::mem::transmute;
        self.cur = self.lines.next().unwrap().unwrap();
        unsafe { self.split = transmute(self.cur.split_ascii_whitespace()) };
    }
    fn next<F: std::str::FromStr>(&mut self) -> F {
        loop {
            if let Some(thing) = self.split.next() {
                return thing.parse().ok().unwrap();
            }
            self.update();
        }
    }
    fn iter<I: std::str::FromStr>(&mut self) -> InputIter<R, I> {
        InputIter {
            input: self,
            _phantom: std::marker::PhantomData,
        }
    }
}

struct InputIter<'a, R, I> {
    input: &'a mut Input<R>,
    _phantom: std::marker::PhantomData<I>,
}

impl<'a, R, I> Iterator for InputIter<'a, R, I>
where
    R: BufRead,
    I: std::str::FromStr,
{
    type Item = I;
    fn next(&mut self) -> Option<Self::Item> {
        Some(self.input.next())
    }
}


use std::io::{stdin, stdout, Write, BufReader, BufRead, Read};

fn solve(input: &mut BufRead, output: &mut Write) {
    let mut input = BufReader::new(input);

    let mut line = String::with_capacity(100);
    input.read_line(&mut line).unwrap();
    let line = line.trim();

    if line.chars().next().unwrap() == '0' {
        output.write(b"0");
    } else if line.chars().skip(1).position(|it| it == '1') == None {
        output.write(format!("{}", line.len() / 2).as_bytes());
    } else {
        output.write(format!("{}", line.len() / 2 + 1).as_bytes());
    }

}

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

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

    #[test]
    fn basic_test() {
        let mut f = BufReader::new("bbaba
bb
".as_bytes());
        let mut buf: Vec<u8> = Vec::new();

        solve(&mut f, &mut buf);

        let res = String::from_utf8(buf).unwrap();
        assert_eq!(res, "3\n");
    }

    #[test]
    fn basic_test2() {
        let mut f = BufReader::new("baaba
ab
".as_bytes());
        let mut buf: Vec<u8> = Vec::new();

        solve(&mut f, &mut buf);

        let res = String::from_utf8(buf).unwrap();
        assert_eq!(res, "2\n");
    }

    #[test]
    fn basic_test3() {
        let mut f = BufReader::new("abcde
abcde
".as_bytes());
        let mut buf: Vec<u8> = Vec::new();

        solve(&mut f, &mut buf);

        let res = String::from_utf8(buf).unwrap();
        assert_eq!(res, "0\n");
    }

    #[test]
    fn basic_test4() {
        let mut f = BufReader::new("asdfasdf
fasd
".as_bytes());
        let mut buf: Vec<u8> = Vec::new();

        solve(&mut f, &mut buf);

        let res = String::from_utf8(buf).unwrap();
        assert_eq!(res, "3\n");
    }
}