use itertools::Itertools; use proconio::input; fn main() { input! { n: usize } let ask = |a: &[usize], b: &[usize]| { assert!(!a.is_empty() && !b.is_empty()); println!( "? {} {} {} {}", a.len(), b.len(), a.iter().map(|&i| i + 1).join(" "), b.iter().map(|&i| i + 1).join(" "), ); input! { r: i8 } assert_ne!(r, -1); r == 1 }; let mut edges = vec![]; let a = (0..n).collect_vec(); let mut stack = vec![]; for i in 0..n - 1 { let rest = &a[i + 1..]; stack.push(rest); while let Some(vs) = stack.pop() { assert!(!vs.is_empty()); if !ask(&[i], vs) { continue; } if vs.len() == 1 { edges.push((i, vs[0])); } else { let (first, second) = vs.split_at(vs.len() / 2); stack.push(first); stack.push(second); } } } println!("! {}", edges.len()); for &(u, v) in &edges { println!("{} {}", u + 1, v + 1); } }