use std::hash::Hash;
use std::collections::hash_set::Iter;
use std::rc::Rc;
use std::ops::DivAssign;
use std::ops::MulAssign;
use std::ops::SubAssign;
use std::collections::BinaryHeap;
use std::str::FromStr;
use std::collections::HashSet;
use std::collections::BTreeMap;
use std::fmt::Display;
use std::ops::Neg;
use std::ops::Div;
use std::ops::Mul;
use std::ops::Add;
use std::ops::{AddAssign, Sub};
use std::cmp::max;
use std::collections::VecDeque;
use std::cmp::min;
use std::collections::{HashMap, BTreeSet};
use std::cmp::Ordering;
use std::fmt::Debug;

fn read_line() -> String {
    let mut buffer = String::new();
    std::io::stdin().read_line(&mut buffer).expect("No Line");
    buffer.trim().to_owned()
}
fn read_lines<T: std::str::FromStr>(count: usize) -> Vec<T> {
    let mut buffer = String::new();
    let mut vec = Vec::with_capacity(count);
    for _ in 0 .. count {
        std::io::stdin().read_line(&mut buffer).expect("No Line");
        vec.push(buffer.trim().parse().ok().expect("Can't Parse"));
        buffer.clear();
    }
    vec
}
fn read_tabulate<R, T: Fn(&str)->R> (count: usize, transformer: T) -> Vec<R> {
    let mut buffer = String::new();
    let mut vec = Vec::with_capacity(count);
    for _ in 0 .. count {
        std::io::stdin().read_line(&mut buffer).expect("No Line");
        vec.push(transformer(buffer.trim()));
        buffer.clear();
    }
    vec
}
fn read_value<T: std::str::FromStr>() -> T {
    read_line().trim().parse().ok().unwrap()
}
fn read_values<T: std::str::FromStr>() -> Vec<T> {
    read_line().trim().split_whitespace().map(|x| x.parse().ok().expect("Can't Parse")).collect::<Vec<T>>()
}
macro_rules! freeze {
    ($($id:ident), *) => {
        $(let $id = $id;)*
    };
}
macro_rules! read_map {
    ($ident: ident: [$block: block; $size: expr]) => {
        let $ident = (0 .. $size).into_iter().map(|_| $block).collect::<Vec<_>>();
    };
    (mut $ident: ident: [$block: block; $size: expr]) => {
        let mut $ident = (0 .. $size).into_iter().map(|_| $block).collect::<Vec<_>>();
    };
}
macro_rules! read {
    (mut $ident: ident: String) => {
        let mut $ident = read_value::<String>();
    };
    ($ident: ident: String) => {
        let $ident = read_value::<String>();
    };
    (mut $ident: ident: [$ty:ty]) => {
        let mut $ident = read_values::<$ty>();
    };
    ($ident: ident: [$ty:ty]) => {
        let $ident = read_values::<$ty>();
    };
    (mut $ident: ident: [[$ty:ty]; $size: expr]) => {
        let mut $ident = (0 .. $size).into_iter().map(|_| read_values::<$ty>()).collect::<Vec<_>>();
    };
    ($ident: ident: [[$ty:ty]; $size: expr]) => {
        let $ident = (0 .. $size).into_iter().map(|_| read_values::<$ty>()).collect::<Vec<_>>();
    };
    (mut $ident: ident: [$ty:ty; $size:expr]) => {
        let mut $ident = read_lines::<$ty>($size);
    };
    ($ident: ident: [$ty:ty; $size:expr]) => {
        let $ident = read_lines::<$ty>($size);
    };
    ($ident: ident: [$block: block; $size: expr]) => {
        let $ident = (0 .. $size).into_iter().map(|_| $block).collect::<Vec<_>>();
    };
    (mut $ident: ident: [$block: block; $size: expr]) => {
        let mut $ident = (0 .. $size).into_iter().map(|_| $block).collect::<Vec<_>>();
    };
    ($($token: tt)*) => {
        let mut iter = read_values::<String>().into_iter();
        read_from_iter!(iter; $($token)*);
    };
}
macro_rules! read_from_iter {
    ($iter:expr; mut $ident:ident:$ty:ty, $($rest:tt)*) => {
        let mut $ident = $iter.next().unwrap().parse::<$ty>().expect("Can't Parse");
        read_from_iter!($iter; $($rest)*);
    };
    ($iter:expr; $ident:ident:$ty:ty, $($rest:tt)*) => {
        let $ident = $iter.next().unwrap().parse::<$ty>().expect("Can't Parse");
        read_from_iter!($iter; $($rest)*);
    };
    ($iter:expr; mut $ident:ident:$ty:ty) => {
        let mut $ident = $iter.next().unwrap().parse::<$ty>().expect("Can't Parse");
    };
    ($iter:expr; $ident:ident:$ty:ty) => {
        let $ident = $iter.next().unwrap().parse::<$ty>().expect("Can't Parse");
    };
    ($iter: expr; ) => {};
}
struct KeyValue<K, V> {
    key: K,
    value: V
}
impl <K: PartialOrd, V> PartialEq for KeyValue<K, V> {
    fn eq(&self, other: &Self) -> bool {
        self.key.eq(&other.key)
    }
}
impl <K: PartialOrd, V> Eq for KeyValue<K, V> {}
impl <K: PartialOrd, V> PartialOrd for KeyValue<K, V> {
    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
        self.key.partial_cmp(&other.key)
    }
}
impl <K: PartialOrd, V> Ord for KeyValue<K, V> {
    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
        self.key.partial_cmp(&other.key).ok_or("Can't Compare").unwrap()
    }
}
#[derive(Eq, PartialEq)]
struct Rev<T: Ord>(T);
impl <T: std::cmp::Ord> PartialOrd for Rev<T> {
    fn partial_cmp(&self, rhs: &Rev<T>) -> std::option::Option<std::cmp::Ordering> { 
        rhs.0.partial_cmp(&self.0)
    }
}
impl <T: Ord> Ord for Rev<T> {
    fn cmp(&self, rhs: &Self) -> std::cmp::Ordering { 
        rhs.0.cmp(&self.0)
    }
}
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
struct Coordinate {
    x: i32, y: i32
}
impl Hash for Coordinate {
    fn hash<H>(&self, hasher: &mut H) where H: std::hash::Hasher {
        self.x.hash(hasher);
        self.y.hash(hasher);
    }
}
impl Coordinate {
    fn is_neighbor(&self, other: Coordinate) -> bool {
        let Coordinate{x: dx, y: dy} = *self - other;
        -1 <= dx && dx <= 1 && -1 <= dy && dy <= 1 && dx != dy
    }
    fn neighbor(&self) -> Vec<Coordinate> {
        vec![
            Coordinate{x: self.x, y: self.y + 1},
            Coordinate{x: self.x + 1, y: self.y},
            Coordinate{x: self.x + 1, y: self.y - 1},
            Coordinate{x: self.x, y: self.y - 1},
            Coordinate{x: self.x - 1, y: self.y},
            Coordinate{x: self.x - 1, y: self.y + 1}
        ]
    }
    fn neighbors() -> Vec<Coordinate> {
        Coordinate{x: 0, y: 0}.neighbor()
    }
}
impl Add for Coordinate {
    type Output = Coordinate;
    fn add(self, rhs: Coordinate) -> <Self as std::ops::Add<Coordinate>>::Output { 
        Coordinate{x: self.x + rhs.x, y: self.y + rhs.y}
    }
}
impl Sub for Coordinate {
    type Output = Coordinate;
    fn sub(self, rhs: Coordinate) -> <Self as std::ops::Sub<Coordinate>>::Output { 
        Coordinate{x: self.x - rhs.x, y: self.y - rhs.y}
    }
}
fn enumerate_all_next<F: FnMut(&Vec<Coordinate>) -> ()>(current: &Vec<Coordinate>, suspect: &mut Vec<Coordinate>, consumer: &mut F) {
    if current.len() == suspect.len() {
        return consumer(suspect);
    }
    if suspect.is_empty() || current[suspect.len() - 1] == suspect[suspect.len() - 1] {
        let len = suspect.len();
        suspect.push(current[len]);
        if is_valid_next_state(&current[0..suspect.len()], suspect) {
            enumerate_all_next(current, suspect, consumer);
        }
        suspect.pop();
        for next in current[suspect.len()].neighbor() {
            suspect.push(next);
            if is_valid_next_state(&current[0..suspect.len()], suspect) {
                enumerate_all_next(current, suspect, consumer);
            }
            suspect.pop();
        }
    }else {
        let len = suspect.len();
        suspect.push(current[len]);
        if is_valid_next_state(&current[0..suspect.len()], suspect) {
            enumerate_all_next(current, suspect, consumer);
        }
        suspect.pop();
    }
}
fn enumerate_all_initial<F: FnMut(&Vec<Coordinate>) -> ()>(suspect: &mut Vec<Coordinate>, consumer: &mut F) {
    if suspect.len() == 8 {
        return;
    }
    if let Some(&last) = suspect.last() {
        for next in last.neighbor() {
            suspect.push(next);
            if is_valid(suspect) {
                consumer(suspect);
                enumerate_all_initial(suspect, consumer);
            }
            suspect.pop();
        }
    }else {
        suspect.push(Coordinate{x: 0, y: 0});
        if is_valid(suspect) {
            consumer(suspect);
            enumerate_all_initial(suspect, consumer);
        }
        suspect.pop();
    }
}
fn to_dir(from: Coordinate, to: Coordinate) -> usize {
    match to - from {
        Coordinate{x: 0, y: 1} => 0,
        Coordinate{x: 1, y: 0} => 1,
        Coordinate{x: 1, y: -1} => 2,
        Coordinate{x: 0, y: -1} => 3,
        Coordinate{x: -1, y: 0} => 4,
        Coordinate{x: -1, y: 1} => 5,
        _ => panic!()
    }
}
fn to_index(trace: &Vec<Coordinate>) -> usize {
    let mut result = if trace[0].x == 0 && trace[0].y == 0 { 6 } else { to_dir(Coordinate{x: 0, y: 0}, trace[0]) };
    for i in 1 .. trace.len() {
        result = (result * 6) + to_dir(trace[i - 1], trace[i]);
    }
    result
}
fn is_valid(body: &[Coordinate]) -> bool {
    for i in 0 .. body.len() {
        for j in i + 2 .. body.len() {
            if body[i] == body[j] || body[i].is_neighbor(body[j]) {
                return false;
            }
        }
    }
    for i in 1 .. body.len() {
        if !body[i - 1].is_neighbor(body[i]) {
            return false;
        }
    }
    true
}
fn is_valid_next_state(prev: &[Coordinate], next: &[Coordinate]) -> bool {
    if !is_valid(next) {return false;}
    for i in 1 .. prev.len() {
        if prev[i - 1] != next[i - 1] && prev[i] != next[i] {
            return false;
        }
    }
    for i in 0 .. prev.len() {
        if prev[i] != next[i] && !prev[i].is_neighbor(next[i]) {
            return false;
        }
    }
    true
}
fn all_pair() -> HashMap<usize, (HashMap<usize, Vec<usize>>, HashMap<usize, Vec<Coordinate>>)>  {
    let mut suspect = vec![];
    let mut result = HashMap::new();
    enumerate_all_initial( &mut suspect, &mut |trace| {
        let ref mut t = result.entry(trace.len()).or_insert((HashMap::new(), HashMap::new()));
        let next_state = &mut t.0;
        let index_to_state = &mut t.1;
        index_to_state.insert(to_index(trace), trace.clone());
        let mut nexts = HashSet::new();
        let mut temp = vec![];
        enumerate_all_next(trace, &mut temp, &mut |next| {
            nexts.insert(to_index(next));
           if next[0] != trace[0] { index_to_state.entry(to_index(next)).or_insert(next.clone()); };
        });
        next_state.insert(to_index(trace), nexts.into_iter().collect::<Vec<_>>());
    });
    result
}
fn main() {
    let heuristic_length = |coordinate: Coordinate| { max(max(coordinate.x, coordinate.y), (coordinate.x + coordinate.y).abs()) };
    let caches = all_pair();
    loop {
        read!(n: usize);
        if n == 0 { break; }
        read_map!(snake: [{
            read!(x: i32, y: i32);
            Coordinate{x: x, y: y}
        }; n]);
        let ref t = caches.get(&n).unwrap();
        let ref next_states = t.0;
        let ref indices_to_state = t.1;
        read!(k: usize);
        read_map!(blocks: [{
            read!(x: i32, y: i32);
            Coordinate{x: x, y: y}
        }; k]);
        read!(X: i32, Y: i32);
        let goal = Coordinate{x: X, y: Y};
        let mut queue = BinaryHeap::new();
        let mut memo = HashMap::<(Coordinate, usize), i32>::new();
        memo.insert((snake[0], to_index(&snake.iter().map(|&c| c - snake[0]).collect::<Vec<_>>())), 0);
        queue.push(Rev(KeyValue{key: 0, value: (snake[0], to_index(&snake.iter().map(|&c| c - snake[0]).collect::<Vec<_>>()))}));
        let mut result = None;
        while let Some(Rev(KeyValue{key: all_step, value: (head, posture)})) = queue.pop() {
            //println!("all_step: {}, head: {:?}, position: {:?}", all_step, head, indices_to_state[&posture]);
            if head == goal {
                result = Some(all_step);
                break;
            }
            let step = *memo.get(&(head, posture)).unwrap();
            for next in &next_states[&posture] {
                if let Some(pos) = indices_to_state.get(next) {
                    let next_pos = pos.iter().map(|&c| c + head).collect::<Vec<_>>();
                    if next_pos.iter().any(|c| blocks.contains(c)) {continue;};
                    //println!("next_pos: {:?}, step: {}", next_pos, step);
                    let next = to_index(&next_pos.iter().map(|&c| c - next_pos[0]).collect::<Vec<_>>());
                    let m = memo.entry((next_pos[0], next)).or_insert(std::i32::MAX);
                    if *m > step + 1 {
                        *m = step + 1;
                        queue.push(Rev(KeyValue{key: step + 1 + heuristic_length(next_pos[0] - goal), value: (next_pos[0], next)}));
                    }
                }else {
                    panic!();
                }
            }
        }
        println!("{}", result.unwrap());
    }
}


Measured memory_bytes: 13252