// 21:24~

#include<queue>
#include<cstdio>

#define rep(i,n) for(int i=0;i<(n);i++)

using namespace std;

const int dx[6]={1,0,-1,-1,0,1},dy[6]={-1,-1,0,1,1,0};

int n; // 大蛇の長さ

int m,rx[100],ry[100]; // 岩
bool rock[100][100];

int dist[100][100]; // 体との干渉を無視したときの, ゴールまでの最短距離

struct state{
	char dir[7]; // メモリ節約のため char
};

void to_xy_from(const state &s,int *x,int *y){
	x[0]=y[0]=0;
	rep(i,n-1){
		x[i+1]=x[i]+dx[s.dir[i]];
		y[i+1]=y[i]+dy[s.dir[i]];
	}
}

state to_direction_form(const int *x,const int *y){
	state s;
	rep(i,n-1){
		rep(k,6) if(x[i]+dx[k]==x[i+1] && y[i]+dy[k]==y[i+1]) { s.dir[i]=k; break; }
	}
	return s;
}

int hash(const state &s){
	int h=0;
	rep(i,n-1) h=h*6+s.dir[i];
	return h;
}

state revhash(int h){
	state s;
	rep(i,n-1) s.dir[n-i-2]=h%6, h/=6;
	return s;
}

bool is_adjacent(int x1,int y1,int x2,int y2){
	rep(k,6) if(x1+dx[k]==x2 && y1+dy[k]==y2) return true;
	return false;
}

bool is_valid(const int *x,const int *y){ // 大蛇が連結かつ, 隣接する体節以外が接触していないかどうか
	rep(i,n-1){
		if(!is_adjacent(x[i],y[i],x[i+1],y[i+1])) return false;
		rep(j,n){
			if(j!=i && x[i]==x[j] && y[i]==y[j]) return false;
			if(j!=i-1 && j!=i+1 && is_adjacent(x[i],y[i],x[j],y[j])) return false;
		}
	}
	return true;
}

struct edge{ int v,dx,dy; };

struct node{
	int x0,y0,v;
	bool operator<(const node &a)const{ return true; } // dummy
};

bool is_conflict(const node &a,const state &s){ // 岩と衝突しているかどうか
	static int x[8],y[8];
	to_xy_from(s,x,y);
	rep(i,n) if(rock[a.y0+y[i]+50][a.x0+x[i]+50]) return true;
	return false;
}

int hstar(const node &a){ return dist[a.y0+50][a.x0+50]; }

