Baby Ehab was toying around with arrays. He has an array $$$a$$$ of length $$$n$$$. He defines an array to be good if there's no way to partition it into $$$2$$$ subsequences such that the sum of the elements in the first is equal to the sum of the elements in the second. Now he wants to remove the minimum number of elements in $$$a$$$ so that it becomes a good array. Can you help him?A sequence $$$b$$$ is a subsequence of an array $$$a$$$ if $$$b$$$ can be obtained from $$$a$$$ by deleting some (possibly zero or all) elements. A partitioning of an array is a way to divide it into $$$2$$$ subsequences such that every element belongs to exactly one subsequence, so you must use all the elements, and you can't share any elements.

The first line contains an integer $$$n$$$ ($$$2 \le n \le 100$$$) — the length of the array $$$a$$$. The second line contains $$$n$$$ integers $$$a_1$$$, $$$a_2$$$, $$$\ldots$$$, $$$a_{n}$$$ ($$$1 \le a_i \le 2000$$$) — the elements of the array $$$a$$$.

The first line should contain the minimum number of elements you need to remove. The second line should contain the indices of the elements you're removing, separated by spaces. We can show that an answer always exists. If there are multiple solutions, you can print any.

NoteIn the first example, you can partition the array into $$$[6,9]$$$ and $$$[3,12]$$$, so you must remove at least $$$1$$$ element. Removing $$$3$$$ is sufficient.In the second example, the array is already good, so you don't need to remove any elements.

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

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

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