#include<cmath>
#include<cstdio>
#include<vector>
#include<algorithm>

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

using namespace std;

const double EPS=1e-9;
const double PI=acos(-1);

template<class T>
struct point{
	T x,y;
	point operator+(const point &a)const{ return (point){x+a.x,y+a.y}; }
	point operator-(const point &a)const{ return (point){x-a.x,y-a.y}; }
};

template<class T>
point<T> operator*(T c,const point<T> &a){ return (point<T>){c*a.x,c*a.y}; }

template<class T>
point<double> operator/(const point<T> &a,double c){
	return (point<double>){a.x/c,a.y/c};
}

bool operator<(const point<double> &a,const point<double> &b){
	return a.x+EPS<b.x || abs(a.x-b.x)<EPS && a.y+EPS<b.y;
}

template<class T>
struct line{ point<T> a,b; };

template<class T>
struct segment{
	point<T> a,b;
	operator line<T>()const{ return (line<T>){a,b}; }
};

template<class T>
struct polygon:vector< point<T> >{
	polygon(){}
	polygon(int n):vector< point<T> >(n){}
};

template<class T>
T dot(const point<T> &a,const point<T> &b){ return a.x*b.x+a.y*b.y; }

template<class T>
T cross(const point<T> &a,const point<T> &b){ return a.x*b.y-a.y*b.x; }

point<double> rot(const point<double> &a,double theta){
	return (point<double>){a.x*cos(theta)-a.y*sin(theta),a.x*sin(theta)+a.y*cos(theta)};
}

enum {CCW=1,CW=-1,ON=0};
int ccw(const point<double> &a,const point<double> &b,const point<double> &c){
	double rdir=cross(b-a,c-a);
	if(rdir> EPS) return CCW;
	if(rdir<-EPS) return CW;
	return ON;
}

bool cover(const polygon<double> &G,const point<double> &p){
	int n=G.size();
	bool res=false;
	rep(i,n){
		point<double> v1=G[i]-p,v2=G[(i+1)%n]-p;
		if(v1.y>v2.y) swap(v1,v2);
		if(v1.y<EPS && EPS<v2.y && cross(v1,v2)>EPS) res=!res;
		if(abs(cross(v1,v2))<EPS && dot(v1,v2)<EPS) return true;
	}
	return res;
}

bool intersect(const segment<double> &S1,const segment<double> &S2){
	if(max(S1.a.x,S1.b.x)+EPS<min(S2.a.x,S2.b.x)
	|| max(S1.a.y,S1.b.y)+EPS<min(S2.a.y,S2.b.y)
	|| max(S2.a.x,S2.b.x)+EPS<min(S1.a.x,S1.b.x)
	|| max(S2.a.y,S2.b.y)+EPS<min(S1.a.y,S1.b.y)) return false;
	return ccw(S1.a,S1.b,S2.a)*ccw(S1.a,S1.b,S2.b)<=0
		&& ccw(S2.a,S2.b,S1.a)*ccw(S2.a,S2.b,S1.b)<=0;
}

point<double> get_intersect(const line<double> &L1,const line<double> &L2){
	double a1=cross(L1.b-L1.a,L2.b-L2.a);
	double a2=cross(L1.b-L1.a,L1.b-L2.a);
	if(abs(a1)<EPS) return L1.a;
	return L2.a+a2/a1*(L2.b-L2.a);
}

bool cover(const polygon<double> &G,const polygon<double> &H){
	int m=G.size(),n=H.size();

	rep(i,n){
		if(!cover(G,H[i])) return false;

		segment<double> S={H[i],H[(i+1)%n]};

		vector< point<double> > cand; // H の辺 i と G との交点全体
		cand.push_back(S.a);
		cand.push_back(S.b);
		rep(j,m){
			segment<double> T={G[j],G[(j+1)%m]};
			if(intersect(S,T)){
				cand.push_back(get_intersect(S,T));
			}
		}

		sort(cand.begin(),cand.end());
		rep(j,(int)cand.size()-1){
			point<double> p=(cand[j]+cand[j+1])/2;
			if(!cover(G,p)) return false;
		}
	}

	return true;
}

int main(){
	for(int m,n;scanf("%d%d",&m,&n),m;){
		polygon<double> G(m),H(n);
		rep(i,m) scanf("%lf%lf",&G[i].x,&G[i].y);
		rep(i,n) scanf("%lf%lf",&H[i].x,&H[i].y);
		point<double> c;
		scanf("%lf%lf",&c.x,&c.y);

		polygon<double> H2(n);
		int deg;
		for(deg=1;deg<360;deg++){
			rep(i,n) H2[i]=rot(H[i]-c,deg*PI/180)+c;
			if(!cover(G,H2)) break;
		}

		double lo=(deg-1)*PI/180,hi=deg*PI/180;
		rep(_,30){
			double mi=(lo+hi)/2;
			rep(i,n) H2[i]=rot(H[i]-c,mi)+c;
			if(cover(G,H2)) lo=mi; else hi=mi;
		}
		printf("%.9f\n",(lo+hi)/2*180/PI);
	}

	return 0;
}

Measured memory_bytes: 876