int main(){
	for(;scanf("%d",&n),n;){
		// input
		int x[8],y[8];
		rep(i,n) scanf("%d%d",x+i,y+i);

		int m; scanf("%d",&m);
		int rx[100],ry[100];
		rep(i,m) scanf("%d%d",rx+i,ry+i);

		int gx,gy; scanf("%d%d",&gx,&gy);

		// 蛇のスタート位置を原点にする
		const int DX=x[0],DY=y[0];
		rep(i,8) x[i]-=DX, y[i]-=DY;
		rep(i,m) rx[i]-=DX, ry[i]-=DY;
		gx-=DX; gy-=DY;

		rep(i,100) rep(j,100) rock[i][j]=false;
		rep(i,m){
			if(-30<rx[i] && rx[i]<30 && -30<ry[i] && ry[i]<30){
				rock[ry[i]+50][rx[i]+50]=true;
			}
		}

		// dist を計算
		{
			rep(i,100) rep(j,100) dist[i][j]=777;
			static pair<int,int> Q[10000];
			int head=0,tail=0; Q[tail++]=make_pair(gx,gy);
			dist[gy+50][gx+50]=0;
			while(head<tail){
				int x=Q[head].first,y=Q[head].second; head++;
				if(x<-30 || 30<x || y<-30 || 30<y) continue;
				rep(k,6){
					int xx=x+dx[k],yy=y+dy[k];
					if(dist[yy+50][xx+50]==777){
						dist[yy+50][xx+50]=dist[y+50][x+50]+1;
						Q[tail++]=make_pair(xx,yy);
					}
				}
			}
		}

		// 長さ n の大蛇の全ての形を生成
		state ini=to_direction_form(x,y);

		static bool vis[279936]; // 279936=6^7
		static state S[279936]; // hash -> state
		rep(i,279936) vis[i]=false;
		vis[hash(ini)]=true;
		S[hash(ini)]=ini;
		{
			static int Q[4074];
			int head=0,tail=0; Q[tail++]=hash(ini);
			while(head<tail){
				state s=S[Q[head++]];
				int x[8],y[8];
				to_xy_from(s,x,y);
				rep(i,n) rep(k,6) {
					x[i]+=dx[k];
					y[i]+=dy[k];
					if(is_valid(x,y)){
						state t=to_direction_form(x,y);
						int h=hash(t);
						if(!vis[h]){
							vis[h]=true;
							S[h]=t;
							Q[tail++]=h;
						}
					}
					x[i]-=dx[k];
					y[i]-=dy[k];
				}
			}
		}

		// 形は高々 4074 通りしかないので圧縮
		int N=0;
		static int f[4074],g[279936];
		rep(i,279936) if(vis[i]) f[N]=i, g[i]=N++;
// printf("N=%d\n",N);
// rep(u,N){
	// state s=S[f[u]];
	// int x[8],y[8];
	// to_xy_from(s,x,y);
	// printf("%2d: ",u);
	// rep(i,n) printf("(%d,%d) - ",x[i],y[i]); puts("");
// }

		static vector<edge> G[4074];
		rep(u,N){
// printf("u=%d:\n",u);
			G[u].clear();

			state s=S[f[u]];
			int x[8],y[8];
			to_xy_from(s,x,y);

			int sz[8]={},dir[8][2]; // 体節を動かせる方向
			rep(i,n) rep(k,6) {
				x[i]+=dx[k];
				y[i]+=dy[k];
				if((i== 0  || is_adjacent(x[i],y[i],x[i-1],y[i-1]))
				&& (i==n-1 || is_adjacent(x[i],y[i],x[i+1],y[i+1]))) dir[i][sz[i]++]=k;
				x[i]-=dx[k];
				y[i]-=dy[k];
			}

			rep(T,1<<n) if(T!=0) { // 動かす体節
				bool ok=true;
				rep(i,n) if(T>>i&1) {
					if(i<n && T>>i+1&1 || sz[i]==0){ ok=false; break; }
				}
				if(!ok) continue;

				int k[8]={};
				for(k[0]=0;k[0]<(T&1?2:1);k[0]++) for(k[n-1]=0;k[n-1]<(T>>n-1&1?2:1);k[n-1]++) {
					int xx[8],yy[8];
					rep(i,n){
						if(T>>i&1){
							xx[i]=x[i]+dx[dir[i][k[i]]];
							yy[i]=y[i]+dy[dir[i][k[i]]];
						}
						else{
							xx[i]=x[i];
							yy[i]=y[i];
						}
					}
					if(is_valid(xx,yy)){
						state t=to_direction_form(xx,yy);
						G[u].push_back((edge){g[hash(t)],x[0]-xx[0],y[0]-yy[0]});
// printf("%2d -> %2d, dx=%2d, dy=%2d\n",u,g[hash(t)],x[0]-xx[0],y[0]-yy[0]);
					}
				}
			}
		}

		// 探索
		static bool memo[40][40][4074];
		rep(i,40) rep(j,40) rep(u,N) memo[i][j][u]=false;

		int ans=-1;
		priority_queue< pair<pair<int,int>,node> > Q;
		node ininode={x[0],y[0],g[hash(ini)]};
		Q.push(make_pair(make_pair(-hstar(ininode),0),ininode));
		while(!Q.empty()){
			int d=-Q.top().first.second;
			node a=Q.top().second; Q.pop();
			int u=a.v;

			if(a.x0==gx && a.y0==gy){ ans=d; break; }

			if(memo[a.y0+20][a.x0+20][u]) continue;
			memo[a.y0+20][a.x0+20][u]=true;

			rep(i,G[u].size()){
				const edge &e=G[u][i];
				node a2={a.x0-e.dx,a.y0-e.dy,e.v};
				if(!is_conflict(a2,S[f[e.v]])){
					Q.push(make_pair(make_pair(-(d+1+hstar(a2)),-(d+1)),a2));
				}
			}
		}
		printf("%d\n",ans);
	}

	return 0;
}

Measured memory_bytes: 16608