fn main() {
    use std::io::Read;
    let mut buf = String::new();
    std::io::stdin().read_to_string(&mut buf).unwrap();
    let mut itr = buf.split_whitespace();

    use std::io::Write;
    let out = std::io::stdout();
    let mut out = std::io::BufWriter::new(out.lock());

    macro_rules! print {
        ($($T:expr),*) => {
            write!(out, $($T),*).unwrap()
        };
    }

    macro_rules! scan {
        (bytes) => {
            scan!(String).bytes().collect::<Vec<_>>()
        };
        (chars) => {
            scan!(String).chars().collect::<Vec<_>>()
        };
        ([$T:tt; $n:expr]) => {
            (0..$n).map(|_| scan!($T)).collect::<Vec<_>>()
        };
        (($($T:tt),*)) => {
            ($(scan!($T)),*)
        };
        ($T:ty) => {
            itr.next().unwrap().parse::<$T>().unwrap()
        };
        ($($T:tt),*) => {
            ($(scan!($T)),*)
        };
    }

    let t: usize = 1; //scan!(usize);
    for _ in 1..=t {
        let n = scan!(usize);
        let mut a = vec![0; n + 1];

        let mut sum = 0;
        for i in 1..=n {
            a[i] = scan!(usize);
            sum += a[i];
        }

        if sum % 2 != 0 {
            print!("0");
        } else {
            let mut dp = vec![vec![false; sum + 1]; n + 1];
            dp[0][0] = true;

            for i in 1..=n {
                for s in 0..=sum {
                    if a[i] + s <= sum {
                        dp[i][s + a[i]] |= dp[i - 1][s];
                    }
                    dp[i][s] |= dp[i - 1][s];
                }
            }

            if dp[n][sum / 2] {
                print!("1\n");
                let mut min_idx = 0;
                let mut min_cnt = 31;
                for i in 1..=n {
                    let mut cnt = 0;
                    let mut a = a[i];
                    while a % 2 == 0 {
                        cnt += 1;
                        a /= 2;
                    }
                    if min_cnt > cnt {
                        min_cnt = cnt;
                        min_idx = i;
                    }
                }

                print!("{}", min_idx);
            } else {
                print!("0");
            }
        }
        print!("\n");
    }
}

cp! {
kind = single;
input {
    n: u,
    a: [u; n],
}

solve {
    fn check(a: &[u], h: &mut m<(u, i), bool>, i: u, sum: i) -> bool {
        if let Some(val) = h.get(&(i, sum)) {
            return *val;
        }
        let val = {
            if sum < 0 {
                return false;
            }
            if sum == 0 {
                return true;
            }
            if i == a.len() {
                return false;
            }
            check(a, h, i + 1, sum - a[i] as i) || check(a, h, i + 1, sum as i)
        };
        h.insert((i, sum), val);
        val
    }

    let mut c = m::new();
    let sum = a.iter().sum::<u>();
    if sum & 1 == 1 || !check(&a, &mut c, 0, sum as i / 2)
    {
        ans!(0);
    }

    loop {
        for (i, x) in a.iter_mut().enumerate() {
            if *x & 1 == 1 {
                outln!(1);
                ans!(i + 1);
            }
            *x /= 2;
        }
    }
}
}

#[cfg(not(ONLINE_JUDGE))]
#[macro_use]
extern crate cp;

#[cfg(not(ONLINE_JUDGE))]
use cp::*;
// =================================================================================
// =================================================================================

// LIBRARY CODE BEGINS HERE
// TAKEN FROM https://github.com/EbTech/rust-algorithms
// YOU CAN JUST RUN rustfmt TO GET READABLE CODE

// =================================================================================
// =================================================================================
pub use std::cmp::*; pub use std::collections::*; use std::hash::Hash; pub use std::io::*; pub use std::mem::*; pub use std::str::FromStr; pub type i = i64; pub type u = usize; pub type v<t = i> = Vec<t>; pub type vi = v<i>; pub type ii = (i, i); pub type uu = (u, u); pub type vu = v<u>; pub type vii = v<ii>; pub type vuu = v<uu>; pub type s = String; pub type m<t, u> = HashMap<t, u>; use std::{ fmt::Display, intrinsics::transmute, io::{self, StdinLock}, mem::MaybeUninit, }; pub mod algo { pub mod caching { use std::collections::{hash_map::Entry, HashMap}; pub struct Cacher<U, V> where U: std::cmp::Eq + std::hash::Hash + Copy, V: Copy, { values: HashMap<U, V>, } impl<U, V> Cacher<U, V> where U: std::cmp::Eq + std::hash::Hash + Copy, V: Copy, { pub fn new() -> Cacher<U, V> { Cacher { values: HashMap::new(), } } pub fn call(&mut self, arg: U, calc: impl Fn(U) -> V) -> V { if let Some(v) = self.values.get(&arg) { return *v; } let val = calc(arg); self.values.insert(arg, val); val } } } pub mod graph { pub mod connectivity { use super::Graph; struct ConnectivityData { time: usize, vis: Box<[usize]>, low: Box<[usize]>, v_stack: Vec<usize>, e_stack: Vec<usize>, } impl ConnectivityData { fn new(num_v: usize) -> Self { Self { time: 0, vis: vec![0; num_v].into_boxed_slice(), low: vec![0; num_v].into_boxed_slice(), v_stack: vec![], e_stack: vec![], } } fn visit(&mut self, u: usize) { self.time += 1; self.vis[u] = self.time; self.low[u] = self.time; self.v_stack.push(u); } fn lower(&mut self, u: usize, val: usize) { if self.low[u] > val { self.low[u] = val } } } pub struct ConnectivityGraph<'a> { pub graph: &'a Graph, pub cc: Vec<usize>, pub vcc: Vec<usize>, pub num_cc: usize, pub num_vcc: usize, } impl<'a> ConnectivityGraph<'a> { pub fn new(graph: &'a Graph, is_directed: bool) -> Self { let mut connect = Self { graph, cc: vec![0; graph.num_v()], vcc: vec![0; graph.num_e()], num_cc: 0, num_vcc: 0, }; let mut data = ConnectivityData::new(graph.num_v()); for u in 0..graph.num_v() { if data.vis[u] == 0 { if is_directed { connect.scc(&mut data, u); } else { connect.bcc(&mut data, u, graph.num_e() + 1); } } } connect } fn scc(&mut self, data: &mut ConnectivityData, u: usize) { data.visit(u); for (_, v) in self.graph.adj_list(u) { if data.vis[v] == 0 { self.scc(data, v); } if self.cc[v] == 0 { data.lower(u, data.low[v]); } } if data.vis[u] == data.low[u] { self.num_cc += 1; while let Some(v) = data.v_stack.pop() { self.cc[v] = self.num_cc; if v == u { break; } } } } pub fn two_sat_assign(&self) -> Option<Vec<bool>> { (0..self.graph.num_v() / 2) .map(|i| { let scc_true = self.cc[2 * i]; let scc_false = self.cc[2 * i + 1]; if scc_true == scc_false { None } else { Some(scc_true < scc_false) } }) .collect() } pub fn topological_sort(&self) -> Vec<usize> { let mut vertices = (0..self.graph.num_v()).collect::<Vec<_>>(); vertices.sort_unstable_by_key(|&u| self.num_cc - self.cc[u]); vertices } fn bcc(&mut self, data: &mut ConnectivityData, u: usize, par: usize) { data.visit(u); for (e, v) in self.graph.adj_list(u) { if data.vis[v] == 0 { data.e_stack.push(e); self.bcc(data, v, e); data.lower(u, data.low[v]); if data.vis[u] <= data.low[v] { self.num_vcc += 1; while let Some(top_e) = data.e_stack.pop() { self.vcc[top_e] = self.num_vcc; self.vcc[top_e ^ 1] = self.num_vcc; if e ^ top_e <= 1 { break; } } } } else if data.vis[v] < data.vis[u] && e ^ par != 1 { data.lower(u, data.vis[v]); data.e_stack.push(e); } else if v == u { self.num_vcc += 1; self.vcc[e] = self.num_vcc; self.vcc[e ^ 1] = self.num_vcc; } } if data.vis[u] == data.low[u] { self.num_cc += 1; while let Some(v) = data.v_stack.pop() { self.cc[v] = self.num_cc; if v == u { break; } } } } pub fn is_cut_vertex(&self, u: usize) -> bool { if let Some(first_e) = self.graph.first[u] { self.graph .adj_list(u) .any(|(e, _)| self.vcc[first_e] != self.vcc[e]) } else { false } } pub fn is_cut_edge(&self, e: usize) -> bool { let u = self.graph.endp[e ^ 1]; let v = self.graph.endp[e]; self.cc[u] != self.cc[v] } } } pub mod flow { use super::{AdjListIterator, Graph}; pub struct FlowGraph { pub graph: Graph, pub cap: Vec<i64>, pub cost: Vec<i64>, } impl FlowGraph { const INF: i64 = i64::MAX; pub fn new(vmax: usize, emax_hint: usize) -> Self { Self { graph: Graph::new(vmax, 2 * emax_hint), cap: Vec::with_capacity(2 * emax_hint), cost: Vec::with_capacity(2 * emax_hint), } } pub fn add_edge(&mut self, u: usize, v: usize, cap: i64, rcap: i64, cost: i64) { self.cap.push(cap); self.cap.push(rcap); self.cost.push(cost); self.cost.push(-cost); self.graph.add_undirected_edge(u, v); } pub fn dinic(&self, s: usize, t: usize) -> (i64, Vec<i64>) { let mut flow = vec![0; self.graph.num_e()]; let mut max_flow = 0; loop { let dist = self.dinic_search(s, &flow); if dist[t] == Self::INF { break; } let mut adj_iters = (0..self.graph.num_v()) .map(|u| self.graph.adj_list(u).peekable()) .collect::<Vec<_>>(); max_flow += self.dinic_augment(s, t, Self::INF, &dist, &mut adj_iters, &mut flow); } (max_flow, flow) } fn dinic_search(&self, s: usize, flow: &[i64]) -> Vec<i64> { let mut dist = vec![Self::INF; self.graph.num_v()]; let mut q = ::std::collections::VecDeque::new(); dist[s] = 0; q.push_back(s); while let Some(u) = q.pop_front() { for (e, v) in self.graph.adj_list(u) { if dist[v] == Self::INF && flow[e] < self.cap[e] { dist[v] = dist[u] + 1; q.push_back(v); } } } dist } fn dinic_augment( &self, u: usize, t: usize, f: i64, dist: &[i64], adj: &mut [::std::iter::Peekable<AdjListIterator>], flow: &mut [i64], ) -> i64 { if u == t { return f; } let mut df = 0; while let Some(&(e, v)) = adj[u].peek() { let rem_cap = (self.cap[e] - flow[e]).min(f - df); if rem_cap > 0 && dist[v] == dist[u] + 1 { let cf = self.dinic_augment(v, t, rem_cap, dist, adj, flow); flow[e] += cf; flow[e ^ 1] -= cf; df += cf; if df == f { break; } } adj[u].next(); } df } pub fn min_cut(&self, dist: &[i64]) -> Vec<usize> { (0..self.graph.num_e()) .filter(|&e| { let u = self.graph.endp[e ^ 1]; let v = self.graph.endp[e]; dist[u] < Self::INF && dist[v] == Self::INF }) .collect() } pub fn mcf(&self, s: usize, t: usize) -> (i64, i64, Vec<i64>) { let mut pot = vec![0; self.graph.num_v()]; for _ in 1..self.graph.num_v() { for e in 0..self.graph.num_e() { if self.cap[e] > 0 { let u = self.graph.endp[e ^ 1]; let v = self.graph.endp[e]; pot[v] = pot[v].min(pot[u] + self.cost[e]); } } } let mut flow = vec![0; self.graph.num_e()]; let (mut min_cost, mut max_flow) = (0, 0); loop { let par = self.mcf_search(s, &flow, &mut pot); if par[t] == None { break; } let (dc, df) = self.mcf_augment(t, &par, &mut flow); min_cost += dc; max_flow += df; } (min_cost, max_flow, flow) } fn mcf_search( &self, s: usize, flow: &[i64], pot: &mut [i64], ) -> Vec<Option<usize>> { let mut vis = vec![false; self.graph.num_v()]; let mut dist = vec![Self::INF; self.graph.num_v()]; let mut par = vec![None; self.graph.num_v()]; dist[s] = 0; while let Some(u) = (0..self.graph.num_v()) .filter(|&u| !vis[u] && dist[u] < Self::INF) .min_by_key(|&u| dist[u] - pot[u]) { vis[u] = true; pot[u] = dist[u]; for (e, v) in self.graph.adj_list(u) { if dist[v] > dist[u] + self.cost[e] && flow[e] < self.cap[e] { dist[v] = dist[u] + self.cost[e]; par[v] = Some(e); } } } par } fn mcf_augment( &self, t: usize, par: &[Option<usize>], flow: &mut [i64], ) -> (i64, i64) { let (mut dc, mut df) = (0, Self::INF); let mut u = t; while let Some(e) = par[u] { df = df.min(self.cap[e] - flow[e]); u = self.graph.endp[e ^ 1]; } u = t; while let Some(e) = par[u] { flow[e] += df; flow[e ^ 1] -= df; dc += df * self.cost[e]; u = self.graph.endp[e ^ 1]; } (dc, df) } } } pub mod util { use super::AdjListIterator; use super::{DisjointSets, Graph}; use std::cmp::Reverse; impl Graph { pub fn euler_path(&self, u: usize) -> Vec<usize> { let mut adj_iters = (0..self.num_v()) .map(|u| self.adj_list(u)) .collect::<Vec<_>>(); let mut edges = Vec::with_capacity(self.num_e()); self.euler_recurse(u, &mut adj_iters, &mut edges); edges.reverse(); edges } fn euler_recurse( &self, u: usize, adj: &mut [AdjListIterator], edges: &mut Vec<usize>, ) { while let Some((e, v)) = adj[u].next() { self.euler_recurse(v, adj, edges); edges.push(e); } } pub fn min_spanning_tree(&self, weights: &[i64]) -> Vec<usize> { assert_eq!(self.num_e(), 2 * weights.len()); let mut edges = (0..weights.len()).collect::<Vec<_>>(); edges.sort_unstable_by_key(|&e| weights[e]); let mut components = DisjointSets::new(self.num_v()); edges .into_iter() .filter(|&e| components.merge(self.endp[2 * e], self.endp[2 * e + 1])) .collect() } pub fn dijkstra(&self, weights: &[u64], u: usize) -> Vec<u64> { assert_eq!(self.num_e(), weights.len()); let mut dist = vec![u64::max_value(); weights.len()]; let mut heap = std::collections::BinaryHeap::new(); dist[u] = 0; heap.push((Reverse(0), 0)); while let Some((Reverse(dist_u), u)) = heap.pop() { if dist[u] == dist_u { for (e, v) in self.adj_list(u) { let dist_v = dist_u + weights[e]; if dist[v] > dist_v { dist[v] = dist_v; heap.push((Reverse(dist_v), v)); } } } } dist } pub fn dfs(&self, root: usize) -> DfsIterator { let mut visited = vec![false; self.num_v()]; visited[root] = true; let adj_iters = (0..self.num_v()) .map(|u| self.adj_list(u)) .collect::<Vec<_>>(); DfsIterator { visited, stack: vec![root], adj_iters, } } } pub struct DfsIterator<'a> { visited: Vec<bool>, stack: Vec<usize>, adj_iters: Vec<AdjListIterator<'a>>, } impl<'a> Iterator for DfsIterator<'a> { type Item = (usize, usize); fn next(&mut self) -> Option<Self::Item> { loop { let &u = self.stack.last()?; while let Some((e, v)) = self.adj_iters[u].next() { if !self.visited[v] { self.visited[v] = true; self.stack.push(v); return Some((e, v)); } } self.stack.pop(); } } } } pub struct DisjointSets { parent: Vec<usize>, } impl DisjointSets { pub fn new(size: usize) -> Self { Self { parent: (0..size).collect(), } } pub fn find(&mut self, u: usize) -> usize { let pu = self.parent[u]; if pu != u { self.parent[u] = self.find(pu); } self.parent[u] } pub fn merge(&mut self, u: usize, v: usize) -> bool { let (pu, pv) = (self.find(u), self.find(v)); self.parent[pu] = pv; pu != pv } } pub struct Graph { first: Vec<Option<usize>>, next: Vec<Option<usize>>, endp: Vec<usize>, } impl Graph { pub fn new(vmax: usize, emax_hint: usize) -> Self { Self { first: vec![None; vmax], next: Vec::with_capacity(emax_hint), endp: Vec::with_capacity(emax_hint), } } pub fn num_v(&self) -> usize { self.first.len() } pub fn num_e(&self) -> usize { self.endp.len() } pub fn add_edge(&mut self, u: usize, v: usize) { self.next.push(self.first[u]); self.first[u] = Some(self.num_e()); self.endp.push(v); } pub fn add_undirected_edge(&mut self, u: usize, v: usize) { self.add_edge(u, v); self.add_edge(v, u); } pub fn add_two_sat_clause(&mut self, u: usize, v: usize) { self.add_edge(u ^ 1, v); self.add_edge(v ^ 1, u); } pub fn adj_list(&self, u: usize) -> AdjListIterator { AdjListIterator { graph: self, next_e: self.first[u], } } } pub struct AdjListIterator<'a> { graph: &'a Graph, next_e: Option<usize>, } impl<'a> Iterator for AdjListIterator<'a> { type Item = (usize, usize); fn next(&mut self) -> Option<Self::Item> { self.next_e.map(|e| { let v = self.graph.endp[e]; self.next_e = self.graph.next[e]; (e, v) }) } } } pub mod math { pub mod fft { use super::num::{CommonField, Complex, PI}; use std::ops::{Add, Div, Mul, Neg, Sub}; struct BitRevIterator { a: usize, n: usize, } impl BitRevIterator { fn new(n: usize) -> Self { assert!(n.is_power_of_two()); Self { a: 2 * n - 1, n } } } impl Iterator for BitRevIterator { type Item = usize; fn next(&mut self) -> Option<Self::Item> { if self.a == 2 * self.n - 2 { return None; } let mut mask = self.n; while self.a & mask > 0 { self.a ^= mask; mask /= 2; } self.a |= mask; Some(self.a / 2) } } #[allow(clippy::upper_case_acronyms)] pub trait FFT: Sized + Copy { type F: Sized + Copy + From<Self> + Neg + Add<Output = Self::F> + Div<Output = Self::F> + Mul<Output = Self::F> + Sub<Output = Self::F>; const ZERO: Self; fn get_roots(n: usize, inverse: bool) -> Vec<Self::F>; fn get_factor(n: usize, inverse: bool) -> Self::F; fn extract(f: Self::F) -> Self; } impl FFT for f64 { type F = Complex; const ZERO: f64 = 0.0; fn get_roots(n: usize, inverse: bool) -> Vec<Self::F> { let step = if inverse { -2.0 } else { 2.0 } * PI / n as f64; (0..n / 2) .map(|i| Complex::from_polar(1.0, step * i as f64)) .collect() } fn get_factor(n: usize, inverse: bool) -> Self::F { Self::F::from(if inverse { (n as f64).recip() } else { 1.0 }) } fn extract(f: Self::F) -> f64 { f.real } } impl FFT for i64 { type F = CommonField; const ZERO: Self = 0; fn get_roots(n: usize, inverse: bool) -> Vec<Self::F> { assert!(n <= 1 << 23); let mut prim_root = Self::F::from(15_311_432); if inverse { prim_root = prim_root.recip(); } for _ in (0..).take_while(|&i| n < 1 << (23 - i)) { prim_root = prim_root * prim_root; } let mut roots = Vec::with_capacity(n / 2); let mut root = Self::F::from(1); for _ in 0..roots.capacity() { roots.push(root); root = root * prim_root; } roots } fn get_factor(n: usize, inverse: bool) -> Self::F { Self::F::from(if inverse { n as Self } else { 1 }).recip() } fn extract(f: Self::F) -> Self { f.val } } pub fn fft<T: FFT>(v: &[T::F], inverse: bool) -> Vec<T::F> { let n = v.len(); assert!(n.is_power_of_two()); let factor = T::get_factor(n, inverse); let roots_of_unity = T::get_roots(n, inverse); let mut dft = BitRevIterator::new(n) .map(|i| v[i] * factor) .collect::<Vec<_>>(); for m in (0..).map(|s| 1 << s).take_while(|&m| m < n) { for k in (0..n).step_by(2 * m) { for j in 0..m { let u = dft[k + j]; let t = dft[k + j + m] * roots_of_unity[n / 2 / m * j]; dft[k + j] = u + t; dft[k + j + m] = u - t; } } } dft } pub fn dft_from_reals<T: FFT>(v: &[T], desired_len: usize) -> Vec<T::F> { assert!(v.len() <= desired_len); let complex_v = v .iter() .cloned() .chain(std::iter::repeat(T::ZERO)) .take(desired_len.next_power_of_two()) .map(T::F::from) .collect::<Vec<_>>(); fft::<T>(&complex_v, false) } pub fn idft_to_reals<T: FFT>(dft_v: &[T::F], desired_len: usize) -> Vec<T> { assert!(dft_v.len() >= desired_len); let complex_v = fft::<T>(dft_v, true); complex_v .into_iter() .take(desired_len) .map(T::extract) .collect() } pub fn convolution<T: FFT>(a: &[T], b: &[T]) -> Vec<T> { let len_c = a.len() + b.len() - 1; let dft_a = dft_from_reals(a, len_c).into_iter(); let dft_b = dft_from_reals(b, len_c).into_iter(); let dft_c = dft_a.zip(dft_b).map(|(a, b)| a * b).collect::<Vec<_>>(); idft_to_reals(&dft_c, len_c) } } pub mod num { pub use std::f64::consts::PI; use std::ops::{Add, Div, Index, IndexMut, Mul, Neg, Sub}; pub fn fast_gcd(mut a: i64, mut b: i64) -> i64 { while b != 0 { a %= b; std::mem::swap(&mut a, &mut b); } a.abs() } #[derive(Clone, Copy, Eq, PartialEq, Debug, Hash)] pub struct Rational { pub num: i64, pub den: i64, } impl Rational { pub fn new(num: i64, den: i64) -> Self { let g = fast_gcd(num, den) * den.signum(); Self { num: num / g, den: den / g, } } pub fn abs(self) -> Self { Self { num: self.num.abs(), den: self.den, } } pub fn recip(self) -> Self { let g = self.num.signum(); Self { num: self.den / g, den: self.num / g, } } } impl From<i64> for Rational { fn from(num: i64) -> Self { Self { num, den: 1 } } } impl Neg for Rational { type Output = Self; fn neg(self) -> Self { Self { num: -self.num, den: self.den, } } } #[allow(clippy::suspicious_arithmetic_impl)] impl Add for Rational { type Output = Self; fn add(self, other: Self) -> Self { Self::new( self.num * other.den + self.den * other.num, self.den * other.den, ) } } #[allow(clippy::suspicious_arithmetic_impl)] impl Sub for Rational { type Output = Self; fn sub(self, other: Self) -> Self { Self::new( self.num * other.den - self.den * other.num, self.den * other.den, ) } } impl Mul for Rational { type Output = Self; fn mul(self, other: Self) -> Self { Self::new(self.num * other.num, self.den * other.den) } } #[allow(clippy::suspicious_arithmetic_impl)] impl Div for Rational { type Output = Self; fn div(self, other: Self) -> Self { self * other.recip() } } impl Ord for Rational { fn cmp(&self, other: &Self) -> std::cmp::Ordering { (self.num * other.den).cmp(&(self.den * other.num)) } } impl PartialOrd for Rational { fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> { Some(self.cmp(other)) } } #[derive(Clone, Copy, PartialEq, Debug)] pub struct Complex { pub real: f64, pub imag: f64, } impl Complex { pub fn new(real: f64, imag: f64) -> Self { Self { real, imag } } pub fn from_polar(r: f64, th: f64) -> Self { Self::new(r * th.cos(), r * th.sin()) } pub fn abs_square(self) -> f64 { self.real * self.real + self.imag * self.imag } pub fn argument(self) -> f64 { self.imag.atan2(self.real) } pub fn conjugate(self) -> Self { Self::new(self.real, -self.imag) } pub fn recip(self) -> Self { let denom = self.abs_square(); Self::new(self.real / denom, -self.imag / denom) } } impl From<f64> for Complex { fn from(real: f64) -> Self { Self::new(real, 0.0) } } impl Neg for Complex { type Output = Self; fn neg(self) -> Self { Self::new(-self.real, -self.imag) } } impl Add for Complex { type Output = Self; fn add(self, other: Self) -> Self { Self::new(self.real + other.real, self.imag + other.imag) } } impl Sub for Complex { type Output = Self; fn sub(self, other: Self) -> Self { Self::new(self.real - other.real, self.imag - other.imag) } } impl Mul for Complex { type Output = Self; fn mul(self, other: Self) -> Self { let real = self.real * other.real - self.imag * other.imag; let imag = self.imag * other.real + self.real * other.imag; Self::new(real, imag) } } #[allow(clippy::suspicious_arithmetic_impl)] impl Div for Complex { type Output = Self; fn div(self, other: Self) -> Self { self * other.recip() } } #[derive(Clone, Copy, Eq, PartialEq, Debug, Hash)] pub struct Modulo<const M: i64> { pub val: i64, } impl<const M: i64> Modulo<M> { pub fn pow(mut self, mut n: u64) -> Self { let mut result = Self::from_small(1); while n > 0 { if n % 2 == 1 { result = result * self; } self = self * self; n /= 2; } result } pub fn vec_of_recips(n: i64) -> Vec<Self> { let mut recips = vec![Self::from(0), Self::from(1)]; for i in 2..=n { let (md, dv) = (M % i, M / i); recips.push(recips[md as usize] * Self::from_small(-dv)); } recips } pub fn recip(self) -> Self { self.pow(M as u64 - 2) } fn from_small(s: i64) -> Self { let val = if s < 0 { s + M } else { s }; Self { val } } } impl<const M: i64> From<i64> for Modulo<M> { fn from(val: i64) -> Self { Self::from_small(val % M) } } impl<const M: i64> Neg for Modulo<M> { type Output = Self; fn neg(self) -> Self { Self::from_small(-self.val) } } impl<const M: i64> Add for Modulo<M> { type Output = Self; fn add(self, other: Self) -> Self { Self::from_small(self.val + other.val - M) } } impl<const M: i64> Sub for Modulo<M> { type Output = Self; fn sub(self, other: Self) -> Self { Self::from_small(self.val - other.val) } } impl<const M: i64> Mul for Modulo<M> { type Output = Self; fn mul(self, other: Self) -> Self { Self::from(self.val * other.val) } } #[allow(clippy::suspicious_arithmetic_impl)] impl<const M: i64> Div for Modulo<M> { type Output = Self; fn div(self, other: Self) -> Self { self * other.recip() } } pub const COMMON_PRIME: i64 = 998_244_353; pub type CommonField = Modulo<COMMON_PRIME>; #[derive(Clone, PartialEq, Debug)] pub struct Matrix { cols: usize, inner: Box<[f64]>, } impl Matrix { pub fn zero(rows: usize, cols: usize) -> Self { let inner = vec![0.0; rows * cols].into_boxed_slice(); Self { cols, inner } } pub fn one(cols: usize) -> Self { let mut matrix = Self::zero(cols, cols); for i in 0..cols { matrix[i][i] = 1.0; } matrix } pub fn vector(vec: &[f64], as_row: bool) -> Self { let cols = if as_row { vec.len() } else { 1 }; let inner = vec.to_vec().into_boxed_slice(); Self { cols, inner } } pub fn pow(&self, mut n: u64) -> Self { let mut base = self.clone(); let mut result = Self::one(self.cols); while n > 0 { if n % 2 == 1 { result = &result * &base; } base = &base * &base; n /= 2; } result } pub fn rows(&self) -> usize { self.inner.len() / self.cols } pub fn transpose(&self) -> Self { let mut matrix = Matrix::zero(self.cols, self.rows()); for i in 0..self.rows() { for j in 0..self.cols { matrix[j][i] = self[i][j]; } } matrix } pub fn recip(&self) -> Self { unimplemented!(); } } impl Index<usize> for Matrix { type Output = [f64]; fn index(&self, row: usize) -> &Self::Output { let start = self.cols * row; &self.inner[start..start + self.cols] } } impl IndexMut<usize> for Matrix { fn index_mut(&mut self, row: usize) -> &mut Self::Output { let start = self.cols * row; &mut self.inner[start..start + self.cols] } } impl Neg for &Matrix { type Output = Matrix; fn neg(self) -> Matrix { let inner = self.inner.iter().map(|&v| -v).collect(); Matrix { cols: self.cols, inner, } } } impl Add for &Matrix { type Output = Matrix; fn add(self, other: Self) -> Matrix { let self_iter = self.inner.iter(); let inner = self_iter .zip(other.inner.iter()) .map(|(&u, &v)| u + v) .collect(); Matrix { cols: self.cols, inner, } } } impl Sub for &Matrix { type Output = Matrix; fn sub(self, other: Self) -> Matrix { let self_iter = self.inner.iter(); let inner = self_iter .zip(other.inner.iter()) .map(|(&u, &v)| u - v) .collect(); Matrix { cols: self.cols, inner, } } } impl Mul<f64> for &Matrix { type Output = Matrix; fn mul(self, scalar: f64) -> Matrix { let inner = self.inner.iter().map(|&v| v * scalar).collect(); Matrix { cols: self.cols, inner, } } } impl Mul for &Matrix { type Output = Matrix; fn mul(self, other: Self) -> Matrix { assert_eq!(self.cols, other.rows()); let mut matrix = Matrix::zero(self.rows(), other.cols); for i in 0..self.rows() { for k in 0..self.cols { for j in 0..other.cols { matrix[i][j] += self[i][k] * other[k][j]; } } } matrix } } } pub fn extended_gcd(a: i64, b: i64) -> (i64, i64, i64) { if b == 0 { (a.abs(), a.signum(), 0) } else { let (d, coef_b, coef_a) = extended_gcd(b, a % b); (d, coef_a, coef_b - coef_a * (a / b)) } } pub fn canon_egcd(a: i64, b: i64, c: i64) -> Option<(i64, i64, i64)> { let (d, _, coef_b_init) = extended_gcd(a, b); if c % d == 0 { let a_d = (a / d).abs(); let coef_b = (coef_b_init * (c / d) % a_d + a_d) % a_d; let coef_a = (c - b * coef_b) / a; Some((d, coef_a, coef_b)) } else { None } } fn pos_mod(n: i64, m: i64) -> i64 { if n < 0 { n + m } else { n } } fn mod_mul(a: i64, b: i64, m: i64) -> i64 { pos_mod((a as i128 * b as i128 % m as i128) as i64, m) } fn mod_exp(mut base: i64, mut exp: u64, m: i64) -> i64 { assert!(m >= 1); let mut ans = 1 % m; base %= m; while exp > 0 { if exp % 2 == 1 { ans = mod_mul(ans, base, m); } base = mod_mul(base, base, m); exp /= 2; } pos_mod(ans, m) } fn is_strong_probable_prime(n: i64, exp: u64, r: i64, a: i64) -> bool { let mut x = mod_exp(a, exp, n); if x == 1 || x == n - 1 { return true; } for _ in 1..r { x = mod_mul(x, x, n); if x == n - 1 { return true; } } false } pub fn is_prime(n: i64) -> bool { const BASES: [i64; 12] = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37]; assert!(n >= 0); match n { 0 | 1 => false, 2 | 3 => true, _ if n % 2 == 0 => false, _ => { let r = (n - 1).trailing_zeros() as i64; let exp = (n - 1) as u64 >> r; BASES .iter() .all(|&base| base > n - 2 || is_strong_probable_prime(n, exp, r, base)) } } } fn pollard_rho(n: i64) -> i64 { for a in 1..n { let f = |x| pos_mod(mod_mul(x, x, n) + a, n); let mut x = 2; let mut y = 2; loop { x = f(x); y = f(f(y)); let div = num::fast_gcd(x - y, n); if div == n { break; } else if div > 1 { return div; } } } panic!("No divisor found!"); } pub fn factorize(n: i64) -> Vec<i64> { assert!(n >= 1); let r = n.trailing_zeros() as usize; let mut factors = vec![2; r]; let mut stack = match n >> r { 1 => vec![], x => vec![x], }; while let Some(top) = stack.pop() { if is_prime(top) { factors.push(top); } else { let div = pollard_rho(top); stack.push(div); stack.push(top / div); } } factors.sort_unstable(); factors } } pub mod order { pub fn asserting_cmp<T: PartialOrd>(a: &T, b: &T) -> std::cmp::Ordering { a.partial_cmp(b).expect("Comparing incomparable elements") } pub fn slice_lower_bound<T: PartialOrd>(slice: &[T], key: &T) -> usize { slice .binary_search_by(|x| asserting_cmp(x, key).then(std::cmp::Ordering::Greater)) .unwrap_err() } pub fn slice_upper_bound<T: PartialOrd>(slice: &[T], key: &T) -> usize { slice .binary_search_by(|x| asserting_cmp(x, key).then(std::cmp::Ordering::Less)) .unwrap_err() } pub fn merge_sorted<T: PartialOrd>( i1: impl IntoIterator<Item = T>, i2: impl IntoIterator<Item = T>, ) -> Vec<T> { let mut i1 = i1.into_iter().peekable(); let mut i2 = i2.into_iter().peekable(); let mut merged = Vec::with_capacity(i1.size_hint().0 + i2.size_hint().0); while let (Some(a), Some(b)) = (i1.peek(), i2.peek()) { merged.push(if a <= b { i1.next() } else { i2.next() }.unwrap()); } merged.extend(i1.chain(i2)); merged } pub fn merge_sort<T: Ord>(mut v: Vec<T>) -> Vec<T> { if v.len() < 2 { v } else { let v2 = v.split_off(v.len() / 2); merge_sorted(merge_sort(v), merge_sort(v2)) } } pub struct SparseIndex { coords: Vec<i64>, } impl SparseIndex { pub fn new(mut coords: Vec<i64>) -> Self { coords.sort_unstable(); coords.dedup(); Self { coords } } pub fn compress(&self, q: i64) -> Result<usize, usize> { self.coords.binary_search(&q) } } #[derive(Default)] pub struct PiecewiseLinearConvexFn { recent_lines: Vec<(f64, f64)>, sorted_lines: Vec<(f64, f64)>, intersections: Vec<f64>, amortized_work: usize, } impl PiecewiseLinearConvexFn { pub fn max_with(&mut self, new_m: f64, new_b: f64) { self.recent_lines.push((new_m, new_b)); } fn max_with_sorted(&mut self, new_m: f64, new_b: f64) { while let Some(&(last_m, last_b)) = self.sorted_lines.last() { if (new_m - last_m).abs() > 1e-9 { let intersect = (new_b - last_b) / (last_m - new_m); if self.intersections.last() < Some(&intersect) { self.intersections.push(intersect); break; } } self.intersections.pop(); self.sorted_lines.pop(); } self.sorted_lines.push((new_m, new_b)); } fn eval_unoptimized(&self, x: f64) -> f64 { let idx = slice_lower_bound(&self.intersections, &x); self.recent_lines .iter() .chain(self.sorted_lines.get(idx)) .map(|&(m, b)| m * x + b) .max_by(asserting_cmp) .unwrap_or(-1e18) } pub fn evaluate(&mut self, x: f64) -> f64 { self.amortized_work += self.recent_lines.len(); if self.amortized_work > self.sorted_lines.len() { self.amortized_work = 0; self.recent_lines.sort_unstable_by(asserting_cmp); self.intersections.clear(); let all_lines = merge_sorted(self.recent_lines.drain(..), self.sorted_lines.drain(..)); for (new_m, new_b) in all_lines { self.max_with_sorted(new_m, new_b); } } self.eval_unoptimized(x) } } } pub mod range_query { pub mod dynamic_arq { use super::ArqSpec; pub struct DynamicArqNode<T: ArqSpec> { val: T::S, app: Option<T::F>, down: (usize, usize), } impl<T: ArqSpec> Clone for DynamicArqNode<T> { fn clone(&self) -> Self { Self { val: self.val.clone(), app: self.app.clone(), down: self.down, } } } impl<T: ArqSpec> Default for DynamicArqNode<T> { fn default() -> Self { Self { val: T::identity(), app: None, down: (usize::max_value(), usize::max_value()), } } } impl<T: ArqSpec> DynamicArqNode<T> { fn apply(&mut self, f: &T::F, size: i64) { self.val = T::apply(f, &self.val, size); if size > 1 { let h = match self.app { Some(ref g) => T::compose(f, g), None => f.clone(), }; self.app = Some(h); } } } pub type ArqView = (usize, i64); pub struct DynamicArq<T: ArqSpec> { nodes: Vec<DynamicArqNode<T>>, is_persistent: bool, } impl<T: ArqSpec> DynamicArq<T> { pub fn new(is_persistent: bool) -> Self { Self { nodes: vec![], is_persistent, } } pub fn build_from_identity(&mut self, size: i64) -> ArqView { self.nodes.push(DynamicArqNode::default()); (self.nodes.len() - 1, size) } pub fn build_from_slice(&mut self, init_val: &[T::S]) -> ArqView { if init_val.len() == 1 { let root = DynamicArqNode { val: init_val[0].clone(), ..Default::default() }; self.nodes.push(root); (self.nodes.len() - 1, 1) } else { let ls = init_val.len() / 2; let (l_init, r_init) = init_val.split_at(ls); let l_view = self.build_from_slice(l_init); let r_view = self.build_from_slice(r_init); self.merge_equal_sized(l_view, r_view) } } pub fn merge_equal_sized( &mut self, (lp, ls): ArqView, (rp, rs): ArqView, ) -> ArqView { assert!(ls == rs || ls + 1 == rs); let p = self.nodes.len(); let root = DynamicArqNode { down: (lp, rp), ..Default::default() }; self.nodes.push(root); self.pull(p); (p, ls + rs) } pub fn push(&mut self, (p, s): ArqView) -> (ArqView, ArqView) { if self.nodes[p].down.0 == usize::max_value() { self.nodes.push(DynamicArqNode::default()); self.nodes.push(DynamicArqNode::default()); self.nodes[p].down = (self.nodes.len() - 2, self.nodes.len() - 1) }; let (lp, rp) = self.nodes[p].down; let ls = s / 2; if let Some(ref f) = self.nodes[p].app.take() { self.nodes[lp].apply(f, ls); self.nodes[rp].apply(f, s - ls); } ((lp, ls), (rp, s - ls)) } pub fn pull(&mut self, p: usize) { let (lp, rp) = self.nodes[p].down; let left_val = &self.nodes[lp].val; let right_val = &self.nodes[rp].val; self.nodes[p].val = T::op(left_val, right_val); } fn clone_node(&mut self, p_orig: usize) -> usize { if self.is_persistent { let node = self.nodes[p_orig].clone(); self.nodes.push(node); self.nodes.len() - 1 } else { p_orig } } pub fn update(&mut self, view: ArqView, l: i64, r: i64, f: &T::F) -> ArqView { let (p_orig, s) = view; if r < 0 || s - 1 < l { view } else if l <= 0 && s - 1 <= r { let p_clone = self.clone_node(p_orig); self.nodes[p_clone].apply(f, s); (p_clone, s) } else { let (l_view, r_view) = self.push(view); let ls = l_view.1; let p_clone = self.clone_node(p_orig); let lp_clone = self.update(l_view, l, r, f).0; let rp_clone = self.update(r_view, l - ls, r - ls, f).0; self.nodes[p_clone].down = (lp_clone, rp_clone); self.pull(p_clone); (p_clone, s) } } pub fn query(&mut self, view: ArqView, l: i64, r: i64) -> T::S { let (p, s) = view; if r < 0 || s - 1 < l { T::identity() } else if l <= 0 && s - 1 <= r { self.nodes[p].val.clone() } else { let (l_view, r_view) = self.push(view); let ls = l_view.1; let l_agg = self.query(l_view, l, r); let r_agg = self.query(r_view, l - ls, r - ls); T::op(&l_agg, &r_agg) } } } pub fn first_negative( arq: &mut DynamicArq<super::specs::AssignMin>, view: ArqView, ) -> Option<i64> { let (p, s) = view; if s == 1 { Some(0).filter(|_| arq.nodes[p].val < 0) } else { let (l_view, r_view) = arq.push(view); let (lp, ls) = l_view; if arq.nodes[lp].val < 0 { first_negative(arq, l_view) } else { first_negative(arq, r_view).map(|x| ls + x) } } } } pub mod specs { pub trait ArqSpec { type S: Clone; type F: Clone; fn op(a: &Self::S, b: &Self::S) -> Self::S; fn identity() -> Self::S; fn compose(f: &Self::F, g: &Self::F) -> Self::F; fn apply(f: &Self::F, a: &Self::S, size: i64) -> Self::S; } pub enum AssignMin {} impl ArqSpec for AssignMin { type S = i64; type F = i64; fn op(&a: &Self::S, &b: &Self::S) -> Self::S { a.min(b) } fn identity() -> Self::S { i64::max_value() } fn compose(&f: &Self::F, _: &Self::F) -> Self::F { f } fn apply(&f: &Self::F, _: &Self::S, _: i64) -> Self::S { f } } pub enum AssignSum {} impl ArqSpec for AssignSum { type S = i64; type F = i64; fn op(&a: &Self::S, &b: &Self::S) -> Self::S { a + b } fn identity() -> Self::S { 0 } fn compose(&f: &Self::F, _: &Self::F) -> Self::F { f } fn apply(&f: &Self::F, _: &Self::S, size: i64) -> Self::S { f * size } } pub enum SupplyDemand {} impl ArqSpec for SupplyDemand { type S = (i64, i64, i64); type F = (i64, i64); fn op((p1, o1, s1): &Self::S, (p2, o2, s2): &Self::S) -> Self::S { let extra = (p1 - s1).min(o2 - s2); (p1 + p2, o1 + o2, s1 + s2 + extra) } fn identity() -> Self::S { (0, 0, 0) } fn compose(_: &Self::F, _: &Self::F) -> Self::F { unimplemented!() } fn apply(&(p_add, o_add): &Self::F, &(p, o, _): &Self::S, s: i64) -> Self::S { assert_eq!(s, 1); let p = p + p_add; let o = o + o_add; (p, o, p.min(o)) } } } pub mod sqrt_decomp { pub trait MoState { type Q; type A; const L_R_RATIO: f64 = 1.0; fn query(&self, q: &Self::Q) -> Self::A; fn insert_left(&mut self, pos: usize); fn remove_left(&mut self, pos: usize); fn insert_right(&mut self, pos: usize) { self.insert_left(pos); } fn remove_right(&mut self, pos: usize) { self.remove_left(pos); } fn process(&mut self, queries: &[(usize, usize, Self::Q)]) -> Vec<Self::A> { let q = queries.len(); let mut q_positions: Vec<usize> = (0..q).collect(); if let Some(max_r) = queries.iter().map(|&(_, r, _)| r).max() { let q_adjusted = q as f64 * Self::L_R_RATIO; let bucket_width = 1 + max_r / q_adjusted.sqrt() as usize; q_positions.sort_unstable_by_key(|&i| { let (l, mut r) = (queries[i].0, queries[i].1); let bucket = l / bucket_width; if bucket % 2 != 0 { r = max_r - r; } (bucket, r) }); } let (mut cur_l, mut cur_r) = (1, 0); let mut answers = Vec::with_capacity(queries.len()); for i in q_positions { let (l, r, ref q) = queries[i]; while cur_l > l { cur_l -= 1; self.insert_left(cur_l); } while cur_r < r { cur_r += 1; self.insert_right(cur_r); } while cur_l < l { self.remove_left(cur_l); cur_l += 1; } while cur_r > r { self.remove_right(cur_r); cur_r -= 1; } answers.push((i, self.query(q))); } answers.sort_unstable_by_key(|&(i, _)| i); answers.into_iter().map(|(_, ans)| ans).collect() } } pub struct DistinctVals { vals: Vec<usize>, counts: Vec<usize>, distinct: usize, } impl DistinctVals { pub fn new(vals: Vec<usize>) -> Self { let &max_val = vals.iter().max().unwrap_or(&0); Self { vals, counts: vec![0; max_val + 1], distinct: 0, } } } impl MoState for DistinctVals { type Q = (); type A = usize; fn query(&self, _: &Self::Q) -> Self::A { self.distinct } fn insert_left(&mut self, pos: usize) { let v = self.vals[pos]; if self.counts[v] == 0 { self.distinct += 1; } self.counts[v] += 1; } fn remove_left(&mut self, pos: usize) { let v = self.vals[pos]; self.counts[v] -= 1; if self.counts[v] == 0 { self.distinct -= 1; } } } } pub mod static_arq { use super::ArqSpec; pub struct StaticArq<T: ArqSpec> { val: Vec<T::S>, app: Vec<Option<T::F>>, } impl<T: ArqSpec> StaticArq<T> { pub fn new(init_val: &[T::S]) -> Self { let size = init_val.len(); let mut val = vec![T::identity(); size]; val.extend_from_slice(init_val); let app = vec![None; size]; let mut arq = Self { val, app }; for p in (0..size).rev() { arq.pull(p); } arq } fn apply(&mut self, p: usize, f: &T::F, s: i64) { self.val[p] = T::apply(f, &self.val[p], s); if let Some(lazy) = self.app.get_mut(p) { let h = match *lazy { Some(ref g) => T::compose(f, g), None => f.clone(), }; *lazy = Some(h); } } fn push(&mut self, p: usize) { if let Some(ref f) = self.app[p].take() { let s = ((self.app.len() + p - 1) / p / 2).next_power_of_two() as i64; self.apply(p << 1, f, s); self.apply(p << 1 | 1, f, s); } } fn pull(&mut self, p: usize) { self.val[p] = T::op(&self.val[p << 1], &self.val[p << 1 | 1]); } fn push_to(&mut self, p: usize) { let one_plus_floor_log_p = (p + 1).next_power_of_two().trailing_zeros(); for i in (1..one_plus_floor_log_p).rev() { self.push(p >> i); } } fn pull_from(&mut self, mut p: usize) { while p > 1 { p >>= 1; self.pull(p); } } pub fn update(&mut self, mut l: usize, mut r: usize, f: &T::F) { l += self.app.len(); r += self.app.len(); if l < r { self.push_to(l); } self.push_to(r); let (mut l0, mut r0, mut s) = (1, 1, 1); while l <= r { if l & 1 == 1 { self.apply(l, f, s); l0 = l0.max(l); l += 1; } if r & 1 == 0 { self.apply(r, f, s); r0 = r0.max(r); r -= 1; } l >>= 1; r >>= 1; s <<= 1; } self.pull_from(l0); self.pull_from(r0); } pub fn query(&mut self, mut l: usize, mut r: usize) -> T::S { l += self.app.len(); r += self.app.len(); if l < r { self.push_to(l); } self.push_to(r); let (mut l_agg, mut r_agg) = (T::identity(), T::identity()); while l <= r { if l & 1 == 1 { l_agg = T::op(&l_agg, &self.val[l]); l += 1; } if r & 1 == 0 { r_agg = T::op(&self.val[r], &r_agg); r -= 1; } l >>= 1; r >>= 1; } T::op(&l_agg, &r_agg) } } pub fn first_negative(arq: &mut StaticArq<super::specs::AssignMin>) -> Option<usize> { assert!(arq.app.len().is_power_of_two()); let mut p = 1; if arq.val[p] >= 0 { None } else { while p < arq.app.len() { arq.push(p); p <<= 1; if arq.val[p] >= 0 { p |= 1; } } Some(p - arq.app.len()) } } } pub use self::dynamic_arq::{ArqView, DynamicArq}; pub use self::specs::ArqSpec; pub use self::static_arq::StaticArq; } pub mod rng { pub type SmallRng = Xoshiro256PlusPlus; #[derive(Debug, Clone, PartialEq, Eq)] pub struct Xoshiro256PlusPlus { s: [u64; 4], } impl Xoshiro256PlusPlus { pub fn new(mut state: u64) -> Self { const PHI: u64 = 0x9e3779b97f4a7c15; let mut seed = <[u64; 4]>::default(); for chunk in &mut seed { state = state.wrapping_add(PHI); let mut z = state; z = (z ^ (z >> 30)).wrapping_mul(0xbf58476d1ce4e5b9); z = (z ^ (z >> 27)).wrapping_mul(0x94d049bb133111eb); z = z ^ (z >> 31); *chunk = z; } Self { s: seed } } #[inline] pub fn next_u32(&mut self) -> u32 { (self.next_u64() >> 32) as u32 } #[inline] pub fn next_u64(&mut self) -> u64 { let result_plusplus = self.s[0] .wrapping_add(self.s[3]) .rotate_left(23) .wrapping_add(self.s[0]); let t = self.s[1] << 17; self.s[2] ^= self.s[0]; self.s[3] ^= self.s[1]; self.s[1] ^= self.s[2]; self.s[0] ^= self.s[3]; self.s[2] ^= t; self.s[3] = self.s[3].rotate_left(45); result_plusplus } } } pub mod scanner { use std::io; use std::str; pub struct Scanner<R> { reader: R, buffer: Vec<String>, } impl<R: io::BufRead> Scanner<R> { pub fn new(reader: R) -> Self { Self { reader, buffer: vec![], } } pub fn token<T: str::FromStr>(&mut self) -> T { loop { if let Some(token) = self.buffer.pop() { return token.parse().ok().expect("Failed parse"); } let mut input = String::new(); self.reader.read_line(&mut input).expect("Failed read"); self.buffer = input.split_whitespace().rev().map(String::from).collect(); } } } pub struct UnsafeScanner<R> { reader: R, buf_str: Vec<u8>, buf_iter: str::SplitAsciiWhitespace<'static>, } impl<R: io::BufRead> UnsafeScanner<R> { pub fn new(reader: R) -> Self { Self { reader, buf_str: vec![], buf_iter: "".split_ascii_whitespace(), } } pub fn token<T: str::FromStr>(&mut self) -> T { loop { if let Some(token) = self.buf_iter.next() { return token.parse().ok().expect("Failed parse"); } self.buf_str.clear(); self.reader .read_until(b'\n', &mut self.buf_str) .expect("Failed read"); self.buf_iter = unsafe { let slice = str::from_utf8_unchecked(&self.buf_str); std::mem::transmute(slice.split_ascii_whitespace()) } } } } pub fn scanner_from_file(filename: &str) -> Scanner<io::BufReader<std::fs::File>> { let file = std::fs::File::open(filename).expect("Input file not found"); Scanner::new(io::BufReader::new(file)) } pub fn writer_to_file(filename: &str) -> io::BufWriter<std::fs::File> { let file = std::fs::File::create(filename).expect("Output file not found"); io::BufWriter::new(file) } } pub mod printer {} pub mod string_proc { use std::cmp::{max, min}; use std::collections::{hash_map::Entry, HashMap, VecDeque}; pub struct Trie<C: std::hash::Hash + Eq> { links: Vec<HashMap<C, usize>>, } impl<C: std::hash::Hash + Eq> Default for Trie<C> { fn default() -> Self { Self { links: vec![HashMap::new()], } } } impl<C: std::hash::Hash + Eq> Trie<C> { pub fn insert(&mut self, word: impl IntoIterator<Item = C>) -> usize { let mut node = 0; for ch in word { let len = self.links.len(); node = match self.links[node].entry(ch) { Entry::Occupied(entry) => *entry.get(), Entry::Vacant(entry) => { entry.insert(len); self.links.push(HashMap::new()); len } } } node } pub fn get(&self, word: impl IntoIterator<Item = C>) -> Option<usize> { let mut node = 0; for ch in word { node = *self.links[node].get(&ch)?; } Some(node) } } pub struct Matcher<'a, C: Eq> { pub pattern: &'a [C], pub fail: Vec<usize>, } impl<'a, C: Eq> Matcher<'a, C> { pub fn new(pattern: &'a [C]) -> Self { let mut fail = Vec::with_capacity(pattern.len()); fail.push(0); let mut len = 0; for ch in &pattern[1..] { while len > 0 && pattern[len] != *ch { len = fail[len - 1]; } if pattern[len] == *ch { len += 1; } fail.push(len); } Self { pattern, fail } } pub fn kmp_match(&self, text: impl IntoIterator<Item = C>) -> Vec<usize> { let mut len = 0; text.into_iter() .map(|ch| { if len == self.pattern.len() { len = self.fail[len - 1]; } while len > 0 && self.pattern[len] != ch { len = self.fail[len - 1]; } if self.pattern[len] == ch { len += 1; } len }) .collect() } } pub struct MultiMatcher<C: std::hash::Hash + Eq> { pub trie: Trie<C>, pub pat_id: Vec<Option<usize>>, pub fail: Vec<usize>, pub fast: Vec<usize>, } impl<C: std::hash::Hash + Eq> MultiMatcher<C> { fn next(trie: &Trie<C>, fail: &[usize], mut node: usize, ch: &C) -> usize { loop { if let Some(&child) = trie.links[node].get(ch) { return child; } else if node == 0 { return 0; } node = fail[node]; } } pub fn new(patterns: impl IntoIterator<Item = impl IntoIterator<Item = C>>) -> Self { let mut trie = Trie::default(); let pat_nodes: Vec<usize> = patterns.into_iter().map(|pat| trie.insert(pat)).collect(); let mut pat_id = vec![None; trie.links.len()]; for (i, node) in pat_nodes.into_iter().enumerate() { pat_id[node] = Some(i); } let mut fail = vec![0; trie.links.len()]; let mut fast = vec![0; trie.links.len()]; let mut q: VecDeque<usize> = trie.links[0].values().cloned().collect(); while let Some(node) = q.pop_front() { for (ch, &child) in &trie.links[node] { let nx = Self::next(&trie, &fail, fail[node], &ch); fail[child] = nx; fast[child] = if pat_id[nx].is_some() { nx } else { fast[nx] }; q.push_back(child); } } Self { trie, pat_id, fail, fast, } } pub fn ac_match(&self, text: impl IntoIterator<Item = C>) -> Vec<usize> { let mut node = 0; text.into_iter() .map(|ch| { node = Self::next(&self.trie, &self.fail, node, &ch); node }) .collect() } pub fn get_end_pos_and_pat_id(&self, match_nodes: &[usize]) -> Vec<(usize, usize)> { let mut res = vec![]; for (text_pos, &(mut node)) in match_nodes.iter().enumerate() { while node != 0 { if let Some(id) = self.pat_id[node] { res.push((text_pos + 1, id)); } node = self.fast[node]; } } res } } pub struct SuffixArray { pub sfx: Vec<usize>, pub rank: Vec<Vec<usize>>, } impl SuffixArray { fn counting_sort( vals: impl Iterator<Item = usize> + Clone, val_to_key: &[usize], max_key: usize, ) -> Vec<usize> { let mut counts = vec![0; max_key]; for v in vals.clone() { counts[val_to_key[v]] += 1; } let mut total = 0; for c in counts.iter_mut() { total += *c; *c = total - *c; } let mut result = vec![0; total]; for v in vals { let c = &mut counts[val_to_key[v]]; result[*c] = v; *c += 1; } result } pub fn new(text: impl IntoIterator<Item = u8>) -> Self { let init_rank = text.into_iter().map(|ch| ch as usize).collect::<Vec<_>>(); let n = init_rank.len(); let mut sfx = Self::counting_sort(0..n, &init_rank, 256); let mut rank = vec![init_rank]; for skip in (0..).map(|i| 1 << i).take_while(|&skip| skip < n) { let prev_rank = rank.last().unwrap(); let mut cur_rank = prev_rank.clone(); let pos = (n - skip..n).chain(sfx.into_iter().filter_map(|p| p.checked_sub(skip))); sfx = Self::counting_sort(pos, &prev_rank, max(n, 256)); let mut prev = sfx[0]; cur_rank[prev] = 0; for &cur in sfx.iter().skip(1) { if max(prev, cur) + skip < n && prev_rank[prev] == prev_rank[cur] && prev_rank[prev + skip] == prev_rank[cur + skip] { cur_rank[cur] = cur_rank[prev]; } else { cur_rank[cur] = cur_rank[prev] + 1; } prev = cur; } rank.push(cur_rank); } Self { sfx, rank } } pub fn longest_common_prefix(&self, mut i: usize, mut j: usize) -> usize { let mut len = 0; for (k, rank) in self.rank.iter().enumerate().rev() { if rank[i] == rank[j] { i += 1 << k; j += 1 << k; len += 1 << k; if max(i, j) >= self.sfx.len() { break; } } } len } } pub fn palindromes(text: &[impl Eq]) -> Vec<usize> { let mut pal = Vec::with_capacity(2 * text.len() - 1); pal.push(1); while pal.len() < pal.capacity() { let i = pal.len() - 1; let max_len = min(i + 1, pal.capacity() - i); while pal[i] < max_len && text[(i - pal[i] - 1) / 2] == text[(i + pal[i] + 1) / 2] { pal[i] += 2; } if let Some(a) = 1usize.checked_sub(pal[i]) { pal.push(a); } else { for d in 1.. { let (a, b) = (pal[i - d], pal[i] - d); if a < b { pal.push(a); } else { pal.push(b); break; } } } } pal } pub fn z_algorithm(text: &[impl Eq]) -> Vec<usize> { let n = text.len(); let (mut l, mut r) = (1, 1); let mut z = Vec::with_capacity(n); z.push(n); for i in 1..n { if r > i + z[i - l] { z.push(z[i - l]); } else { l = i; while r < i || (r < n && text[r - i] == text[r]) { r += 1; } z.push(r - i); } } z } } } use algo::scanner::UnsafeScanner; static mut SCANNER: MaybeUninit<UnsafeScanner<io::StdinLock>> = MaybeUninit::uninit(); static mut WRITER: MaybeUninit<io::BufWriter<io::StdoutLock>> = MaybeUninit::uninit(); pub const YES: &str = "YES"; pub const NO: &str = "NO"; pub fn init() { unsafe { let scanner = UnsafeScanner::new(transmute::<StdinLock, StdinLock<'static>>( io::stdin().lock(), )); SCANNER.as_mut_ptr().write(scanner); let writer = io::BufWriter::new(transmute::<io::StdoutLock, io::StdoutLock<'static>>( io::stdout().lock(), )); WRITER.as_mut_ptr().write(writer); } } #[cfg(generator)] pub fn r< T: rand::distributions::uniform::SampleUniform, R: rand::distributions::uniform::SampleRange<T>, >( r: R, ) -> T { use rand::Rng; rand::thread_rng().gen_range(r) } #[inline(always)] pub fn __scanner() -> &'static mut UnsafeScanner<io::StdinLock<'static>> { unsafe { &mut *SCANNER.as_mut_ptr() } } #[inline(always)] pub fn __writer() -> &'static mut io::BufWriter<io::StdoutLock<'static>> { unsafe { &mut *WRITER.as_mut_ptr() } } pub fn flush() { __writer().flush().unwrap(); } #[macro_export] macro_rules! main { (multi) => { fn main() { $crate::init(); input!(t: usize); for _ in 0..t { solve(); } $crate::flush(); } }; (multi , intr) => { fn main() { $crate::init(); input!(t: usize); for _ in 0..t { solve(); $crate::flush(); } } }; () => { fn main() { $crate::init(); solve(); $crate::flush(); } }; } #[macro_export] macro_rules! flush { () => { $crate::flush(); }; } #[macro_export] macro_rules ! input { ($ ($ r : tt) *) => { let sc = $ crate :: __scanner () ; input_inner ! { sc , $ ($ r) * } } ; } #[macro_export] macro_rules ! input_inner { ($ sc : expr) => { } ; ($ sc : expr ,) => { } ; ($ sc : expr , $ var : ident : $ t : tt $ ($ r : tt) *) => { # [allow (unused_mut)] let mut $ var = read_value ! ($ sc , $ t) ; input_inner ! { $ sc $ ($ r) * } } ; } #[macro_export] macro_rules ! read_value { ($ sc : expr , ($ ($ t : tt) ,*)) => { ($ (read_value ! ($ sc , $ t)) ,*) } ; ($ sc : expr , [$ t : tt ; $ len : expr]) => { (0 ..$ len) . map (| _ | read_value ! ($ sc , $ t)) . collect ::< Vec < _ >> () } ; ($ sc : expr , c) => { read_value ! ($ sc , String) . chars () . collect ::< Vec < char >> () } ; ($ sc : expr , b) => { read_value ! ($ sc , String) . into_bytes () } ; ($ sc : expr , u1) => { read_value ! ($ sc , usize) - 1 } ; ($ sc : expr , $ t : ty) => { $ sc . token ::<$ t > () } ; } #[macro_export] macro_rules ! println { ($ ($ args : tt) *) => { { use std :: io :: Write ; writeln ! ($ crate :: __writer () , $ ($ args) *) . unwrap () } } ; } #[macro_export] macro_rules ! print { ($ ($ args : tt) *) => { { use std :: io :: Write ; write ! ($ crate :: __writer () , $ ($ args) *) . unwrap () } } ; } #[macro_export] macro_rules ! out { () => { } ; ($ e : expr) => { print ! ("{}" , $ e) ; } ; ($ e : expr , $ ($ es : expr) ,*) => { out ! ($ e) ; out ! (" ") ; out ! ($ ($ es) ,*) ; } ; } #[macro_export] macro_rules ! outln { ($ ($ args : tt) *) => { { out ! ($ ($ args) *) ; println ! () ; } } ; } pub fn out_spaced<T: Display>(it: impl IntoIterator<Item = T>) { let mut first = true; for v in it { if !first { print!(" {}", v); } else { print!("{}", v); first = false; } } } pub fn out_lined<T: Display>(it: impl IntoIterator<Item = T>) { let mut first = true; for v in it { if !first { print!("\n{}", v); } else { print!("{}", v); first = false; } } } pub fn yn(yes: bool) -> &'static str { if yes { "YES" } else { "NO" } } #[macro_export] macro_rules ! ans { ($ ($ args : tt) *) => { output ! ($ ($ args) *;) ; return ; } ; } #[macro_export] macro_rules ! output { (; $ ($ r : tt) *) => { println ! () ; output ! ($ ($ r) *) ; } ; ($ x : expr ,* $ ($ r : tt) *) => { $ crate :: out_spaced ($ x) ; output ! ($ ($ r) *) ; } ; ($ x : expr ;* $ ($ r : tt) *) => { $ crate :: out_lined ($ x) ; output ! ($ ($ r) *) ; } ; ($ x : expr , $ ($ r : tt) *) => { out ! ($ x) ; print ! (" ") ; output ! ($ ($ r) *) ; } ; ($ x : expr ; $ ($ r : tt) *) => { out ! ($ x) ; println ! () ; output ! ($ ($ r) *) ; } ; ($ x : expr) => { print ! ("{}" , $ x) ; } ; () => { } ; } #[macro_export] macro_rules ! cmp_go { (@ go $ a : ident , $ b : ident , .$ x : tt , $ ($ tt : tt) *) => { match ($ a .$ x) . cmp (& ($ b .$ x)) { std :: cmp :: Ordering :: Equal => cmp_go ! (@ go $ a , $ b , $ ($ tt) *) , ordering => ordering } } ; (@ go $ a : ident , $ b : ident , .$ x : tt) => { cmp_go ! (@ go $ a , $ b , .$ x ,) } ; (@ go $ a : ident , $ b : ident , $ x : expr ,) => { cmp_go ! (@ go $ a , $ b , $ x ,) } ; (@ go $ a : ident , $ b : ident , $ x : expr , $ ($ tt : tt) *) => { match $ x { mut x => match (x ($ a)) . cmp (& (x (&$ b))) { std :: cmp :: Ordering :: Equal => cmp_go ! (@ go $ a , $ b , $ ($ tt) *) , ordering => ordering } } } ; (@ go $ a : ident , $ b : ident , $ x : tt , $ ($ tt : tt) *) => { match ($ x ($ a)) . cmp (& ($ x (&$ b))) { std :: cmp :: Ordering :: Equal => cmp_go ! (@ go $ a , $ b , $ ($ tt) *) , ordering => ordering } } ; (@ go $ a : ident , $ b : ident ,) => { std :: cmp :: Ordering :: Equal } ; } #[macro_export(local_inner_macros)] macro_rules ! cmp { ($ ($ tt : tt) *) => { | a , b | { cmp_go ! (@ go a , b , $ ($ tt) *) } } ; } pub trait IExt { fn i(self) -> i64; } impl IExt for usize { fn i(self) -> i64 { self as i64 } } pub trait UExt { fn u(self) -> usize; } impl UExt for usize { fn u(self) -> usize { self } } impl UExt for i64 { fn u(self) -> usize { self as usize } } impl UExt for i32 { fn u(self) -> usize { self as usize } } pub fn freq_map<t: Hash + Copy + Eq>(v: &[t]) -> m<t, u> { let mut m = m::new(); for x in v { *m.entry(*x).or_default() += 1; } m } #[macro_export] macro_rules ! query { ($ ($ name : ident ($ ($ arg : ident) ,*) : $ ret : ty = $ query : expr ;) *) => { $ (pub fn $ name ($ ($ arg : impl :: std :: fmt :: Display) ,*) -> $ ret { println ! ($ query , $ ($ arg) ,*) ; $ crate :: flush () ; input ! (v : $ ret) ; v }) * } ; } #[macro_export] macro_rules! rand { ($ ($ name : ident = $ value : expr ;) *) => {}; } #[macro_export] macro_rules ! cp { ($ (kind = multi ;) ? input { $ ($ input : tt) * } $ (rand { $ ($ rand : tt) * }) ? $ (query { $ ($ query : tt) * }) ? $ (pre { $ ($ pre : tt) * }) ? $ (naive { $ ($ naive : tt) * }) ? solve $ solve : expr) => { $ (__random ! { $ ($ rand) * }) ? $ (query ! { $ ($ query) * }) ? # [cfg (not (generator))] fn main () { $ crate :: init () ; $ ($ ($ pre) *) ? input ! (t : usize) ; for _ in 0 .. t { input ! { $ ($ input) * } (|| { # [cfg (naive)] { $ ($ ($ naive) *) ? } # [cfg (not (naive))] { $ solve } }) () ; $ crate :: flush () ; } } # [cfg (generator)] fn main () { $ crate :: init () ; println ! ("{}" , 1) ; __generate_input ! { $ ($ input) * } $ crate :: flush () ; } } ; (kind = single ; input { $ ($ input : tt) * } $ (rand { $ ($ rand : tt) * }) ? $ (query { $ ($ query : tt) * }) ? $ (pre { $ ($ pre : tt) * }) ? $ (naive { $ ($ naive : tt) * }) ? solve { $ ($ solve : tt) * }) => { $ (__random ! { $ ($ rand) * }) ? $ (query ! { $ ($ query) * }) ? # [cfg (not (generator))] fn main () { $ crate :: init () ; $ ($ ($ pre) *) ? input ! { $ ($ input) * } (|| { # [cfg (naive)] { $ ($ ($ naive) *) ? } # [cfg (not (naive))] { $ ($ solve) * } }) () ; $ crate :: flush () ; } # [cfg (generator)] fn main () { $ crate :: init () ; __generate_input ! { $ ($ input) * } $ crate :: flush () ; } } ; } #[macro_export] macro_rules ! __random { ($ ($ name : ident = $ value : expr ;) *) => { macro_rules ! __get_random_value { $ (($ name) => { $ value } ;) * } } } #[macro_export] macro_rules ! __generate_input { ($ ($ name : ident : $ ty : tt) ,* $ (,) ?) => { $ (__generate_value ! { $ name : $ ty }) * } } #[macro_export] macro_rules! __print_value { ($ name : ident : ($ a : ty , $ b : ty)) => { println!("{} {}", $name.0, $name.1); }; ($ name : ident : ($ a : ty , $ b : ty , $ c : ty)) => { println!("{} {} {}", $name.0, $name.1, $name.2); }; ($ name : ident : ($ a : ty , $ b : ty , $ c : ty , $ d : ty)) => { println!("{} {} {} {}", $name.0, $name.1, $name.2, $name.3); }; ($ name : ident : $ ty : ty) => { println!("{}", $name); }; } #[macro_export] macro_rules! __generate_value { ($ var : ident : [$ t : tt ; $ len : expr]) => { for _ in 0..$len { __generate_value!($var: $t); } }; ($ var : ident : $ t : tt) => { let $var: $t = __get_random_value!($var); __print_value!($var: $t); }; } #[macro_export] macro_rules! dp { ($ t : block) => { macro_rules! solve { () => { $t }; } }; } pub fn yc<T, R, F: Fn(&F, T) -> R>(f: &F) -> impl Fn(T) -> R + '_ { move |x| f(f, x) } #[macro_export] macro_rules ! yc { ($ this : ident = |$ ($ arg : ident : $ ($ ty : ty) ?) ,*| $ (-> $ ret : ty) ? $ body : block) => { let $ this = $ crate :: yc (|$ this , $ ($ arg : $ ($ ty) ?) ,*| $ (-> $ ret) ? $ body) ; } ; }

use std::{io, usize};

#[allow(dead_code)]
fn gets() -> String {
    let mut s = String::new();
    io::stdin().read_line(&mut s).unwrap();
    s.trim().to_string()
}

#[allow(unused_macros)]
macro_rules! read_vec {
    ($ty:ty) => {{
        let line = gets();
        let mut it = line.split_whitespace();
        let mut v = Vec::new();
        while let Some(value) = it.next() {
            v.push(value.parse::<$ty>().unwrap());
        }
        v
    }};
}

#[allow(unused_macros)]
macro_rules! read {
    ( $ty:ty) => {
        gets().split_whitespace().next().unwrap().parse::<$ty>().unwrap()
    };
    ( $($ty:ty),* ) => {{
        let line = gets();
        let mut it = line.split_whitespace();
        ( $(it.next().unwrap().parse::<$ty>().unwrap(),)* )
    }};
    ( $( $ty:ty ),+ ,) => {
		read![ $( $ty ),* ]
    };
}
use std::collections::BTreeSet;
fn main() {
    let _ = read!(usize);
    let mut a = read_vec!(i32);
    let mut set = BTreeSet::new();
    set.insert(0);
    for x in &a {
        let mut tmp = BTreeSet::new();
        for y in set.iter() {
            tmp.insert(y + x);
        }
        for y in tmp.iter() {
            set.insert(*y);
        }
    }
    let mut sum = 0;
    for x in &a {
        sum += x;
    }
    if sum % 2 == 0 && set.contains(&(sum / 2)) {
        println!("1");
        loop {
            match a.iter().position(|a| a % 2 != 0) {
                Some(ans) => {
                    println!("{}", ans + 1);
                    break;
                }
                None => {
                    for i in 0..a.len() {
                        a[i] /= 2;
                    }
                }
            }
        }
    } else {
        println!("0");
    }
}

// codesnip-guard: main
fn main() {
    #![allow(unused_imports, unused_macros)]
    prepare_io!(_in_buf, scanner, _out);
    macro_rules ! print { ($ ($ arg : tt) *) => (:: std :: write ! (_out , $ ($ arg) *) . expect ("io error")) }
    macro_rules ! println { ($ ($ arg : tt) *) => (:: std :: writeln ! (_out , $ ($ arg) *) . expect ("io error")) }
    scan!(scanner, n, a: [usize; n]);
    let s: usize = a.iter().cloned().sum();
    if s % 2 == 0 {
        let mut dp = vec![false; 2001 * n];
        dp[0] = true;
        for a in a.iter().cloned() {
            for i in (0..dp.len().saturating_sub(a + 1)).rev() {
                dp[i + a] |= dp[i];
            }
        }
        if dp[s / 2] {
            println!("{}", 1);
            let i = (0..n).min_by_key(|&i| a[i].trailing_zeros()).unwrap();
            println!("{}", i + 1);
        } else {
            println!("{}", 0);
        }
    } else {
        println!("{}", 0);
    }
}
#[macro_export]
macro_rules! prepare_io {
    ($ in_buf : ident , $ scanner : ident , $ out : ident) => {
        use std::io::{stdout, BufWriter, Write as _};
        let $in_buf = read_stdin_all_unchecked();
        let mut $scanner = Scanner::new(&$in_buf);
        let $out = stdout();
        let mut $out = BufWriter::new($out.lock());
    };
}
// codesnip-guard: _echo
pub fn echo<T: std::fmt::Display>(
    mut writer: impl std::io::Write,
    iter: impl IntoIterator<Item = T>,
    sep: impl std::fmt::Display,
) -> std::io::Result<()> {
    let mut iter = iter.into_iter();
    if let Some(item) = iter.next() {
        write!(writer, "{}", item)?;
    }
    for item in iter {
        write!(writer, "{}{}", sep, item)?;
    }
    writeln!(writer)
}
// codesnip-guard: scanner
pub fn read_stdin_all_unchecked() -> String {
    use std::io::Read as _;
    let mut buf = Vec::new();
    std::io::stdin().read_to_end(&mut buf).expect("io error");
    unsafe { String::from_utf8_unchecked(buf) }
}
pub fn read_stdin_line() -> String {
    let mut s = String::new();
    std::io::stdin().read_line(&mut s).expect("io error");
    s
}
pub trait IterScan: Sized {
    type Output;
    fn scan<'a, I: Iterator<Item = &'a str>>(iter: &mut I) -> Option<Self::Output>;
}
pub trait MarkedIterScan: Sized {
    type Output;
    fn mscan<'a, I: Iterator<Item = &'a str>>(self, iter: &mut I) -> Option<Self::Output>;
}
#[derive(Clone, Debug)]
pub struct Scanner<'a> {
    iter: std::str::SplitAsciiWhitespace<'a>,
}
mod scanner_impls {
    use super::*;
    impl<'a> Scanner<'a> {
        #[inline]
        pub fn new(s: &'a str) -> Self {
            let iter = s.split_ascii_whitespace();
            Self { iter }
        }
        #[inline]
        pub fn scan<T: IterScan>(&mut self) -> <T as IterScan>::Output {
            <T as IterScan>::scan(&mut self.iter).expect("scan error")
        }
        #[inline]
        pub fn mscan<T: MarkedIterScan>(&mut self, marker: T) -> <T as MarkedIterScan>::Output {
            marker.mscan(&mut self.iter).expect("scan error")
        }
        #[inline]
        pub fn scan_vec<T: IterScan>(&mut self, size: usize) -> Vec<<T as IterScan>::Output> {
            (0..size)
                .map(|_| <T as IterScan>::scan(&mut self.iter).expect("scan error"))
                .collect()
        }
        #[inline]
        pub fn iter<'b, T: IterScan>(&'b mut self) -> ScannerIter<'a, 'b, T> {
            ScannerIter {
                inner: self,
                _marker: std::marker::PhantomData,
            }
        }
    }
    macro_rules ! iter_scan_impls { ($ ($ t : ty) *) => { $ (impl IterScan for $ t { type Output = Self ; # [inline] fn scan <'a , I : Iterator < Item = &'a str >> (iter : & mut I) -> Option < Self > { iter . next () ?. parse ::<$ t > () . ok () } }) * } ; }
    iter_scan_impls ! (char u8 u16 u32 u64 usize i8 i16 i32 i64 isize f32 f64 u128 i128 String);
    macro_rules ! iter_scan_tuple_impl { ($ ($ T : ident) *) => { impl <$ ($ T : IterScan) ,*> IterScan for ($ ($ T ,) *) { type Output = ($ (<$ T as IterScan >:: Output ,) *) ; # [inline] fn scan <'a , It : Iterator < Item = &'a str >> (_iter : & mut It) -> Option < Self :: Output > { Some (($ (<$ T as IterScan >:: scan (_iter) ?,) *)) } } } ; }
    iter_scan_tuple_impl!();
    iter_scan_tuple_impl!(A);
    iter_scan_tuple_impl ! (A B);
    iter_scan_tuple_impl ! (A B C);
    iter_scan_tuple_impl ! (A B C D);
    iter_scan_tuple_impl ! (A B C D E);
    iter_scan_tuple_impl ! (A B C D E F);
    iter_scan_tuple_impl ! (A B C D E F G);
    iter_scan_tuple_impl ! (A B C D E F G H);
    iter_scan_tuple_impl ! (A B C D E F G H I);
    iter_scan_tuple_impl ! (A B C D E F G H I J);
    iter_scan_tuple_impl ! (A B C D E F G H I J K);
    pub struct ScannerIter<'a, 'b, T> {
        inner: &'b mut Scanner<'a>,
        _marker: std::marker::PhantomData<fn() -> T>,
    }
    impl<'a, 'b, T: IterScan> Iterator for ScannerIter<'a, 'b, T> {
        type Item = <T as IterScan>::Output;
        #[inline]
        fn next(&mut self) -> Option<Self::Item> {
            <T as IterScan>::scan(&mut self.inner.iter)
        }
    }
}
#[derive(Debug, Copy, Clone)]
pub struct Usize1;
#[derive(Debug, Copy, Clone)]
pub struct CharWithBase(pub char);
#[derive(Debug, Copy, Clone)]
pub struct Chars;
#[derive(Debug, Copy, Clone)]
pub struct CharsWithBase(pub char);
#[derive(Debug, Copy, Clone)]
pub struct Collect<T: IterScan, B: std::iter::FromIterator<<T as IterScan>::Output>> {
    size: usize,
    _marker: std::marker::PhantomData<fn() -> (T, B)>,
}
mod marker_impls {
    use super::*;
    use std::{iter::FromIterator, marker::PhantomData};
    impl IterScan for Usize1 {
        type Output = usize;
        #[inline]
        fn scan<'a, I: Iterator<Item = &'a str>>(iter: &mut I) -> Option<Self::Output> {
            <usize as IterScan>::scan(iter)?.checked_sub(1)
        }
    }
    impl MarkedIterScan for CharWithBase {
        type Output = usize;
        #[inline]
        fn mscan<'a, I: Iterator<Item = &'a str>>(self, iter: &mut I) -> Option<Self::Output> {
            Some((<char as IterScan>::scan(iter)? as u8 - self.0 as u8) as usize)
        }
    }
    impl IterScan for Chars {
        type Output = Vec<char>;
        #[inline]
        fn scan<'a, I: Iterator<Item = &'a str>>(iter: &mut I) -> Option<Self::Output> {
            Some(iter.next()?.chars().collect())
        }
    }
    impl MarkedIterScan for CharsWithBase {
        type Output = Vec<usize>;
        #[inline]
        fn mscan<'a, I: Iterator<Item = &'a str>>(self, iter: &mut I) -> Option<Self::Output> {
            Some(
                iter.next()?
                    .chars()
                    .map(|c| (c as u8 - self.0 as u8) as usize)
                    .collect(),
            )
        }
    }
    impl<T: IterScan, B: FromIterator<<T as IterScan>::Output>> Collect<T, B> {
        pub fn new(size: usize) -> Self {
            Self {
                size,
                _marker: PhantomData,
            }
        }
    }
    impl<T: IterScan, B: FromIterator<<T as IterScan>::Output>> MarkedIterScan for Collect<T, B> {
        type Output = B;
        #[inline]
        fn mscan<'a, I: Iterator<Item = &'a str>>(self, iter: &mut I) -> Option<Self::Output> {
            Some(
                (0..self.size)
                    .map(|_| <T as IterScan>::scan(iter).expect("scan error"))
                    .collect::<B>(),
            )
        }
    }
}
#[macro_export]
macro_rules ! scan_value { ($ scanner : expr , ($ ($ t : tt) ,*)) => { ($ ($ crate :: scan_value ! ($ scanner , $ t)) ,*) } ; ($ scanner : expr , [$ t : tt ; $ len : expr]) => { (0 ..$ len) . map (| _ | $ crate :: scan_value ! ($ scanner , $ t)) . collect ::< Vec < _ >> () } ; ($ scanner : expr , [$ t : ty ; $ len : expr]) => { $ scanner . scan_vec ::<$ t > ($ len) } ; ($ scanner : expr , [$ t : ty]) => { $ scanner . iter ::<$ t > () } ; ($ scanner : expr , { $ e : expr }) => { $ scanner . mscan ($ e) } ; ($ scanner : expr , $ t : ty) => { $ scanner . scan ::<$ t > () } ; }
#[macro_export]
macro_rules ! scan { ($ scanner : expr) => { } ; ($ scanner : expr ,) => { } ; ($ scanner : expr , mut $ var : tt : $ t : tt) => { let mut $ var = $ crate :: scan_value ! ($ scanner , $ t) ; } ; ($ scanner : expr , $ var : tt : $ t : tt) => { let $ var = $ crate :: scan_value ! ($ scanner , $ t) ; } ; ($ scanner : expr , mut $ var : tt : $ t : tt , $ ($ rest : tt) *) => { let mut $ var = $ crate :: scan_value ! ($ scanner , $ t) ; scan ! ($ scanner , $ ($ rest) *) } ; ($ scanner : expr , $ var : tt : $ t : tt , $ ($ rest : tt) *) => { let $ var = $ crate :: scan_value ! ($ scanner , $ t) ; scan ! ($ scanner , $ ($ rest) *) } ; ($ scanner : expr , mut $ var : tt) => { let mut $ var = $ crate :: scan_value ! ($ scanner , usize) ; } ; ($ scanner : expr , $ var : tt) => { let $ var = $ crate :: scan_value ! ($ scanner , usize) ; } ; ($ scanner : expr , mut $ var : tt , $ ($ rest : tt) *) => { let mut $ var = $ crate :: scan_value ! ($ scanner , usize) ; scan ! ($ scanner , $ ($ rest) *) } ; ($ scanner : expr , $ var : tt , $ ($ rest : tt) *) => { let $ var = $ crate :: scan_value ! ($ scanner , usize) ; scan ! ($ scanner , $ ($ rest) *) } ; }

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

fn run() {
    input! {
        n: usize,
        a: [usize; n],
    }
    let s = a.iter().sum::<usize>();
    let mut dp = vec![0; s + 1];
    dp[0] = 1u32;
    for &a in a.iter() {
        for i in (a..=s).rev() {
            dp[i] = dp[i].saturating_add(dp[i - a]);
        }
    }
    if s % 2 == 1 || dp[s / 2] == 0 {
        println!("0");
        return;
    }
    for d in 0.. {
        let d = 2usize.pow(d);
        if let Some(x) = a.iter().position(|a| *a / d % 2 == 1) {
            println!("1\n{}", x + 1);
            return;
        }
    }
}

fn main() {
    run();
}

//spnauti-rusT {{{
#[allow(unused_imports)]use std::{io::*,collections::*,fmt::Debug,str::{self,*},cmp::Ordering,ops::{self,*},iter::{self,*}};
#[allow(unused_macros)]macro_rules!min{($x:expr,$y:expr)=>{let b=$y;let a=&mut$x;if b<*a{*a=b;true}else{false}};}
#[allow(unused_macros)]macro_rules!max{($x:expr,$y:expr)=>{let b=$y;let a=&mut$x;if b>*a{*a=b;true}else{false}};}
#[allow(unused_macros)]macro_rules!l{
	($($v:ident),+:$t:ty=$e:expr)=>{$(let$v:$t=$e;)+};(mut $($v:ident),+ =$e:expr)=>{$(let mut$v=$e;)+};
	(mut $($v:ident),+:$t:ty=$e:expr)=>{$(let mut$v:$t=$e;)+};($($v:ident),+ =$e:expr)=>{$(let$v=$e;)+};
}#[allow(unused_macros)]macro_rules!v{([$d:expr]$($s:tt)+)=>{vec![v!($($s)+);$d]};
	([])=>{Vec::new()};([$e:expr])=>{Vec::with_capacity($e)};(=$e:expr)=>{$e};
}#[allow(unused_macros)]macro_rules!rp{{[$c:expr]$($s:tt)+}=>(for _ in 0..$c{$($s)+})}
#[allow(dead_code)]fn rio()->(Reader,BufWriter<Stdout>){(Reader::new(),BufWriter::new(stdout()))}
struct Reader{buf:Vec<u8>,pos:usize,q:StdinLock<'static>}//'
#[allow(dead_code)]impl Reader{
	fn new()->Self{let r=unsafe{&*Box::into_raw(Box::new(stdin()))};Self{q:r.lock(),buf:v!([]),pos:0}}
	fn next_line(&mut self)->bool{self.buf.clear();self.pos=0;self.q.read_until(b'\n',&mut self.buf).unwrap_or(0)>0}
	fn is_ws(c:u8)->bool{c==b' '||c==b'\n'||c==b'\r'||c==b'\t'}
	fn byte(&mut self) -> Option<u8> {
		if self.pos==self.buf.len(){if!self.next_line(){return None;}}self.pos+=1;Some(self.buf[self.pos-1])
	}
	fn vb(&mut self)->Vec<u8>{
		let mut s=v!([10]);let mut f=false;while let Some(c)=self.byte()
		{if!Self::is_ws(c){s.push(c);f=true;}else if f{break;}}s
	}
	fn board(&mut self, r: usize, c: Option<usize>) -> Vec<Vec<u8>> {
		let mut res = v!([r]);
		let c = c.unwrap_or(0);
		rp!{[r]
			let t = self.vb();
			assert!(c == 0 || t.len() == c);
			res.push(t);
		}
		res
	}
	fn framed_board(&mut self, r: usize, c: usize, f: u8) -> Vec<Vec<u8>> {
		let mut res = v!([r+2]);
		res.push( v!([c+2] = f) );
		rp!{[r]
			let mut t = self.vb();
			assert!(t.len() == c);
			t.reserve(2);
			t.insert(0,f);
			t.push(f);
			res.push(t);
		}
		res.push( v!([c+2] = f) );
		res
	}
	fn s(&mut self) -> String { String::from_utf8(self.vb()).expect("invalid utf8") }
	fn i(&mut self) ->    i32 { self.p() }
	fn l(&mut self) ->    i64 { self.p() }
	fn u(&mut self) ->  usize { self.p() }
	fn f(&mut self) ->    f64 { self.p() }
	fn vi(&mut self, n: usize) -> Vec<i32> { self.vp(n) }
	fn vl(&mut self, n: usize) -> Vec<i64> { self.vp(n) }
	fn vu(&mut self, n: usize) -> Vec<usize> { self.vp(n) }
	fn ii(&mut self, n: usize) -> impl Iterator<Item=i32> { self.ip(n).into_iter() }
	fn iu(&mut self, n: usize) -> impl Iterator<Item=usize> { self.ip(n).into_iter() }
	fn p<T: FromStr>(&mut self) -> T where T::Err: Debug {
		let w = self.vb(); str::from_utf8(w.as_ref()).unwrap().parse::<T>().unwrap()
	}
	fn vp<T: FromStr>(&mut self, n: usize) -> Vec<T> where T::Err: Debug {
		(0..n).map(|_|self.p()).collect()
	}
	fn ip<T: FromStr>(&mut self, n: usize) -> impl Iterator<Item=T> where T::Err: Debug {
		self.vp(n).into_iter()
	}
	fn graph(&mut self, n: usize, m: usize) -> Vec<Vec<usize>> {
		let mut e = v!([n][]); rp!{[m] l!(a,b = self.u()-1); e[a].push(b); e[b].push(a); } e
	}
	fn graph_w<T: Copy+FromStr>(&mut self, n: usize, m: usize) -> Vec<Vec<(usize,T)>> where T::Err: Debug {
		let mut e=v!([n][]);rp!{[m]l!(a,b=self.u()-1);let c:T=self.p();e[a].push((b,c));e[b].push((a,c));}e
	}
}
//----------}}}

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

fn main() {
	let (mut rin,mut rout) = rio();

	let n = rin.u();
	let mut a = rin.vi(n);
	let mut g = 0;
	for &x in a.iter() {
		g = gcd(g, x);
	}
	for x in a.iter_mut() {
		*x /= g;
	}
	let sum: i32 = a.iter().sum();
	let mut ans = None;
	if sum % 2 == 0 {
		let s = (sum/2) as usize;
		let mut dp = v!([s+1] = false);
		dp[0] = true;
		for i in 0..n {
			let b = a[i] as usize;
			for j in (b..=s).rev() {
				dp[j] |= dp[j-b];
			}
		}
		if dp[s] {
			for i in 0..n {
				if a[i] % 2 == 1 {
					ans = Some(i+1);
					break;
				}
			}
		}
	}
	if let Some(x) = ans {
		writeln!(rout, "1\n{}", x).unwrap();
	} else {
		writeln!(rout, "0").unwrap();
	}
}

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

fn main() {
    let (stdin, stdout) = (io::stdin(), io::stdout());
    let mut sc = cf_scanner::Scanner::new(stdin.lock());
    let mut out = io::BufWriter::new(stdout.lock());

    let n: usize = sc.next();
    let mut a: Vec<usize> = sc.next_vec(n);

    let mut can_reach: Vec<bool> = vec![false; n * 2000 + 10];
    can_reach[0] = true;
    for i in 0..n {
        for j in (0..can_reach.len()).rev() {
            if j < a[i] {
                continue;
            }
            can_reach[j] |= can_reach[j - a[i]];
        }
    }

    let s: usize = a.iter().sum();

    if s % 2 == 1 || !can_reach[s / 2] {
        writeln!(out, "0").unwrap();
        return;
    }

    let mut ans: usize = 0;
    let mut to_make: usize = 31;
    for i in 0..n {
        let mut c: usize = 0;
        while a[i] % 2 == 0 {
            c += 1;
            a[i] /= 2;
        }
        if c < to_make {
            to_make = c;
            ans = i;
        }
    }
    writeln!(out, "1\n{}", ans + 1).unwrap();
}

#[allow(dead_code)]
mod cf_scanner {
    use std::io;
    use std::str::{FromStr, SplitAsciiWhitespace};

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

    impl<R: io::BufRead> Scanner<R> {
        pub fn new(reader: R) -> Scanner<R> {
            Scanner {
                reader,
                buf_str: Vec::new(),
                buf_iter: "".split_ascii_whitespace(),
            }
        }

        pub fn next<T: FromStr>(&mut self) -> T {
            loop {
                if let Some(token) = self.buf_iter.next() {
                    return token.parse().ok().expect("Failed parse");
                }
                self.buf_str.clear();
                self.reader
                    .read_until(b'\n', &mut self.buf_str)
                    .expect("Failed read");
                self.buf_iter = unsafe {
                    let slice = std::str::from_utf8_unchecked(&self.buf_str);
                    std::mem::transmute(slice.split_ascii_whitespace())
                }
            }
        }

        pub fn next_vec<T: FromStr>(&mut self, n: usize) -> Vec<T> {
            (0..n).map(|_| self.next()).collect()
        }
    }
}

#![allow(unused_imports, unused_macros)]

use kyoproio::*;
use std::{
    collections::*,
    io::{self, prelude::*},
    iter, mem,
};

fn run<I: Input, O: Write>(mut kin: I, mut out: O) {
    let t: usize = 1; // kin.parse();
    for _ in 0..t {
        case(&mut kin, &mut out);
    }
}

fn case<I: Input, O: Write>(mut kin: I, mut out: O) {
    let n: usize = kin.parse();
    let a: Vec<i32> = kin.collect(n);
    let sum: i32 = a.iter().sum();
    let mut s = vec![false; sum as usize + 1];
    s[0] = true;
    for &a in &a {
        let a = a as usize;
        for i in (0..s.len() - a).rev() {
            s[i + a] |= s[i];
        }
    }
    d!(s);
    if sum % 2 == 1 || !s[sum as usize / 2] {
        wln!(out, "0");
        return;
    }
    for k in 0.. {
        for (i, &a) in a.iter().enumerate() {
            if a & 1 << k != 0 {
                wln!(out, "1");
                wln!(out, "{}", i + 1);
                return;
            }
        }
    }
}

// -----------------------------------------------------------------------------
fn main() -> io::Result<()> {
    std::thread::Builder::new()
        .stack_size(1 << 26)
        .spawn(|| {
            run(
                Scanner::new(io::stdin().lock()),
                io::BufWriter::new(io::stdout().lock()),
            )
        })?
        .join()
        .unwrap();
    Ok(())
}

#[macro_export]
macro_rules! w {
    ($($arg:tt)*) => { write!($($arg)*).unwrap(); }
}
#[macro_export]
macro_rules! wln {
    ($dst:expr $(, $($arg:tt)*)?) => {{
        writeln!($dst $(, $($arg)*)?).unwrap();
        #[cfg(debug_assertions)]
        $dst.flush().unwrap();
    }}
}
#[macro_export]
macro_rules! w_iter {
    ($dst:expr, $fmt:expr, $iter:expr, $delim:expr) => {{
        let mut first = true;
        for elem in $iter {
            if first {
                w!($dst, $fmt, elem);
                first = false;
            } else {
                w!($dst, concat!($delim, $fmt), elem);
            }
        }
    }};
    ($dst:expr, $fmt:expr, $iter:expr) => {
        w_iter!($dst, $fmt, $iter, " ")
    };
}
#[macro_export]
macro_rules! w_iter_ln {
    ($dst:expr, $($t:tt)*) => {{
        w_iter!($dst, $($t)*);
        wln!($dst);
    }}
}
#[macro_export]
macro_rules! e {
    ($($t:tt)*) => {
        #[cfg(debug_assertions)]
        eprint!($($t)*)
    }
}
#[macro_export]
macro_rules! eln {
    ($($t:tt)*) => {
        #[cfg(debug_assertions)]
        eprintln!($($t)*)
    }
}
#[macro_export]
macro_rules! __tstr {
    ($h:expr $(, $t:expr)+) => { concat!(__tstr!($($t),+), ", ", __tstr!(@)) };
    ($h:expr) => { concat!(__tstr!(), " ",  __tstr!(@)) };
    () => { "\x1B[94m[{}:{}]\x1B[0m" };
    (@) => { "\x1B[1;92m{}\x1B[0m = {:?}" }
}
#[macro_export]
macro_rules! d {
    ($($a:expr),*) => { eln!(__tstr!($($a),*), file!(), line!(), $(stringify!($a), $a),*) };
}

pub mod kyoproio {
    use std::{
        fmt::Display,
        io::{self, prelude::*},
        iter::FromIterator,
        marker::PhantomData,
        mem::{self, MaybeUninit},
        str,
    };

    pub trait Input {
        fn bytes(&mut self) -> &[u8];
        fn str(&mut self) -> &str {
            str::from_utf8(self.bytes()).unwrap()
        }
        fn parse<T: Parse>(&mut self) -> T {
            T::parse(self)
        }
        fn parse_iter<T: Parse>(&mut self) -> ParseIter<T, Self> {
            ParseIter(self, PhantomData)
        }
        fn collect<T: Parse, B: FromIterator<T>>(&mut self, n: usize) -> B {
            self.parse_iter().take(n).collect()
        }
        fn map<T: Parse, U, F: FnMut(T) -> U, B: FromIterator<U>>(&mut self, n: usize, f: F) -> B {
            self.parse_iter().take(n).map(f).collect()
        }
    }
    impl<I: Input> Input for &mut I {
        fn bytes(&mut self) -> &[u8] {
            (**self).bytes()
        }
    }
    pub struct Scanner<R> {
        src: R,
        buf: Vec<u8>,
        pos: usize,
        len: usize,
    }
    impl<R: Read> Scanner<R> {
        pub fn new(src: R) -> Self {
            Self {
                src,
                buf: vec![0; 1 << 16],
                pos: 0,
                len: 0,
            }
        }
        fn read(&mut self) -> usize {
            if self.pos > 0 {
                self.buf.copy_within(self.pos..self.len, 0);
                self.len -= self.pos;
                self.pos = 0;
            } else if self.len >= self.buf.len() {
                self.buf.resize(2 * self.buf.len(), 0);
            }
            let n = self.src.read(&mut self.buf[self.len..]).unwrap();
            self.len += n;
            assert!(self.len <= self.buf.len());
            n
        }
    }
    impl<R: Read> Input for Scanner<R> {
        fn bytes(&mut self) -> &[u8] {
            loop {
                while let Some(d) = unsafe { self.buf.get_unchecked(self.pos..self.len) }
                    .iter()
                    .position(u8::is_ascii_whitespace)
                {
                    let p = self.pos;
                    self.pos += d + 1;
                    if d > 0 {
                        return unsafe { self.buf.get_unchecked(p..p + d) };
                    }
                }
                if self.read() == 0 {
                    let p = self.pos;
                    self.pos = self.len;
                    return unsafe { self.buf.get_unchecked(p..self.len) };
                }
            }
        }
    }
    pub struct ParseIter<'a, T, I: ?Sized>(&'a mut I, PhantomData<*const T>);
    impl<'a, T: Parse, I: Input + ?Sized> Iterator for ParseIter<'a, T, I> {
        type Item = T;
        fn next(&mut self) -> Option<T> {
            Some(self.0.parse())
        }
        fn size_hint(&self) -> (usize, Option<usize>) {
            (!0, None)
        }
    }
    pub trait Parse: Sized {
        fn parse<I: Input + ?Sized>(src: &mut I) -> Self;
    }
    macro_rules! from_bytes {
        ($($T:ty)*) => {$(
            impl Parse for $T {
                fn parse<I: Input + ?Sized>(src: &mut I) -> Self {
                    src.bytes().into()
                }
            }
        )*}
    }
    from_bytes!(Vec<u8> Box<[u8]>);
    macro_rules! from_str {
        ($($T:ty)*) => {$(
            impl Parse for $T {
                fn parse<I: Input + ?Sized>(src: &mut I) -> Self {
                    src.str().parse::<$T>().unwrap()
                }
            }
        )*}
    }
    from_str!(String char bool f32 f64);
    macro_rules! int {
        ($($I:ty: $U:ty)*) => {$(
            impl Parse for $I {
                fn parse<I: Input + ?Sized>(src: &mut I) -> Self {
                    let f = |s: &[u8]| s.iter().fold(0, |x, b| 10 * x + (b & 0xf) as $I);
                    let s = src.bytes();
                    if let Some((&b'-', t)) = s.split_first() { -f(t) } else { f(s) }
                }
            }
            impl Parse for $U {
                fn parse<I: Input + ?Sized>(src: &mut I) -> Self {
                    src.bytes().iter().fold(0, |x, b| 10 * x + (b & 0xf) as $U)
                }
            }
        )*}
    }
    int!(isize:usize i8:u8 i16:u16 i32:u32 i64:u64 i128:u128);
    macro_rules! tuple {
        ($H:ident $($T:ident)*) => {
            impl<$H: Parse, $($T: Parse),*> Parse for ($H, $($T),*) {
                fn parse<I: Input + ?Sized>(src: &mut I) -> Self {
                    ($H::parse(src), $($T::parse(src)),*)
                }
            }
            tuple!($($T)*);
        };
        () => {}
    }
    tuple!(A B C D E F G);
    macro_rules! array {
        ($($N:literal)*) => {$(
            impl<T: Parse> Parse for [T; $N] {
                fn parse<I: Input + ?Sized>(src: &mut I) -> Self {
                    unsafe {
                        let mut arr: [MaybeUninit<T>; $N] = MaybeUninit::uninit().assume_init();
                        for elem in &mut arr {
                            *elem = MaybeUninit::new(src.parse());
                        }
                        mem::transmute_copy(&arr)
                    }
                }
            }
        )*}
    }
    array!(1 2 3 4 5 6 7 8);
}

#![allow(unused_imports)]
use std::cmp::*;
use std::collections::*;
use std::io::Write;
use std::ops::Bound::*;

#[allow(unused_macros)]
macro_rules! debug {
    ($($e:expr),*) => {
        #[cfg(debug_assertions)]
        $({
            let (e, mut err) = (stringify!($e), std::io::stderr());
            writeln!(err, "{} = {:?}", e, $e).unwrap()
        })*
    };
}

fn main() {
    let n = read::<usize>();
    let mut a = read_vec::<usize>();
    while a.iter().all(|&x| x % 2 == 0) {
        a = a.iter().map(|&x| x / 2).collect::<Vec<_>>();
    }

    if a.iter().sum::<usize>() % 2 == 1 {
        println!("0");
        return;
    }
    let mut dp = vec![false; 2000 * n + 1];
    dp[0] = true;
    for i in 0..n {
        for next in (a[i]..dp.len()).rev() {
            dp[next] |= dp[next - a[i]];
        }
    }
    // debug!(dp);
    if !dp[a.iter().sum::<usize>() / 2] {
        println!("0");
        return;
    }
    println!("1");
    for i in 0..n {
        if a[i] % 2 == 1 {
            println!("{}", i + 1);
            return;
        }
    }
}

fn read<T: std::str::FromStr>() -> T {
    let mut s = String::new();
    std::io::stdin().read_line(&mut s).ok();
    s.trim().parse().ok().unwrap()
}

fn read_vec<T: std::str::FromStr>() -> Vec<T> {
    read::<String>()
        .split_whitespace()
        .map(|e| e.parse().ok().unwrap())
        .collect()
}

use crate::lib::stdio::*;
use crate::lib::ds::idx::*;

fn main() {
    prtln!(new cout);
    scan!(new cin, n: usize, a: [isize; n]);
    let ofs: isize = 101 * 2000;
    let mut dp = IdxInt(vec![false; ofs as usize * 2]);
    dp[ofs] = true;
    for i in 0..n {
        let mut dp2 = IdxInt(vec![false; ofs as usize * 2]);
        for s in 0..ofs * 2 {
            if s >= a[i] {
                dp2[s - a[i]] |= dp[s];
            }
            if s + a[i] < ofs * 2 {
                dp2[s + a[i]] |= dp[s];
            }
        }
        dp = dp2;
    }
    if !dp[ofs] {
        return prtln!(to cout, 0);
    }
    prtln!(to cout, 1);
    for d in 0.. {
        if let Some(i) = (0..n).filter(|&i| a[i] >> d & 1 != 0).next() {
            return prtln!(to cout, i + 1);
        }
    }
}

pub mod lib {

pub mod ds {

pub mod idx {

use std::ops::{Deref, DerefMut, Index, IndexMut};

#[derive(Debug, Clone)]
pub struct IdxInt<T>(pub Vec<T>);

impl<T> Deref for IdxInt<T> {
    type Target = Vec<T>;
    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

impl<T> DerefMut for IdxInt<T> {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.0
    }
}

macro_rules! impl_index {
    ($($idx:ty),*) => { $(
        impl<T> Index<$idx> for IdxInt<T> {
            type Output = T;
            fn index(&self, index: $idx) -> &Self::Output {
                self.0.index(index as usize)
            }
        }
        impl<T> IndexMut<$idx> for IdxInt<T> {
            fn index_mut(&mut self, index: $idx) -> &mut Self::Output {
                self.0.index_mut(index as usize)
            }
        }
    )* }
}

impl_index!(i32, i64, i128, isize, u32, u64, u128, usize);

}  // mod idx

}  // mod ds

pub mod stdio {

pub use crate::prtln;
pub use crate::scan;
pub use  std::io::Write;
use std::io::{stdout, BufWriter, StdoutLock};

pub fn stdout_buf() -> BufWriter<StdoutLock<'static>> {
    let out = Box::leak(Box::new(stdout()));
    BufWriter::new(out.lock())
}

#[macro_export]
macro_rules! prtln {
    (@ $dst:expr, iter=$v:expr) => { $crate::prtln!(@ $dst, iter=$v, sep=" "); };
    (@ $dst:expr, iter=$v:expr, sep=$sep:expr) => { {
        let mut iter = $v.into_iter();
        if let Some(expr) = iter.next() {
            std::write!($dst, "{}", expr).unwrap();
            for v in iter { std::write!($dst, "{}{}", $sep, v).unwrap(); }
        }
        $crate::prtln!(@ $dst, "");
    } };
    (@ $dst:expr, bytes=$v:expr) => {
        $crate::prtln!(@ $dst, std::str::from_utf8(&$v).unwrap());
    };
    (@ $dst:expr, YesNo=$v:expr) => { $crate::prtln!(@ $dst, if $v { "Yes" } else { "No" }); };
    (@ $dst:expr, YESNO=$v:expr) => { $crate::prtln!(@ $dst, if $v { "YES" } else { "NO" }); };
    (@ $dst:expr, $v:expr, no eol) => { std::write!($dst, "{}", $v).unwrap(); };
    (@ $dst:expr, $v:expr) => { std::writeln!($dst, "{}", $v).unwrap(); };
    (@ $dst:expr, $v:expr, $($t:tt)*) => { {
        std::write!($dst, "{} ", $v).unwrap();
        $crate::prtln!(@ $dst, $($t)*);
    } };
    (new $var:ident $(,)?) => { let mut $var = stdout_buf(); };
    (new $var:ident, $($t:tt)*) => {
        $crate::prtln!(new $var);
        $crate::prtln!(to $var, $($t)*);
    };
    (to $var:ident, $($t:tt)*) => { {
        $crate::prtln!(@ $var, $($t)*);
    } };
    ($($t:tt)*) => { {
        $crate::prtln!(new __prtln, $($t)*);
        std::mem::drop(__prtln);
    } };
}

#[macro_export]
macro_rules! scan {
    (@ $iter:expr $(,)?) => {};
    (@ $iter:expr, mut $var:ident : $t:tt $($r:tt)*) => {
        #[allow(non_snake_case)]
        let mut $var = $crate::scan_value!($iter.into_iter(), $t);
        $crate::scan!(@ $iter $($r)*)
    };
    (@ $iter:expr, $var:ident : $t:tt $($r:tt)*) => {
        #[allow(non_snake_case)]
        let $var = $crate::scan_value!($iter.into_iter(), $t);
        $crate::scan!(@ $iter $($r)*)
    };
    (@ $iter:expr, $pat:pat in $t:tt $($r:tt)*) => {
        let $pat = $crate::scan_value!($iter.into_iter(), $t);
        $crate::scan!(@ $iter $($r)*)
    };
    (from $s:expr, $($r:tt)*) => { $crate::scan!(@ $s, $($r)*); };
    (new $var:ident, $($r:tt)*) => {
        let mut __input = String::new();
        std::io::Read::read_to_string(&mut std::io::stdin(), &mut __input).unwrap();
        let $var = &mut __input.split_ascii_whitespace();
        $crate::scan!(@ $var, $($r)*);
    };
    ($($r:tt)*) => { $crate::scan!(new __scan, $($r)*); };
}

#[macro_export]
macro_rules! scan_value {
    ($iter:expr, ( $($t:tt),* )) => { ( $($crate::scan_value!($iter, $t)),* ) };
    ($iter:expr, [ $t:tt ; $len:expr ]) => {
        (0..$len).map(|_| $crate::scan_value!($iter, $t)).collect::<Vec<_>>()
    };
    ($iter:expr, bytes) => { $iter.next().unwrap().as_bytes() };
    ($iter:expr, [u8]) => { $iter.next().unwrap().as_bytes().to_vec() };
    ($iter:expr, [char]) => { $iter.next().unwrap().chars().collect::<Vec<_>>() };
    ($iter:expr, usize1) => { $crate::scan_value!($iter, usize) - 1 };
    (@graph $iter:expr, $n:expr, $m:expr) => { {
        let mut graph = vec![Vec::new(); $n];
        for _ in 0..$m {
            let (a, b) = $crate::scan_value!($iter, (usize1, usize1));
            graph[a].push(b);
            graph[b].push(a);
        }
        graph
    } };
    ($iter:expr, graph) => { {
        let (n, m) = $crate::scan_value!($iter, (usize, usize));
        $crate::scan_value!(@graph $iter, n, m)
    } };
    ($iter:expr, tree) => { {
        let n = $crate::scan_value!($iter, usize);
        $crate::scan_value!(@graph $iter, n, n - 1)
    } };
    ($iter:expr, $t:ty) => { $iter.next().unwrap().parse::<$t>().unwrap() };
}

}  // mod stdio

}  // mod lib

use std::{io, usize};

#[allow(dead_code)]
fn gets() -> String {
    let mut s = String::new();
    io::stdin().read_line(&mut s).unwrap();
    s.trim().to_string()
}

#[allow(unused_macros)]
macro_rules! read_vec {
    ($ty:ty) => {{
        let line = gets();
        let mut it = line.split_whitespace();
        let mut v = Vec::new();
        while let Some(value) = it.next() {
            v.push(value.parse::<$ty>().unwrap());
        }
        v
    }};
}

#[allow(unused_macros)]
macro_rules! read {
    ( $ty:ty) => {
        gets().split_whitespace().next().unwrap().parse::<$ty>().unwrap()
    };
    ( $($ty:ty),* ) => {{
        let line = gets();
        let mut it = line.split_whitespace();
        ( $(it.next().unwrap().parse::<$ty>().unwrap(),)* )
    }};
    ( $( $ty:ty ),+ ,) => {
		read![ $( $ty ),* ]
    };
}
use std::collections::BTreeSet;
fn main() {
    let _ = read!(usize);
    let a = read_vec!(i32);
    let mut set = BTreeSet::new();
    set.insert(0);
    for x in &a {
        let mut tmp = BTreeSet::new();
        for y in set.iter() {
            tmp.insert(y + x);
        }
        for y in tmp.iter() {
            set.insert(*y);
        }
    }
    let mut sum = 0;
    for x in &a {
        sum += x;
    }
    if sum % 2 == 0 && set.contains(&(sum / 2)) {
        println!("1");
        let mut ans = a[0];
        let mut ansidx = 0;
        for i in 0..a.len() {
            if ans > a[i] {
                ans = a[i];
                ansidx = i;
            }
        }
        println!("{}", ansidx + 1);
    } else {
        println!("0");
    }
}

use std::{io, usize};

#[allow(dead_code)]
fn gets() -> String {
    let mut s = String::new();
    io::stdin().read_line(&mut s).unwrap();
    s.trim().to_string()
}

#[allow(unused_macros)]
macro_rules! read_vec {
    ($ty:ty) => {{
        let line = gets();
        let mut it = line.split_whitespace();
        let mut v = Vec::new();
        while let Some(value) = it.next() {
            v.push(value.parse::<$ty>().unwrap());
        }
        v
    }};
}

#[allow(unused_macros)]
macro_rules! read {
    ( $ty:ty) => {
        gets().split_whitespace().next().unwrap().parse::<$ty>().unwrap()
    };
    ( $($ty:ty),* ) => {{
        let line = gets();
        let mut it = line.split_whitespace();
        ( $(it.next().unwrap().parse::<$ty>().unwrap(),)* )
    }};
    ( $( $ty:ty ),+ ,) => {
		read![ $( $ty ),* ]
    };
}
use std::collections::BTreeSet;
fn main() {
    let _ = read!(usize);
    let a = read_vec!(i32);
    let mut set = BTreeSet::new();
    set.insert(0);
    for x in &a {
        let mut tmp = BTreeSet::new();
        for y in set.iter() {
            tmp.insert(y + x);
        }
        for y in tmp.iter() {
            set.insert(*y);
        }
    }
    let mut sum = 0;
    for x in &a {
        sum += x;
    }
    if sum % 2 == 0 && set.contains(&(sum / 2)) {
        println!("1");
        let mut ans = a[0];
        let mut ansidx = 0;
        for i in 0..a.len(){
            if ans > a[i] {
                ans = a[i];
                ansidx = i;
            }
        }
        println!("{}", ansidx);
    } else {
        println!("0");
    }
}

use std::{io, usize};

#[allow(dead_code)]
fn gets() -> String {
    let mut s = String::new();
    io::stdin().read_line(&mut s).unwrap();
    s.trim().to_string()
}

#[allow(unused_macros)]
macro_rules! read_vec {
    ($ty:ty) => {{
        let line = gets();
        let mut it = line.split_whitespace();
        let mut v = Vec::new();
        while let Some(value) = it.next() {
            v.push(value.parse::<$ty>().unwrap());
        }
        v
    }};
}

#[allow(unused_macros)]
macro_rules! read {
    ( $ty:ty) => {
        gets().split_whitespace().next().unwrap().parse::<$ty>().unwrap()
    };
    ( $($ty:ty),* ) => {{
        let line = gets();
        let mut it = line.split_whitespace();
        ( $(it.next().unwrap().parse::<$ty>().unwrap(),)* )
    }};
    ( $( $ty:ty ),+ ,) => {
		read![ $( $ty ),* ]
    };
}
use std::collections::BTreeSet;
fn main() {
    let _ = read!(usize);
    let a = read_vec!(i32);
    let mut set = BTreeSet::new();
    set.insert(0);
    for x in &a {
        let mut tmp = BTreeSet::new();
        for y in set.iter() {
            tmp.insert(y + x);
        }
        for y in tmp.iter() {
            set.insert(*y);
        }
    }
    let mut sum = 0;
    for x in a {
        sum += x;
    }
    if sum % 2 == 0 && set.contains(&(sum / 2)) {
        println!("1\n1");
    } else {
        println!("0");
    }
}

fn main() {
    use std::io::Read;
    let mut buf = String::new();
    std::io::stdin().read_to_string(&mut buf).unwrap();
    let mut itr = buf.split_whitespace();

    use std::io::Write;
    let out = std::io::stdout();
    let mut out = std::io::BufWriter::new(out.lock());

    macro_rules! print {
        ($($T:expr),*) => {
            write!(out, $($T),*).unwrap()
        };
    }

    macro_rules! scan {
        (bytes) => {
            scan!(String).bytes().collect::<Vec<_>>()
        };
        (chars) => {
            scan!(String).chars().collect::<Vec<_>>()
        };
        ([$T:tt; $n:expr]) => {
            (0..$n).map(|_| scan!($T)).collect::<Vec<_>>()
        };
        (($($T:tt),*)) => {
            ($(scan!($T)),*)
        };
        ($T:ty) => {
            itr.next().unwrap().parse::<$T>().unwrap()
        };
        ($($T:tt),*) => {
            ($(scan!($T)),*)
        };
    }

    let t: usize = 1; //scan!(usize);
    for _ in 1..=t {
        let n = scan!(usize);
        let mut a = vec![0; n + 1];

        let mut sum = 0;
        for i in 1..=n {
            a[i] = scan!(usize);
            sum += a[i];
        }

        if sum % 2 != 0 {
            print!("0");
        } else {
            let mut dp = vec![vec![false; sum + 1]; n + 1];
            dp[0][0] = true;

            for i in 1..=n {
                for s in 0..=sum {
                    if a[i] + s <= sum {
                        dp[i][s + a[i]] |= dp[i - 1][s];
                    }
                    dp[i][s] |= dp[i - 1][s];
                }
            }

            if dp[n][sum / 2] {
                print!("1\n");
                let mut min_idx = 0;
                let mut min_cnt = 31;
                for i in 1..=n {
                    let mut cnt = 0;
                    let mut a = a[i];
                    while a > 1 {
                        cnt += 1;
                        a /= 2;
                    }
                    if min_cnt > cnt {
                        min_cnt = cnt;
                        min_idx = i;
                    }
                }

                print!("{}", min_idx);
            } else {
                print!("0");
            }
        }
        print!("\n");
    }
}

// codesnip-guard: main
fn main() {
    #![allow(unused_imports, unused_macros)]
    prepare_io!(_in_buf, scanner, _out);
    macro_rules ! print { ($ ($ arg : tt) *) => (:: std :: write ! (_out , $ ($ arg) *) . expect ("io error")) }
    macro_rules ! println { ($ ($ arg : tt) *) => (:: std :: writeln ! (_out , $ ($ arg) *) . expect ("io error")) }
    scan!(scanner, n, a: [u64; n]);
    let s: u64 = a.iter().cloned().sum();
    if s % 2 == 0 {
        println!("{}", 1);
        let i = (0..n).min_by_key(|&i| a[i].trailing_zeros()).unwrap();
        println!("{}", i + 1);
    } else {
        println!("{}", 0);
    }
}
#[macro_export]
macro_rules! prepare_io {
    ($ in_buf : ident , $ scanner : ident , $ out : ident) => {
        use std::io::{stdout, BufWriter, Write as _};
        let $in_buf = read_stdin_all_unchecked();
        let mut $scanner = Scanner::new(&$in_buf);
        let $out = stdout();
        let mut $out = BufWriter::new($out.lock());
    };
}
// codesnip-guard: _echo
pub fn echo<T: std::fmt::Display>(
    mut writer: impl std::io::Write,
    iter: impl IntoIterator<Item = T>,
    sep: impl std::fmt::Display,
) -> std::io::Result<()> {
    let mut iter = iter.into_iter();
    if let Some(item) = iter.next() {
        write!(writer, "{}", item)?;
    }
    for item in iter {
        write!(writer, "{}{}", sep, item)?;
    }
    writeln!(writer)
}
// codesnip-guard: scanner
pub fn read_stdin_all_unchecked() -> String {
    use std::io::Read as _;
    let mut buf = Vec::new();
    std::io::stdin().read_to_end(&mut buf).expect("io error");
    unsafe { String::from_utf8_unchecked(buf) }
}
pub fn read_stdin_line() -> String {
    let mut s = String::new();
    std::io::stdin().read_line(&mut s).expect("io error");
    s
}
pub trait IterScan: Sized {
    type Output;
    fn scan<'a, I: Iterator<Item = &'a str>>(iter: &mut I) -> Option<Self::Output>;
}
pub trait MarkedIterScan: Sized {
    type Output;
    fn mscan<'a, I: Iterator<Item = &'a str>>(self, iter: &mut I) -> Option<Self::Output>;
}
#[derive(Clone, Debug)]
pub struct Scanner<'a> {
    iter: std::str::SplitAsciiWhitespace<'a>,
}
mod scanner_impls {
    use super::*;
    impl<'a> Scanner<'a> {
        #[inline]
        pub fn new(s: &'a str) -> Self {
            let iter = s.split_ascii_whitespace();
            Self { iter }
        }
        #[inline]
        pub fn scan<T: IterScan>(&mut self) -> <T as IterScan>::Output {
            <T as IterScan>::scan(&mut self.iter).expect("scan error")
        }
        #[inline]
        pub fn mscan<T: MarkedIterScan>(&mut self, marker: T) -> <T as MarkedIterScan>::Output {
            marker.mscan(&mut self.iter).expect("scan error")
        }
        #[inline]
        pub fn scan_vec<T: IterScan>(&mut self, size: usize) -> Vec<<T as IterScan>::Output> {
            (0..size)
                .map(|_| <T as IterScan>::scan(&mut self.iter).expect("scan error"))
                .collect()
        }
        #[inline]
        pub fn iter<'b, T: IterScan>(&'b mut self) -> ScannerIter<'a, 'b, T> {
            ScannerIter {
                inner: self,
                _marker: std::marker::PhantomData,
            }
        }
    }
    macro_rules ! iter_scan_impls { ($ ($ t : ty) *) => { $ (impl IterScan for $ t { type Output = Self ; # [inline] fn scan <'a , I : Iterator < Item = &'a str >> (iter : & mut I) -> Option < Self > { iter . next () ?. parse ::<$ t > () . ok () } }) * } ; }
    iter_scan_impls ! (char u8 u16 u32 u64 usize i8 i16 i32 i64 isize f32 f64 u128 i128 String);
    macro_rules ! iter_scan_tuple_impl { ($ ($ T : ident) *) => { impl <$ ($ T : IterScan) ,*> IterScan for ($ ($ T ,) *) { type Output = ($ (<$ T as IterScan >:: Output ,) *) ; # [inline] fn scan <'a , It : Iterator < Item = &'a str >> (_iter : & mut It) -> Option < Self :: Output > { Some (($ (<$ T as IterScan >:: scan (_iter) ?,) *)) } } } ; }
    iter_scan_tuple_impl!();
    iter_scan_tuple_impl!(A);
    iter_scan_tuple_impl ! (A B);
    iter_scan_tuple_impl ! (A B C);
    iter_scan_tuple_impl ! (A B C D);
    iter_scan_tuple_impl ! (A B C D E);
    iter_scan_tuple_impl ! (A B C D E F);
    iter_scan_tuple_impl ! (A B C D E F G);
    iter_scan_tuple_impl ! (A B C D E F G H);
    iter_scan_tuple_impl ! (A B C D E F G H I);
    iter_scan_tuple_impl ! (A B C D E F G H I J);
    iter_scan_tuple_impl ! (A B C D E F G H I J K);
    pub struct ScannerIter<'a, 'b, T> {
        inner: &'b mut Scanner<'a>,
        _marker: std::marker::PhantomData<fn() -> T>,
    }
    impl<'a, 'b, T: IterScan> Iterator for ScannerIter<'a, 'b, T> {
        type Item = <T as IterScan>::Output;
        #[inline]
        fn next(&mut self) -> Option<Self::Item> {
            <T as IterScan>::scan(&mut self.inner.iter)
        }
    }
}
#[derive(Debug, Copy, Clone)]
pub struct Usize1;
#[derive(Debug, Copy, Clone)]
pub struct CharWithBase(pub char);
#[derive(Debug, Copy, Clone)]
pub struct Chars;
#[derive(Debug, Copy, Clone)]
pub struct CharsWithBase(pub char);
#[derive(Debug, Copy, Clone)]
pub struct Collect<T: IterScan, B: std::iter::FromIterator<<T as IterScan>::Output>> {
    size: usize,
    _marker: std::marker::PhantomData<fn() -> (T, B)>,
}
mod marker_impls {
    use super::*;
    use std::{iter::FromIterator, marker::PhantomData};
    impl IterScan for Usize1 {
        type Output = usize;
        #[inline]
        fn scan<'a, I: Iterator<Item = &'a str>>(iter: &mut I) -> Option<Self::Output> {
            <usize as IterScan>::scan(iter)?.checked_sub(1)
        }
    }
    impl MarkedIterScan for CharWithBase {
        type Output = usize;
        #[inline]
        fn mscan<'a, I: Iterator<Item = &'a str>>(self, iter: &mut I) -> Option<Self::Output> {
            Some((<char as IterScan>::scan(iter)? as u8 - self.0 as u8) as usize)
        }
    }
    impl IterScan for Chars {
        type Output = Vec<char>;
        #[inline]
        fn scan<'a, I: Iterator<Item = &'a str>>(iter: &mut I) -> Option<Self::Output> {
            Some(iter.next()?.chars().collect())
        }
    }
    impl MarkedIterScan for CharsWithBase {
        type Output = Vec<usize>;
        #[inline]
        fn mscan<'a, I: Iterator<Item = &'a str>>(self, iter: &mut I) -> Option<Self::Output> {
            Some(
                iter.next()?
                    .chars()
                    .map(|c| (c as u8 - self.0 as u8) as usize)
                    .collect(),
            )
        }
    }
    impl<T: IterScan, B: FromIterator<<T as IterScan>::Output>> Collect<T, B> {
        pub fn new(size: usize) -> Self {
            Self {
                size,
                _marker: PhantomData,
            }
        }
    }
    impl<T: IterScan, B: FromIterator<<T as IterScan>::Output>> MarkedIterScan for Collect<T, B> {
        type Output = B;
        #[inline]
        fn mscan<'a, I: Iterator<Item = &'a str>>(self, iter: &mut I) -> Option<Self::Output> {
            Some(
                (0..self.size)
                    .map(|_| <T as IterScan>::scan(iter).expect("scan error"))
                    .collect::<B>(),
            )
        }
    }
}
#[macro_export]
macro_rules ! scan_value { ($ scanner : expr , ($ ($ t : tt) ,*)) => { ($ ($ crate :: scan_value ! ($ scanner , $ t)) ,*) } ; ($ scanner : expr , [$ t : tt ; $ len : expr]) => { (0 ..$ len) . map (| _ | $ crate :: scan_value ! ($ scanner , $ t)) . collect ::< Vec < _ >> () } ; ($ scanner : expr , [$ t : ty ; $ len : expr]) => { $ scanner . scan_vec ::<$ t > ($ len) } ; ($ scanner : expr , [$ t : ty]) => { $ scanner . iter ::<$ t > () } ; ($ scanner : expr , { $ e : expr }) => { $ scanner . mscan ($ e) } ; ($ scanner : expr , $ t : ty) => { $ scanner . scan ::<$ t > () } ; }
#[macro_export]
macro_rules ! scan { ($ scanner : expr) => { } ; ($ scanner : expr ,) => { } ; ($ scanner : expr , mut $ var : tt : $ t : tt) => { let mut $ var = $ crate :: scan_value ! ($ scanner , $ t) ; } ; ($ scanner : expr , $ var : tt : $ t : tt) => { let $ var = $ crate :: scan_value ! ($ scanner , $ t) ; } ; ($ scanner : expr , mut $ var : tt : $ t : tt , $ ($ rest : tt) *) => { let mut $ var = $ crate :: scan_value ! ($ scanner , $ t) ; scan ! ($ scanner , $ ($ rest) *) } ; ($ scanner : expr , $ var : tt : $ t : tt , $ ($ rest : tt) *) => { let $ var = $ crate :: scan_value ! ($ scanner , $ t) ; scan ! ($ scanner , $ ($ rest) *) } ; ($ scanner : expr , mut $ var : tt) => { let mut $ var = $ crate :: scan_value ! ($ scanner , usize) ; } ; ($ scanner : expr , $ var : tt) => { let $ var = $ crate :: scan_value ! ($ scanner , usize) ; } ; ($ scanner : expr , mut $ var : tt , $ ($ rest : tt) *) => { let mut $ var = $ crate :: scan_value ! ($ scanner , usize) ; scan ! ($ scanner , $ ($ rest) *) } ; ($ scanner : expr , $ var : tt , $ ($ rest : tt) *) => { let $ var = $ crate :: scan_value ! ($ scanner , usize) ; scan ! ($ scanner , $ ($ rest) *) } ; }

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

fn run() {
    input! {
        n: usize,
        a: [u32; n],
    }
    let s = a.iter().sum::<u32>();
    if s % 2 == 1 {
        println!("0");
        return;
    }
    for d in 0.. {
        let d = 2u32.pow(d);
        if let Some(x) = a.iter().position(|a| *a / d % 2 == 1) {
            println!("1\n{}", x + 1);
            return;
        }
    }
}

fn main() {
    run();
}