Problem:
Problem G:
Turn Polygons
HCII, the health committee for interstellar intelligence, aims to take care of the health of every
interstellar intelligence.
Staff of HCII uses a special equipment for health checks of patients. This equipment looks like a
polygon-shaped room with plenty of instruments. The staff puts a patient into the equipment,
then the equipment rotates clockwise to diagnose the patient from various angles. It fits many
species without considering the variety of shapes, but not suitable for big patients. Furthermore,
even if it fits the patient, it can hit the patient during rotation.
Figure 1: The Equipment used by HCII
The interior shape of the equipment is a polygon with
M
vertices, and the shape of patients
is a
convex
polygon with
N
vertices. Your job is to calculate how much you can rotate the
equipment clockwise without touching the patient, and output the angle in degrees.
Input
The input consists of multiple data sets, followed by a line containing “0 0”. Each data set is
given as follows:
M N
px
1
py
1
px
2
py
2
...
px
M
py
M
qx
1
qy
1
qx
2
qy
2
...
qx
N
qy
N
cx cy
The first line contains two integers
M
and
N
(3 ≤
M, N
≤ 10). The second line contains 2
M
integers, where (
px
j
,
py
j
) are the coordinates of the
j
-th vertex of the equipment. The third
line contains 2
N
integers, where (
qx
j
,
qy
j
) are the coordinates of the
j
-th vertex of the patient.
The fourth line contains two integers
cx
and
cy
, which indicate the coordinates of the center of
rotation.
All the coordinates are between -1000 and 1000, inclusive. The vertices of each polygon are
given in counterclockwise order.
At the initial state, the patient is inside the equipment, and they don’t intersect each other.
You may assume that the equipment doesn’t approach patients closer than 10
-6
without hitting
patients, and that the equipment gets the patient to stick out by the length greater than 10
-6
whenever the equipment keeps its rotation after hitting the patient.
Output
For each data set, print the angle in degrees in a line. Each angle should be given as a decimal
with an arbitrary number of fractional digits, and with an absolute error of at most 10
-7
.
If the equipment never hit the patient during the rotation, print 360 as the angle.
Sample Input
5 4
0 0 20 0 20 10 0 10 1 5
10 3 12 5 10 7 8 5
10 5
4 3
0 0 10 0 10 5 0 5
3 1 6 1 5 4
0 0
5 3
0 0 10 0 10 10 0 10 3 5
1 1 4 1 4 6
0 0
0 0
Output for the Sample Input
360.0000000
12.6803835
3.3722867

Submitted solutions:

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 4000000000000000000 //オーバーフローに注意
#define MOD 1000000007
//#define EPS 0.000000001
using namespace std;


#define EPS 0.000000001
#define SIZE 15

struct Point{
	Point(double arg_x,double arg_y){
		x = arg_x;
		y = arg_y;
	}

	Point(){
		x = y = 0.0;
	}

	Point operator + (Point p){ return Point(x+p.x,y+p.y); }
	Point operator - (Point p){ return Point(x-p.x,y-p.y);}
	Point operator * (double a){ return Point(a*x,a*y); }
	Point operator / (double a){ return Point(x/a,y/a); }

	double abs(){ return sqrt(norm()); }
	double norm(){ return x*x + y*y; }

	bool operator<(const Point &p) const{

		if(fabs(x-p.x) > EPS){

			return x < p.x;
		}else{

			return y < p.y;
		}
	}

	bool operator == (const Point &p) const{
		return fabs(x-p.x) < EPS && fabs(y-p.y) < EPS;
	}


	void debug(){

		printf("(%.3lf,%.3lf)\n",x,y);
	}

	double x,y;
};

typedef Point Vector;
typedef vector<Point> Polygon;


struct Line{
	Line(){

	}
	Line(Point a,Point b){
		p[0] = a;
		p[1] = b;
	}
	/*void outPut(){

		printf("(%.3lf,%.3lf)-(%.3lf,%.3lf)\n",p[0].x,p[0].y,p[1].x,p[1].y);
	}*/
	Point p[2];
};

int M,N;

double norm(Vector a){
	return a.x*a.x+a.y*a.y;
}

double abs(Vector a){
	return sqrt(norm(a));
}

double cross(Vector a,Vector b){
    return a.x*b.y-a.y*b.x;
}

double dot(Vector a,Vector b){
    return a.x*b.x + a.y*b.y;
}

static const int COUNTER_CLOCKWISE = 1;
static const int CLOCKWISE = -1;
static const int ONLINE_BACK = 2;
static const int ONLINE_FRONT = -2;
static const int ON_SEGMENT = 0;

/*
 * p0を基準点として、p1から見てp2が
 * 反時計回り側にあれば
 * COUNTER_CLOCKWISE
 * */
int ccw(Point p0,Point p1,Point p2){

	Vector a = p1 - p0;
	Vector b = p2 - p0;

	if(cross(a,b) > EPS)return COUNTER_CLOCKWISE;
	if(cross(a,b) < -EPS)return CLOCKWISE;
	if(dot(a,b) < -EPS)return ONLINE_BACK;
	if(a.norm() < b.norm())return ONLINE_FRONT;

	return ON_SEGMENT;
}



/*点moveをbaseを中心にradラジアン回転させる
rad > 0なら反時計回り、rad < 0なら時計周り
*/
Point rotate(Point base,Point move,double rad){

	Point ret;
	move = move-base;

	ret.x = move.x*cos(rad)-move.y*sin(rad);
	ret.y = move.x*sin(rad)+move.y*cos(rad);

	ret = ret+base;

	return ret;
}

int func(double x1,double y1,double x2, double y2, double xp, double yp){
	double naiseki,norm1,norm2,gaiseki;
	norm1 = sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
	norm2 = sqrt((xp-x1)*(xp-x1)+(yp-y1)*(yp-y1));
	naiseki = (xp-x1)*(x2-x1)+(yp-y1)*(y2-y1);
	gaiseki = (x2-x1)*(yp-y1)-(xp-x1)*(y2-y1);
	if(gaiseki > EPS){
		return 1;
	}else if(gaiseki < -EPS){
		return -1;
	}
	if(naiseki < -EPS){
		return 2;
	}

	if(norm1 < norm2){
		return -2;
	}
	return 0;
}


//★★直線ではなく、線分の交差判定★★
bool is_Cross(Line a,Line b){

	if(func(a.p[0].x,a.p[0].y,a.p[1].x,a.p[1].y,b.p[0].x,b.p[0].y)*
			func(a.p[0].x,a.p[0].y,a.p[1].x,a.p[1].y,b.p[1].x,b.p[1].y) <= 0 &&
			func(b.p[0].x,b.p[0].y,b.p[1].x,b.p[1].y,a.p[0].x,a.p[0].y)*
			func(b.p[0].x,b.p[0].y,b.p[1].x,b.p[1].y,a.p[1].x,a.p[1].y) <= 0){
		return true;
	}
	return false;
}

Point calc_minus(Point a,Point b){
    Point ret;

    ret.x = a.x-b.x;
    ret.y = a.y-b.y;

    return ret;
}

double calc_len(Vector a){
    return sqrt(a.x*a.x+a.y*a.y);
}

//線分ではなく直線と点の距離
double getDistanceLP(Line l,Point p){
    return fabs(cross(calc_minus(l.p[1],l.p[0]),calc_minus(p,l.p[0]))/calc_len(calc_minus(l.p[1],l.p[0])));
}

//点と線分の距離
double getDistanceSP(Line l,Point p){
	if(dot(calc_minus(l.p[1],l.p[0]),calc_minus(p,l.p[0])) < 0.0)return calc_len(calc_minus(p,l.p[0]));
	if(dot(calc_minus(l.p[0],l.p[1]),calc_minus(p,l.p[1])) < 0.0)return calc_len(calc_minus(p,l.p[1]));
	return getDistanceLP(l,p);
}

bool Cross_Check(Line A,Line B){


	if(getDistanceSP(B,A.p[0]) < EPS){

		return true;

	}else if(getDistanceSP(B,A.p[1]) < EPS){

		return true;

	}else if(getDistanceSP(A,B.p[0]) < EPS){

		return true;

	}else if(getDistanceSP(A,B.p[1]) < EPS){

		return true;
	}

	return is_Cross(A,B);
}


bool is_Cross(Polygon a, Polygon b){

	for(int i = 0; i < a.size(); i++){

		Line base_line = Line(a[i],a[(i+1)%a.size()]);

		for(int k = 0; k < b.size(); k++){

			Line work_line = Line(b[k],b[(k+1)%b.size()]);
			if(getDistanceSP(work_line,a[i]) < EPS)return true;

			if(is_Cross(base_line,work_line)){

				return true;
			}
		}
	}

	return false;
}


void func(){

	Polygon BOX,poly;

	double x,y;

	for(int i = 0; i < M; i++){

		scanf("%lf %lf",&x,&y);
		BOX.push_back(Point(x,y));
	}

	for(int i = 0; i < N; i++){

		scanf("%lf %lf",&x,&y);
		poly.push_back(Point(x,y));
	}

	Point base;
	scanf("%lf %lf",&base.x,&base.y);

	int NUM = 10000;

	double diff = 2*M_PI/NUM;
	double roll_rad = 0;
	double last = -1;

	for(int i = 0; i < NUM; i++){

		Polygon tmp_B;
		for(int k = 0; k < BOX.size(); k++){

			Point tmp_p = rotate(base,BOX[k],-roll_rad);
			tmp_B.push_back(tmp_p);
		}

		if(is_Cross(poly,tmp_B)){
			last = roll_rad;
			break;
		}

		roll_rad += diff;
	}

	if(fabs(last+1.0) < EPS){

		printf("360.0000000000000\n");
		return;
	}

	double left = last-diff,right = last,mid = (left+right)/2;
	double ans = right;

	for(int loop = 0; loop < 100; loop++){

		Polygon tmp_B;
		for(int k = 0; k < BOX.size(); k++){

			Point tmp_p = rotate(base,BOX[k],-mid);
			tmp_B.push_back(tmp_p);
		}
		if(is_Cross(poly,tmp_B)){

			ans = mid;
			right = mid-EPS;
		}else{

			left = mid+EPS;
		}
		mid = (left+right)/2;
	}

	printf("%.12lf\n",ans*(180/M_PI));
}

int main(){

	while(true){

		scanf("%d %d",&M,&N);
		if(M == 0 && N == 0)break;

		func();
	}

	return 0;
}
accuracy: 1
time_ms: 3190
memory_kb: 3616
final_rank: 18

code_snippet: #include <iostream>
#include <iomanip>
#include <complex>
#include <vector>
#include <algorithm>
#include <cmath>
using namespace std;
const double EPS = 1e-10;
const double INF = 1e12;
const double PI = acos(-1);
#define EQ(n,m) (abs((n)-(m)) < EPS)
#define X real()
#define Y imag()

typedef complex<double> P;
typedef vector<P> VP;
struct L : array<P, 2>{
    L(const P& a, const P& b){ at(0)=a; at(1)=b; }
    L(){}
};
struct C{
    P p;
    double r;
    C(const P& p, const double& r) : p(p), r(r) {}
    C(){}
};

namespace std{
    bool operator < (const P& a, const P& b){
        return !EQ(a.X,b.X) ? a.X<b.X : a.Y+EPS<b.Y;
    }
    bool operator == (const P& a, const P& b){
        return abs(a-b) < EPS;
    }
}

double dot(P a, P b){
    return (conj(a)*b).X;
}
double cross(P a, P b){
    return (conj(a)*b).Y;
}
int ccw(P a, P b, P c){
    b -= a;
    c -= a;
    if(cross(b,c) > EPS) return +1; //ccw
    if(cross(b,c) < -EPS) return -1; //cw
    if(dot(b,c) < -EPS) return +2; //c-a-b
    if(abs(c)-abs(b) > EPS) return -2; //a-b-c
    return 0; //a-c-b
}

P unit(const P &p){
    return p/abs(p);
}

bool intersectSP(const L& s, const P &p){
    return abs(cross(s[0]-p, s[1]-p))<EPS  && dot(s[0]-p, s[1]-p)<EPS;
}

P projection(const L& l, const P& p) {
    double t = dot(p-l[0], l[0]-l[1]) / norm(l[0]-l[1]);
    return l[0] + t*(l[0]-l[1]);
}
double distanceLP(const L &l, const P &p) {
    return abs(cross(l[1]-l[0], p-l[0])) /abs(l[1]-l[0]);
}


VP crosspointCL(const C &c, const L &l){
    VP ret;
    P mid = projection(l, c.p);
    double d = distanceLP(l, c.p);
    if(EQ(d, c.r)){
        ret.push_back(mid);
    }else if(d < c.r){
        double len = sqrt(c.r*c.r -d*d);
        ret.push_back(mid +len*unit(l[1]-l[0]));
        ret.push_back(mid -len*unit(l[1]-l[0]));
    }
    return ret;
}
VP crosspointCS(const C &c, const L &s){
    VP ret;
    VP cp = crosspointCL(c,s);
    for(int i=0; i<(int)cp.size(); i++){
        if(intersectSP(s, cp[i])){
            ret.push_back(cp[i]);
        }
    }
    return ret;
}

double getangle360(const P &p, const P &a, const P &b){
    P proj = projection(L(p,a), b);
    int sign= (dot(a-p, b-p)>0)? 1: -1;
    if(ccw(p,a,b)!=-1){
        return acos(sign*abs(proj-p)/abs(b-p));
    }else{
        return 2*PI - acos(sign*abs(proj-p)/abs(b-p));
    }
}

int main(){
    while(1){
        int m,n;
        cin >> m >> n;
        if(m == 0) break;

        VP p(m), q(n);
        for(int i=0; i<m; i++){
            double x,y;
            cin >> x >> y;
            p[i] = P(x, y);
        }
        for(int i=0; i<n; i++){
            double x,y;
            cin >> x >> y;
            q[i] = P(x, y);
        }
        double cx,cy;
        cin >> cx >> cy;
        P c(cx, cy);

        double ans = 2*PI;
        //すべての辺同士の組み合わせ
        for(int i=0; i<m; i++){
            for(int j=0; j<n; j++){
                L ei(p[i], p[(i+1)%m]), ej(q[j], q[(j+1)%n]);
                for(int d=0; d<2; d++){
                    C ci(c, abs(ei[d] -c)), cj(c, abs(ej[d] -c));
                    VP cpi = crosspointCS(ci, ej);
                    for(P p: cpi){
                        ans = min(ans, getangle360(c, p, ei[d]));
                    }
                    VP cpj = crosspointCS(cj, ei);
                    for(P p: cpj){
                        ans = min(ans, getangle360(c, ej[d], p));
                    }
                }
            }
        }        


        cout << fixed << setprecision(10);
        cout << ans*180/PI << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3608
final_rank: 17

code_snippet: #include "bits/stdc++.h"
#include<unordered_map>
#include<unordered_set>
#pragma warning(disable:4996)
using namespace std;
using ld = long double;
const ld eps = 1e-9;



/* 幾何の基本 */

#include <complex>

typedef complex<ld> Point;


const ld pi = acos(-1.0);
const ld dtop = pi / 180.;
const ld ptod = 1. / dtop;

namespace std {
	bool operator<(const Point &lhs, const Point &rhs) {
		if (lhs.real() < rhs.real() - eps) return true;
		if (lhs.real() > rhs.real() + eps) return false;
		return lhs.imag() < rhs.imag();
	}
}

// 点の入力
Point input_Point() {
	ld x, y;
	cin >> x >> y;
	return Point(x, y);
}

// 誤差つき等号判定
bool eq(const ld a, const ld b) {
	return (abs(a - b) < eps);
}

// 内積
ld dot(const Point& a, const Point& b) {
	return real(conj(a) * b);
}

// 外積
ld cross(const Point& a, const Point& b) {
	return imag(conj(a) * b);
}

// 直線の定義
class Line {
public:
	Point a, b;
	Line() : a(Point(0, 0)), b(Point(0, 0)) {}
	Line(Point a, Point b) : a(a), b(b) {}
	Point operator[](const int _num)const {
		if (_num == 0)return a;
		else if (_num == 1)return b;
		else {
			assert(false);
			return Point();
		}
	}
};

// 円の定義
class Circle {
public:
	Point p;
	ld r;
	Circle() : p(Point(0, 0)), r(0) {}
	Circle(Point p, ld r) : p(p), r(r) {}
};

// ccw
// 1: a,b,cが反時計周りの順に並ぶ
//-1: a,b,cが時計周りの順に並ぶ
// 2: c,a,bの順に直線に並ぶ
//-2: a,b,cの順に直線に並ぶ
// 0: a,c,bの順に直線に並ぶ
int ccw(const Point& a, const Point &b, const Point &c) {
	const Point nb(b - a);
	const Point nc(c - a);
	if (cross(nb, nc) > eps) return 1;   // a,b,cが反時計周りの順に並ぶ
	if (cross(nb, nc) < -eps) return -1; // a,b,cが時計周りの順に並ぶ
	if (dot(nb, nc) < 0) return 2;       // c,a,bの順に直線に並ぶ
	if (norm(nb) < norm(nc)) return -2;  // a,b,cの順に直線に並ぶ
	return 0;                          // a,c,bの順に直線に並ぶ
}


/* 交差判定 */

// 直線と直線の交差判定
bool isis_ll(const Line& l, const Line& m) {
	return !eq(cross(l.b - l.a, m.b - m.a), 0);
}

// 直線と線分の交差判定
bool isis_ls(const Line& l, const Line& s) {
	return isis_ll(l, s) &&
		(cross(l.b - l.a, s.a - l.a) * cross(l.b - l.a, s.b - l.a) < eps);
}

// 線分と線分の交差判定
bool isis_ss(const Line& s, const Line& t) {
	return ccw(s.a, s.b, t.a) * ccw(s.a, s.b, t.b) <= 0 &&
		ccw(t.a, t.b, s.a) * ccw(t.a, t.b, s.b) <= 0;
}

// 点の直線上判定
bool isis_lp(const Line& l, const Point& p) {
	return (abs(cross(l.b - p, l.a - p)) < eps);
}

// 点の線分上判定
bool isis_sp(const Line& s, const Point& p) {
	return (abs(s.a - p) + abs(s.b - p) - abs(s.b - s.a) < eps);
}

// 垂線の足
Point proj(const Line &l, const Point& p) {
	ld t = dot(p - l.a, l.b - l.a) / norm(l.a - l.b);
	return l.a + t * (l.b - l.a);
}

//線対象の位置にある点
Point reflect(const Line &l, const Point &p) {
	Point pr = proj(l, p);
	return pr * 2.l - p;
}

// 直線と直線の交点
Point is_ll(const Line &s, const Line& t) {
	Point sv = s.b - s.a, tv = t.b - t.a;
	assert(cross(sv, tv) != 0);
	return s.a + sv * cross(tv, t.a - s.a) / cross(tv, sv);
}
// 直線と直線の交点
vector<Point> is_ll2(const Line &s, const Line& t) {
	Point sv = s.b - s.a, tv = t.b - t.a;
	if (cross(sv, tv) != 0)return vector<Point>(1, is_ll(s, t));
	else {
		vector<Point>ans;
		for (int k = 0; k < 2; ++k) {
			if (isis_sp(s, t[k]) && find(ans.begin(), ans.end(), t[k]) == ans.end())ans.push_back(t[k]);
			if (isis_sp(t, s[k]) && find(ans.begin(), ans.end(), s[k]) == ans.end())ans.push_back(s[k]);
		}
		return ans;
	}
}
// 線分と線分の交点
//　重なってる部分あるとassert(false)
Point is_ss(const Line &s, const Line& t) {
	if (isis_ss(s, t)) {
		for (int k = 0; k < 2; ++k) {
			for (int l = 0; l < 2; ++l) {
				if (s[k] == t[l])return s[k];
			}
		}
		return is_ll(s, t);
	}
	else {
		//先にisis_ssしてね
		assert(false);
		return Point(0, 0);
	}
}
// 線分と線分の交点
vector<Point> is_ss2(const Line &s, const Line& t) {
	vector<Point> kouho(is_ll2(s, t));
	vector<Point>ans;
	for (auto p : kouho) {
		if (isis_sp(s, p) && isis_sp(t, p))ans.emplace_back(p);
	}
	return ans;
}
// 直線と点の距離
ld dist_lp(const Line& l, const Point& p) {
	return abs(p - proj(l, p));
}

//直線と直線の距離
ld dist_ll(const Line& l, const Line& m) {
	return isis_ll(l, m) ? 0 : dist_lp(l, m.a);
}

// 直線と線分の距離
ld dist_ls(const Line& l, const Line& s) {
	return isis_ls(l, s) ? 0 : min(dist_lp(l, s.a), dist_lp(l, s.b));
}

// 線分と点の距離
ld dist_sp(const Line& s, const Point& p) {
	Point r = proj(s, p);
	return isis_sp(s, r) ? abs(r - p) : min(abs(s.a - p), abs(s.b - p));
}

// 線分と線分の距離
ld dist_ss(const Line& s, const Line& t) {
	if (isis_ss(s, t)) return 0;
	return min({ dist_sp(s, t.a), dist_sp(s, t.b), dist_sp(t, s.a), dist_sp(t, s.b) });
}


//直線と直線の二等分線のベクトル
Line line_bisection(const Line &s, const Line &t) {
	const Point laglanju(is_ll(s, t));
	const Point avec = !(abs(laglanju - s[0])<eps) ? s[0] - laglanju : s[1] - laglanju;
	const Point bvec = !(abs(laglanju - t[0])<eps) ? t[0] - laglanju : t[1] - laglanju;

	return Line(laglanju, laglanju + (abs(bvec)*avec + abs(avec)*bvec) / (abs(avec) + abs(bvec)));
}
//点と点の垂直二等分線　aを左に見ながら
Line point_bisection(const Point&a, const Point&b) {
	const Point cen((a + b) / 2.l);
	const Point vec = (b - a)*Point(0, 1);
	return Line(cen, cen + vec);
}

//三つの点からなる外心
Point outer_center(const vector<Point>&ps) {
	assert(ps.size() == 3);
	Line l1 = point_bisection(ps[0], ps[1]);
	Line l2 = point_bisection(ps[1], ps[2]);
	return is_ll(l1, l2);
}


//三つの直線からなる内心
//三つの直線が並行でないことは確かめといてね
Point  inner_center(const vector<Line>&ls) {
	vector<Point>vertics;
	for (int i = 0; i <static_cast<int>(ls.size()); ++i) {
		vertics.push_back(is_ll(ls[i], ls[(i + 1) % 3]));
	}
	if (vertics[0] == vertics[1] || vertics[1] == vertics[2] || vertics[2] == vertics[0])return vertics[0];
	Line bi1(line_bisection(Line(vertics[0], vertics[1]), Line(vertics[0], vertics[2])));
	Line bi2(line_bisection(Line(vertics[1], vertics[2]), Line(vertics[1], vertics[0])));
	if (bi1[0] == bi2[0])return bi1[0];
	else {
		return is_ll(bi1, bi2);
	}
}

//三つの直線からなる傍心
//三つの直線が並行でないことは確かめといてね
vector<Point>  ex_center(const vector<Line>&ls) {
	vector<Point>vertics;
	for (int i = 0; i < static_cast<int>(ls.size()); ++i) {
		vertics.push_back(is_ll(ls[i], ls[(i + 1) % 3]));
	}
	if (abs(vertics[0] - vertics[1])<eps || abs(vertics[1] - vertics[2])<eps || (abs(vertics[2] - vertics[0])<eps))return vector<Point>();
	vector<Point>ecs;
	for (int i = 0; i < 3; ++i) {
		Line bi1(line_bisection(Line(vertics[i], vertics[i] * 2.0l - vertics[(i + 2) % 3]), Line(vertics[i], vertics[(i + 1) % 3])));
		Line bi2(line_bisection(Line(vertics[(i + 1) % 3], vertics[(i + 1) % 3] * 2.0l - vertics[(i + 2) % 3]), Line(vertics[(i + 1) % 3], vertics[i])));
		ecs.push_back(is_ll(bi1, bi2));
	}
	return ecs;
}


//a,b:並行
//c:並行でない
//三つの直線から同距離の位置を求める。
vector<Point>  same_dis(const vector<Line>&ls) {
	vector<Point>vertics;
	vertics.push_back(is_ll(ls[0], ls[2]));
	vertics.push_back(is_ll(ls[1], ls[2]));

	if (abs(vertics[0] - vertics[1]) < eps)return vector<Point>{vertics[0]};
	Line bis(line_bisection(ls[0], ls[1]));
	vector<Point>ecs;

	Line abi(line_bisection(Line(vertics[0], vertics[1]), ls[0]));
	ecs.push_back(is_ll(bis, abi));


	Line bbi(line_bisection(Line(vertics[0], 2.l*vertics[0] - vertics[1]), ls[0]));
	ecs.push_back(is_ll(bis, bbi));

	return ecs;
}
/* 円 */

// 円と円の交点
vector<Point> is_cc(const Circle& c1, const Circle& c2) {
	vector<Point> res;
	ld d = abs(c1.p - c2.p);
	ld rc = (d * d + c1.r * c1.r - c2.r * c2.r) / (2 * d);
	ld dfr = c1.r * c1.r - rc * rc;
	if (abs(dfr) < eps) dfr = 0.0;
	else if (dfr < 0.0) return res; // no intersection
	ld rs = sqrt(dfr);
	Point diff = (c2.p - c1.p) / d;
	res.push_back(c1.p + diff * Point(rc, rs));
	if (dfr != 0.0) res.push_back(c1.p + diff * Point(rc, -rs));
	return res;
}

/*
点が円の中にいるか
0 => out
1 => on
2 => in*/
int is_in_Circle(const  Point& p, const Circle &cir) {
	ld dis = abs(cir.p - p);
	if (dis > cir.r + eps)return 0;
	else if (dis < cir.r - eps)return 2;
	else return 1;
}
int is_in_Circle(const Circle &cir, const  Point& p) {
	ld dis = abs(cir.p - p);
	if (dis > cir.r + eps)return 0;
	else if (dis < cir.r - eps)return 2;
	else return 1;
}
/*
円lcが円rcの中にいるか
0 => out
1 => on
2 => in*/
int Circle_in_Circle(const Circle &lc, const  Circle&rc) {
	ld dis = abs(lc.p - rc.p);
	if (dis < rc.r - lc.r - eps)return 2;
	else if (dis>rc.r - lc.r + eps)return 0;
	else return 1;
}

// 円と直線の交点
vector<Point> is_lc(const Circle& c, const Line& l) {
	vector<Point> res;
	ld d = dist_lp(l, c.p);
	if (d < c.r + eps) {
		ld len = (d > c.r) ? 0.0 : sqrt(c.r * c.r - d * d); //safety;
		Point nor = (l.a - l.b) / abs(l.a - l.b);
		res.push_back(proj(l, c.p) + len * nor);
		res.push_back(proj(l, c.p) - len * nor);
	}
	return res;
}

// 円と線分の距離
vector<Point> is_sc(const Circle& c, const Line& l) {
	vector<Point> v = is_lc(c, l), res;
	for (Point p : v)
		if (isis_sp(l, p)) res.push_back(p);
	return res;
}

// 円と点の接線
vector<Line> tangent_cp(const Circle& c, const Point& p) {
	vector<Line> ret;
	Point v = c.p - p;
	ld d = abs(v);
	ld l = sqrt(norm(v) - c.r * c.r);
	if (isnan(l)) { return ret; }
	Point v1 = v * Point(l / d, c.r / d);
	Point v2 = v * Point(l / d, -c.r / d);
	ret.push_back(Line(p, p + v1));
	if (l < eps) return ret;
	ret.push_back(Line(p, p + v2));
	return ret;
}

// 円と円の接線
vector<Line> tangent_cc(const Circle& c1, const Circle& c2) {
	vector<Line> ret;
	if (abs(c1.p - c2.p) - (c1.r + c2.r) > -eps) {
		Point center = (c1.p * c2.r + c2.p * c1.r) / (c1.r + c2.r);
		ret = tangent_cp(c1, center);
	}
	if (abs(c1.r - c2.r) > eps) {
		Point out = (-c1.p * c2.r + c2.p * c1.r) / (c1.r - c2.r);
		vector<Line> nret = tangent_cp(c1, out);
		ret.insert(ret.end(), nret.begin(), nret.end());
	}
	else {
		Point v = c2.p - c1.p;
		v /= abs(v);
		Point q1 = c1.p + v * Point(0, 1) * c1.r;
		Point q2 = c1.p + v * Point(0, -1) * c1.r;
		ret.push_back(Line(q1, q1 + v));
		ret.push_back(Line(q2, q2 + v));
	}
	return ret;
}
//二つの円の重なり面積
ld two_Circle_area(const Circle&l, const Circle&r) {
	ld dis = abs(l.p - r.p);
	if (dis > l.r + r.r)return 0;
	else if (dis + r.r < l.r) {
		return r.r*r.r*pi;
	}
	else if (dis + l.r < r.r) {
		return l.r*l.r*pi;
	}
	else {
		ld ans = (l.r)*(l.r)*acos((dis*dis + l.r*l.r - r.r*r.r) / (2 * dis*l.r)) +
			(r.r)*(r.r)*acos((dis*dis + r.r*r.r - l.r*l.r) / (2 * dis*r.r)) -
			sqrt(4 * dis*dis*l.r*l.r - (dis*dis + l.r*l.r - r.r*r.r)*(dis*dis + l.r*l.r - r.r*r.r)) / 2;
		return ans;
	}

}

/* 多角形 */

typedef vector<Point> Polygon;



//多角形(複数の点)の最小包含円をO(N=頂点数)で求めるアルゴリズム
//同一直線上に三つの点がないこと
#include<random>
Circle welzl(vector<Point>ps) {
	struct solver {
		Circle solve(vector<Point>&ps, vector<Point>&rs) {
			if (ps.empty() || rs.size() == 3) {
				if (rs.size() == 1) {
					return Circle(Point(rs[0]), 0);
				}
				else if (rs.size() == 2) {
					return Circle((rs[0] + rs[1]) / 2.0l, abs(rs[1] - rs[0]) / 2);
				}
				else if (rs.size() == 3) {
					vector<Line> ls(3);
					for (int i = 0; i < 3; ++i) {
						ls[i] = Line(rs[i], rs[(i + 1) % 3]);
					}
					Point center = outer_center(rs);
					return Circle(center, abs(center - rs[0]));
				}
				else {
					return Circle(Point(), 0);
				}
			}
			else {

				Point p_ba = ps.back();
				ps.pop_back();
				Circle d = solve(ps, rs);
				ps.push_back(p_ba);
				if (is_in_Circle(d, p_ba)) {
					return d;
				}
				else {
					rs.push_back(p_ba);
					ps.pop_back();
					auto ans = solve(ps, rs);
					ps.push_back(p_ba);
					rs.pop_back();
					return ans;
				}
			}
		}
	}so;
	std::random_device rd;
	std::mt19937 mt(rd());
	shuffle(ps.begin(), ps.end(), mt);
	vector<Point>rs;
	Circle ans = so.solve(ps, rs);
	return ans;
}
// 面積
ld get_area(const Polygon &p) {
	ld res = 0;
	int n = p.size();
	for (int j = 0; j<n; ++j) res += cross(p[j], p[(j + 1) % n]);
	return res / 2;
}

//多角形の回転方向
bool is_counter_clockwise(const Polygon &poly) {
	ld angle = 0;
	int n = poly.size();
	for(int i=0;i<n;++i) {
		Point a = poly[i], b = poly[(i + 1) % n], c = poly[(i + 2) % n];
		angle += arg((c - b) / (b - a));
	}
	return angle > eps;
}

// 円の内外判定
/*0 => out
1 => on
2 => in*/
int is_in_Polygon(const Polygon &poly, const  Point& p) {
	ld angle = 0;
	int n = poly.size();
	for(int i=0;i<n;++i) {
		Point a = poly[i], b = poly[(i + 1) % n];
		if (isis_sp(Line(a, b), p)) return 1;
		angle += arg((b - p) / (a - p));
	}
	return eq(angle, 0) ? 0 : 2;
}
//円の内外判定2　高速
enum { out, on, in };
int convex_contains(const Polygon &P, const Point &p) {
	const int n = P.size();
	Point g = (P[0] + P[n / 3] + P[2 * n / 3]) / 3.0l; // inner-point
	int a = 0, b = n;
	while (a + 1 < b) { // invariant: c is in fan g-P[a]-P[b]
		int c = (a + b) / 2;
		if (cross(P[a] - g, P[c] - g) > 0) { // angle < 180 deg
			if (cross(P[a] - g, p - g) > 0 && cross(P[c] - g, p - g) < 0) b = c;
			else                                                  a = c;
		}
		else {
			if (cross(P[a] - g, p - g) < 0 && cross(P[c] - g, p - g) > 0) a = c;
			else                                                  b = c;
		}
	}
	b %= n;
	if (cross(P[a] - p, P[b] - p) < 0) return 0;
	if (cross(P[a] - p, P[b] - p) > 0) return 2;
	return 1;
}

// 凸包
//点や線を返すことも有り得るので注意
Polygon convex_hull(vector<Point> ps) {
	int n = ps.size();
	int k = 0;
	sort(ps.begin(), ps.end());
	Polygon ch(2 * n);
	for (int i = 0; i < n; ch[k++] = ps[i++])
		while (k >= 2 && ccw(ch[k - 2], ch[k - 1], ps[i]) <= 0) --k;
	for (int i = n - 2, t = k + 1; i >= 0; ch[k++] = ps[i--])
		while (k >= t && ccw(ch[k - 2], ch[k - 1], ps[i]) <= 0) --k;
	ch.resize(k - 1);
	return ch;
}



//凸カット
vector<Polygon> convex_cut(const Polygon &ps, const Line& l) {
	int n = ps.size();
	Polygon q;
	Polygon r;
	for(int i=0;i<n;++i) {
		Point a = ps[i], b = ps[(i + 1) % n];
		Line m = Line(a, b);
		if (ccw(l.a, l.b, a) != -1) q.push_back(a);
		if (ccw(l.a, l.b, a) != 1) r.push_back(a);
		if (ccw(l.a, l.b, a) * ccw(l.a, l.b, b) < 0 && isis_ll(l, m)) {
			q.push_back(is_ll(l, m));
			r.push_back(is_ll(l, m));
		}
	}
	const vector<Polygon>polys{ q,r };
	return polys;
}



int main() {
	cout<<setprecision(10)<<fixed;
	cout<<setprecision(10)<<fixed;
	cout<<setprecision(10)<<fixed;
	cout<<setprecision(10)<<fixed;
	cout<<setprecision(10)<<fixed;
	while (true){
		int M,N;cin>>M>>N;
		if(!M)break;
		Polygon rooms,patient;
		for (int i = 0; i < M; ++i) {
			int x,y;cin>>x>>y;
			rooms.emplace_back(x,y);
		}
		for (int i = 0; i < N; ++i) {
			int x,y;cin>>x>>y;
			patient.emplace_back(x,y);
		}
		{
			Point center;
			int x,y;cin>>x>>y;
			center=Point(x,y);
			for (auto &p : rooms) {
				p-=center;
			}
			for (auto&p : patient) {
				p-=center;
			}
		}

		ld ans=2*pi;

		for (int i = 0; i < M; ++i) {
			Line l(rooms[i],rooms[(i+1)%M]);
			for (int j = 0; j < N; ++j) {
				Point p(patient[j]);
				Circle c(Point(0,0),abs(p));

				auto ps=is_sc(c,l);
				for (auto n : ps) {
					ld theta1=atan2l(p.imag(),p.real());
					ld theta2=atan2l(n.imag(),n.real());
					if(theta2<theta1)theta2+=2*pi;

					ans=min(ans,theta2-theta1);
				}
				

			}
		}
		for (int i = 0; i < N; ++i) {
			Line l(patient[i], patient[(i + 1) % N]);
			for (int j = 0; j < M; ++j) {
				Point p(rooms[j]);
				Circle c(Point(0, 0), abs(p));

				auto ps = is_sc(c, l);
				for (auto n : ps) {
					ld theta1 = atan2l(p.imag(), p.real());
					ld theta2 = atan2l(n.imag(), n.real());
					if (theta2<theta1)theta2 += 2 * pi;

					ans = min(ans, 2*pi-(theta2 - theta1));
				}


			}
		}
		cout<<ans/(2*pi)*360<<endl;
		
	}
	return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 3284
final_rank: 14

code_snippet: #include<bits/stdc++.h>
using namespace std;
 
const double PI=acos(-1);
const double PI2=PI*2.0;
const double eps=1e-10;
 
typedef complex<double> P;
typedef pair<P,P> S;
typedef pair<P,double> C;
typedef vector<P> vecP;
 
bool eq(double a,double b){
  return -eps<a-b&&a-b<eps;
}
 
double Sqrt(double x){
  if(x<0)return x;
  return sqrt(x);
}
 
P normal( P a ){
  return a/abs(a);
}
 
double dot(P a,P b){
  return real( b*conj(a) );
}
double cross(P a,P b){
  return imag( b*conj(a) );
}
double getArg(P a,P b){
  return arg(b*conj(a));
}
 
double getTime(P a,P b){
  return ( dot(a,b) < 0 ? -1.0 : 1.0)*abs(b)/abs(a);  
}
 
bool onSP(S s,P p){
  P a=s.first, b=s.second;
  return eq( abs(a-b) , abs(p-a)+abs(p-b) );
}
 
P project(P a,P b,P c){
  b-=a;c-=a;
  return a+b*real(c/b);
}
 
double getDistLP(S s,P p){
  P a=s.first, b=s.second;
  return abs( cross(b-a,p-a) / abs(b-a) );
}
 
double getDistSP(S s,P p){
  P a=s.first, b=s.second;
  if( dot(b-a,p-a) < eps )return abs(p-a);
  if( dot(a-b,p-b) < eps )return abs(p-b);
  return getDistLP(s,p);
}
 
bool isCrossCS(C c,S s){
  P a=s.first, b=s.second;
  double A=abs(c.second-a);
  double B=abs(c.second-b);
  double C=getDistSP(s,c.second);
  if( A < c.second+eps  && B < c.second+eps )return false;
  if( c.second+eps < C )return false;
  return true;
}
 
vecP getCrossCL(C cir,S line){
  P a=line.first, b=line.second;
  double cr=cir.second;
  P cp=cir.first;
  vecP res;
  P base=b-a, target=project(a,b,cp);
  double length=abs(base), h=abs(cp-target);
  base/=length;
 
  if(cr+eps<h)return res;
  double w=Sqrt(cr*cr-h*h);
  double L=getTime( normal(b-a), target-a) -w , R=L+w*2.0;
 
  res.push_back( a+ base * L );
  if(eq(L,R))return res;
  res.push_back( a+ base * R );
  return res;
}
 
vecP getCrossCS(C cir,S s){
  vecP tmp=getCrossCL(cir,s);
  vecP res;
  for(int i=0;i<(int)tmp.size();i++)
    if( onSP(s,tmp[i]) )
      res.push_back( tmp[i] );
 
  return res;
}
 
double calc(P cen,S a,P b){
  if( eq(abs(cen-b),0) )return 1e10;
   
  vecP tp=getCrossCS( C(cen, abs(cen-b) ) , a );
  double res=1e10;
   
  for(int i=0;i<(int)tp.size();i++){
    P p=tp[i];
    double value=getArg(b-cen,p-cen);
    if( value < 0 )value+=PI2;
    res=min(res,value);
  }
  return res;
}
 
double calc2(P cen,S a,P b){
  if( eq(abs(cen-b),0) )return 1e10;
   
  vecP tp=getCrossCS( C(cen, abs(cen-b) ) , a );
  double res=1e10;
   
  for(int i=0;i<(int)tp.size();i++){
    P p=tp[i];
    double value=getArg(b-cen,p-cen);
    if( value < 0 )value+=PI2;
    res=min(res,PI2-value);
  }
  return res;
}
 
double calc(P cen,S a,S b){
  double res=1e10;
  res=min(res,calc(cen,a,b.first));
  res=min(res,calc(cen,a,b.second));
  res=min(res,calc2(cen,b,a.first));
  res=min(res,calc2(cen,b,a.second));
  return res;
}
 
P input(){
  int x,y;
  cin>>x>>y;
  return P(x,y);
}
 
 
S getS(const vecP& polygon,int index){
  int n=polygon.size();
  index%=n;
  return S(polygon[index], polygon[ (index+1) % n ]);
}
 
int main(){
  int M,N;
  P cen;
  while(1){
    cin>>M>>N;
    if(M==0&&N==0)break;
    vecP inpol,outpol;
     
    for(int i=0;i<M;i++){
      inpol.push_back( input() );
    }
    for(int i=0;i<N;i++){
      outpol.push_back( input() );
    }
    cen=input();
 
    double ans=1e10;
    for(int i=0;i<M;i++){
      for(int j=0;j<N;j++){
        ans=min(ans, calc(cen, getS(inpol,i) , getS(outpol,j) ) );
      }
    }
    printf("%.10f\n", min(360.0,ans/PI*180.0) );
  }
  return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 3384
final_rank: 15

code_snippet: #include<bits/stdc++.h>
using namespace std;

const double PI=acos(-1);
const double PI2=PI*2.0;
const double eps=1e-10;

typedef complex<double> P;
typedef pair<P,P> S;
typedef pair<P,double> C;
typedef vector<P> vecP;

bool eq(double a,double b){
  return -eps<a-b&&a-b<eps;
}

double Sqrt(double x){
  if(x<0)return x;
  return sqrt(x);
}

P normal( P a ){
  return a/abs(a);
}

double dot(P a,P b){
  return real( b*conj(a) );
}
double cross(P a,P b){
  return imag( b*conj(a) );
}
double getArg(P a,P b){
  return arg(b*conj(a));
}

double getTime(P a,P b){
  return ( dot(a,b) < 0 ? -1.0 : 1.0)*abs(b)/abs(a);  
}

bool onSP(S s,P p){
  P a=s.first, b=s.second;
  return eq( abs(a-b) , abs(p-a)+abs(p-b) );
}

P project(P a,P b,P c){
  b-=a;c-=a;
  return a+b*real(c/b);
}

double getDistLP(S s,P p){
  P a=s.first, b=s.second;
  return abs( cross(b-a,p-a) / abs(b-a) );
}

double getDistSP(S s,P p){
  P a=s.first, b=s.second;
  if( dot(b-a,p-a) < eps )return abs(p-a);
  if( dot(a-b,p-b) < eps )return abs(p-b);
  return getDistLP(s,p);
}

bool isCrossCS(C c,S s){
  P a=s.first, b=s.second;
  double A=abs(c.second-a);
  double B=abs(c.second-b);
  double C=getDistSP(s,c.second);
  if( A < c.second+eps  && B < c.second+eps )return false;
  if( c.second+eps < C )return false;
  return true;
}

vecP getCrossCL(C cir,S line){
  P a=line.first, b=line.second;
  double cr=cir.second;
  P cp=cir.first;
  vecP res;
  P base=b-a, target=project(a,b,cp);
  double length=abs(base), h=abs(cp-target);
  base/=length;

  if(cr+eps<h)return res;
  double w=Sqrt(cr*cr-h*h);
  double L=getTime( normal(b-a), target-a) -w , R=L+w*2.0;

  res.push_back( a+ base * L );
  if(eq(L,R))return res;
  res.push_back( a+ base * R );
  return res;
}

vecP getCrossCS(C cir,S s){
  vecP tmp=getCrossCL(cir,s);
  vecP res;
  for(int i=0;i<(int)tmp.size();i++)
    if( onSP(s,tmp[i]) )
      res.push_back( tmp[i] );

  return res;
}

double calc(P cen,S a,P b){
  if( eq(abs(cen-b),0) )return 1e10;
  
  vecP tp=getCrossCS( C(cen, abs(cen-b) ) , a );
  double res=1e10;
  
  for(int i=0;i<(int)tp.size();i++){
    P p=tp[i];
    double value=getArg(b-cen,p-cen);
    if( value < 0 )value+=PI2;
    res=min(res,value);
  }
  return res;
}

double calc2(P cen,S a,P b){
  if( eq(abs(cen-b),0) )return 1e10;
  
  vecP tp=getCrossCS( C(cen, abs(cen-b) ) , a );
  double res=1e10;
  
  for(int i=0;i<(int)tp.size();i++){
    P p=tp[i];
    double value=getArg(b-cen,p-cen);
    if( value < 0 )value+=PI2;
    res=min(res,PI2-value);
  }
  return res;
}

double calc(P cen,S a,S b){
  double res=1e10;
  res=min(res,calc(cen,a,b.first));
  res=min(res,calc(cen,a,b.second));
  res=min(res,calc2(cen,b,a.first));
  res=min(res,calc2(cen,b,a.second));
  return res;
}

P input(){
  int x,y;
  cin>>x>>y;
  return P(x,y);
}


S getS(const vecP& polygon,int index){
  int n=polygon.size();
  index%=n;
  return S(polygon[index], polygon[ (index+1) % n ]);
}

int main(){
  int M,N;
  P cen;
  while(1){
    cin>>M>>N;
    if(M==0&&N==0)break;
    vecP inpol,outpol;
    
    for(int i=0;i<M;i++){
      inpol.push_back( input() );
    }
    for(int i=0;i<N;i++){
      outpol.push_back( input() );
    }
    cen=input();

    double ans=1e10;
    for(int i=0;i<M;i++){
      for(int j=0;j<N;j++){
        ans=min(ans, calc(cen, getS(inpol,i) , getS(outpol,j) ) );
      }
    }
    printf("%.10f\n", min(360.0,ans/PI*180.0) );
  }
  return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 3404
final_rank: 16

code_snippet: #include <algorithm>
#include <cassert>
#include <cctype>
#include <cstdio>
#include <complex>
#include <iostream>
#include <iomanip>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <bitset>
#include <stack>
#include <utility>
#include <numeric>
#include <functional>
#include <string>
#include <cstring>
#include <sstream>
// #include <tuple>
// #include <regex>
 
using namespace std;
typedef long long ll;
 
#define ALL(c) (c).begin(),(c).end()
#define REP(i,n) for(int i=0;i<(int)(n);++i)
#define EACH(i,c) for(auto i=(c).begin(); i!=(c).end(); ++i)
#define IN(l,v,r) ((l)<=(v) && (v)<(r))
 
 
typedef long double D;
const D EPS = 1e-8,INF = 1e12;
 
template<typename T> int sig(T a,T b=0){return a<b-EPS?-1:a>b+EPS?1:0;}
template<typename T> bool eq(T a,T b){ return sig(abs(a-b))==0;}
template<typename T> D norm(T a){ return a*a;}
 
typedef complex<D> P,Vec;
#define X real()
#define Y imag()
 
bool debug = false;
 
 
namespace std{
    bool operator < (const P& a,const P& b){
            return a.X != b.X ? a.X < b.X : a.Y < b.Y;
    }
    bool operator == (const P& a,const P& b){
            return eq(a,b);
    }
};
 
// a×b
D cross(const Vec& a,const Vec& b){
    return imag(conj(a)*b);
}
// a・b
D dot(const Vec& a,const Vec& b) {
    return real(conj(a)*b);
}
//射影ベクトル
Vec proj(Vec p,Vec b) {
    return b * dot(p,b) / norm(b);
}
 
//直線・線分
struct L : public vector<P> {
    L(const P &a, const P &b) {
        push_back(a); push_back(b);
     }
};
 
//直線へ射影した時の点
P projection(const L &l, const P &p) {
    return l[0] + proj(p-l[0],l[1]-l[0]);
}
 
D distanceLP(const L &l, const P &p) {
    return abs(p - projection(l, p));
}
 
struct C {
    P o; D r;
    C(const P &o,D r) : o(o), r(r) { }
};
 
vector<P> intersectionLC(L l,C c){
    D d = distanceLP(l,c.o);
    vector <P> res;
    if(eq(d,c.r)){
        res.push_back(projection(l,c.o));
    }else if(sig(d,c.r)<0){
        P m = projection(l,c.o),u = (l[1]-l[0])/abs(l[1]-l[0]);
        D t = sqrt(c.r*c.r - d*d);
        res.push_back( m + t * u);res.push_back( m - t * u);
    }
    return res;
}
 
int ccw(const P& a,P b,P c){
		b -= a; c -= a;
		if (sig(cross(b,c))>0)   return +1;       // counter clockwise
		if (sig(cross(b,c))<0)   return -1;       // clockwise
		if (sig(dot(b,c)) < 0)     return +2;       // c--a--b on line
		if (sig(norm(b),norm(c))<0) return -2;       // a--b--c on line
		return 0;
	}
 
vector<P> intersectionSC(L l,C c){
    vector<P> ps=intersectionLC(l,c),res;
    REP(i,ps.size()){
        if(ccw(ps[i],l[0],l[1])==+2 || ccw(ps[i],l[1],l[0])==+2){
            res.push_back(ps[i]);
        }
    }
    return res;
}
 
//浮動小数点modで非負の値のみかえす．
D pfmod(D v,D M=2*M_PI){
    return fmod(fmod(v,M)+M,M);
}
 
int main(){
    cout <<fixed <<setprecision(20);
    cerr <<fixed <<setprecision(20);
 
    while(true){
        int m,n;cin >> m >> n;
        if(m==0 && n==0)break;
 
        vector<P> ps(m);
        REP(i,m){
            D x,y;cin >>x >> y;ps[i]=P(x,y); 
        }
        vector<P> qs(n);
        REP(i,n){
            D x,y;cin >>x >> y;qs[i]=P(x,y); 
        }
        P c;
        {
            D x,y;cin >>x >> y;c=P(x,y); 
        }
 
        D ma = 2 * M_PI;
        REP(i,m){
            C ic(c,abs(ps[i]-c));
            REP(j,n){
                L l(qs[j],qs[(j+1)%n]);
                vector<P> ip=intersectionSC(l,ic);
                REP(k,ip.size()){
                    D a=pfmod(arg(ps[i]-c)-arg(ip[k]-c));
                    ma=min(ma,a);
                }
            }
        }
        REP(j,n){
            C ic(c,abs(qs[j]-c));
            REP(i,m){
                L l(ps[i],ps[(i+1)%m]);
                vector<P> ip=intersectionSC(l,ic);
                REP(k,ip.size()){
                    D a=pfmod(arg(ip[k]-c)-arg(qs[j]-c));
                    ma=min(ma,a);
                }
            }
        }
 
        cout << ma * 360.0/(2*M_PI)<<endl;
    }
 
 
    return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 1320
final_rank: 6

code_snippet: #include <algorithm>
#include <cassert>
#include <cctype>
#include <cstdio>
#include <complex>
#include <iostream>
#include <iomanip>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <bitset>
#include <stack>
#include <utility>
#include <numeric>
#include <functional>
#include <string>
#include <cstring>
#include <sstream>
// #include <tuple>
// #include <regex>

using namespace std;
typedef long long ll;

#define ALL(c) (c).begin(),(c).end()
#define REP(i,n) for(int i=0;i<(int)(n);++i)
#define EACH(i,c) for(auto i=(c).begin(); i!=(c).end(); ++i)
#define IN(l,v,r) ((l)<=(v) && (v)<(r))


typedef long double D;
const D EPS = 1e-8,INF = 1e12;

template<typename T> int sig(T a,T b=0){return a<b-EPS?-1:a>b+EPS?1:0;}
template<typename T> bool eq(T a,T b){ return sig(abs(a-b))==0;}
template<typename T> D norm(T a){ return a*a;}

typedef complex<D> P,Vec;
#define X real()
#define Y imag()

bool debug = false;


namespace std{
	bool operator < (const P& a,const P& b){
    		return a.X != b.X ? a.X < b.X : a.Y < b.Y;
  	}
  	bool operator == (const P& a,const P& b){
    		return eq(a,b);
   	}
};

// a×b
D cross(const Vec& a,const Vec& b){
	return imag(conj(a)*b);
}
// a・b
D dot(const Vec& a,const Vec& b) {
	return real(conj(a)*b);
}
//射影ベクトル
Vec proj(Vec p,Vec b) {
	return b * dot(p,b) / norm(b);
}

//直線・線分
struct L : public vector<P> {
	L(const P &a, const P &b) {
	  	push_back(a); push_back(b);
	 }
};

//直線へ射影した時の点
P projection(const L &l, const P &p) {
	return l[0] + proj(p-l[0],l[1]-l[0]);
}

D distanceLP(const L &l, const P &p) {
	return abs(p - projection(l, p));
}

struct C {
 	P o; D r;
 	C(const P &o,D r) : o(o), r(r) { }
};

vector<P> intersectionLC(L l,C c){
	D d = distanceLP(l,c.o);
	vector <P> res;
 	if(eq(d,c.r)){
		res.push_back(projection(l,c.o));
	}else if(sig(d,c.r)<0){
		P m = projection(l,c.o),u = (l[1]-l[0])/abs(l[1]-l[0]);
	 	D t = sqrt(c.r*c.r - d*d);
		res.push_back( m + t * u);res.push_back( m - t * u);
	}
	return res;
}

int ccw(const P& a,P b,P c){
	b -= a; c -= a;
	if (cross(b,c) > EPS)   return +1;      	// counter clockwise
	if (cross(b,c) < -EPS)   return -1;      	// clockwise
	if (dot(b,c) < 0)     return +2;        // c--a--b on line
	if (norm(b) < norm(c)) return -2;       // a--b--c on line
	return 0; 								// a--c--b on line (or b==c)
}

vector<P> intersectionSC(L l,C c){
	vector<P> ps=intersectionLC(l,c),res;
	REP(i,ps.size()){
		if(ccw(ps[i],l[0],l[1])==+2 || ccw(ps[i],l[1],l[0])==+2){
			res.push_back(ps[i]);
		}
	}
	return res;
}

//浮動小数点modで非負の値のみかえす．
D pfmod(D v,D M=2*M_PI){
	return fmod(fmod(v,M)+M,M);
}

int main(){
	cout <<fixed <<setprecision(20);
	cerr <<fixed <<setprecision(20);

	while(true){
		int m,n;cin >> m >> n;
		if(m==0 && n==0)break;

		vector<P> ps(m);
		REP(i,m){
			D x,y;cin >>x >> y;ps[i]=P(x,y); 
		}
		vector<P> qs(n);
		REP(i,n){
			D x,y;cin >>x >> y;qs[i]=P(x,y); 
		}
		P c;
		{
			D x,y;cin >>x >> y;c=P(x,y); 
		}

		D ma = 2 * M_PI;
		REP(i,m){
			C ic(c,abs(ps[i]-c));
			REP(j,n){
				L l(qs[j],qs[(j+1)%n]);
				vector<P> ip=intersectionSC(l,ic);
				REP(k,ip.size()){
					D a=pfmod(arg(ps[i]-c)-arg(ip[k]-c));
					ma=min(ma,a);
				}
			}
		}
		REP(j,n){
			C ic(c,abs(qs[j]-c));
			REP(i,m){
				L l(ps[i],ps[(i+1)%m]);
				vector<P> ip=intersectionSC(l,ic);
				REP(k,ip.size()){
					D a=pfmod(arg(ip[k]-c)-arg(qs[j]-c));
					ma=min(ma,a);
				}
			}
		}

		cout << ma * 360.0/(2*M_PI)<<endl;
	}


	return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 1320
final_rank: 6

code_snippet: #include <algorithm>
#include <cassert>
#include <cctype>
#include <cstdio>
#include <complex>
#include <iostream>
#include <iomanip>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <bitset>
#include <stack>
#include <utility>
#include <numeric>
#include <functional>
#include <string>
#include <cstring>
#include <sstream>
// #include <tuple>
// #include <regex>

using namespace std;
typedef long long ll;

#define ALL(c) (c).begin(),(c).end()
#define REP(i,n) for(int i=0;i<(int)(n);++i)
#define EACH(i,c) for(auto i=(c).begin(); i!=(c).end(); ++i)
#define IN(l,v,r) ((l)<=(v) && (v)<(r))


typedef long double D;
const D EPS = 1e-8,INF = 1e12;

template<typename T> int sig(T a,T b=0){return a<b-EPS?-1:a>b+EPS?1:0;}
template<typename T> bool eq(T a,T b){ return sig(abs(a-b))==0;}
template<typename T> D norm(T a){ return a*a;}

typedef complex<D> P,Vec;
#define X real()
#define Y imag()

bool debug = false;


namespace std{
	bool operator < (const P& a,const P& b){
    		return a.X != b.X ? a.X < b.X : a.Y < b.Y;
  	}
  	bool operator == (const P& a,const P& b){
    		return eq(a,b);
   	}
};

// a×b
D cross(const Vec& a,const Vec& b){
	return imag(conj(a)*b);
}
// a・b
D dot(const Vec& a,const Vec& b) {
	return real(conj(a)*b);
}
//射影ベクトル
Vec proj(Vec p,Vec b) {
	return b * dot(p,b) / norm(b);
}

//直線・線分
struct L : public vector<P> {
	L(const P &a, const P &b) {
	  	push_back(a); push_back(b);
	 }
};

//直線へ射影した時の点
P projection(const L &l, const P &p) {
	return l[0] + proj(p-l[0],l[1]-l[0]);
}

D distanceLP(const L &l, const P &p) {
	return abs(p - projection(l, p));
}

struct C {
 	P o; D r;
 	C(const P &o,D r) : o(o), r(r) { }
};

vector<P> intersectionLC(L l,C c){
	D d = distanceLP(l,c.o);
	vector <P> res;
 	if(eq(d,c.r)){
		res.push_back(projection(l,c.o));
	}else if(sig(d,c.r)<0){
		P m = projection(l,c.o),u = (l[1]-l[0])/abs(l[1]-l[0]);
	 	D t = sqrt(c.r*c.r - d*d);
		res.push_back( m + t * u);res.push_back( m - t * u);
	}
	return res;
}


int ccw(const P& a,P b,P c){
	b -= a; c -= a;
	if (cross(b,c) > EPS)   return +1;      	// counter clockwise
	if (cross(b,c) < -EPS)   return -1;      	// clockwise
	if (dot(b,c) < 0)     return +2;        // c--a--b on line
	if (norm(b) < norm(c)) return -2;       // a--b--c on line
	return 0; 								// a--c--b on line (or b==c)
}

vector<P> intersectionSC(L l,C c){
	vector<P> ps=intersectionLC(l,c),res;
	// if(debug){
	// 	REP(i,ps.size()){
	// 		cerr <<ps[i]<<endl;
	// 	}
	// }
	REP(i,ps.size()){
		// cerr << ccw(ps[i],l[0],l[1])<<endl;
		// cerr << ccw(ps[i],l[1],l[0])<<endl;
		if(ccw(ps[i],l[0],l[1])==+2 || ccw(ps[i],l[1],l[0])==+2){
			res.push_back(ps[i]);
		}
	}
	return res;
}

//浮動小数点modで非負の値のみかえす．
D pfmod(D v,D M=2*M_PI){
	return fmod(fmod(v,M)+M,M);
}

int main(){
	cout <<fixed <<setprecision(20);
	cerr <<fixed <<setprecision(20);

	while(true){
		int m,n;cin >> m >> n;
		if(m==0 && n==0)break;

		vector<P> ps(m);
		REP(i,m){
			D x,y;cin >>x >> y;ps[i]=P(x,y); 
		}
		vector<P> qs(n);
		REP(i,n){
			D x,y;cin >>x >> y;qs[i]=P(x,y); 
		}
		P c;
		{
			D x,y;cin >>x >> y;c=P(x,y); 
		}

		D ma = 2 * M_PI;
		REP(i,m){
			C ic(c,abs(ps[i]-c));
			REP(j,n){
				if(i==4 && j==2)debug=true;
				L l(qs[j],qs[(j+1)%n]);
				vector<P> ip=intersectionSC(l,ic);

				// if(i==4 && j==2){
				// 	cerr << i <<" " <<j <<endl;
				// 	cerr << c<<" "<<ps[i] << endl;				
				// 	cerr << abs(ps[i]-c)<<endl;
				// 	cerr << l[0]<<" "<<l[1]<<endl;	
				// 	cerr <<"--"<<endl;			
				// 	REP(k,ip.size())cerr << ip[k]<<endl;
				// }
				REP(k,ip.size()){
					D a=pfmod(arg(ps[i]-c)-arg(ip[k]-c));
	//				cerr << a <<endl;
					ma=min(ma,a);
				}

				// cerr << ma<<endl;
				// cerr <<endl;
				// if(i==4 && j==2)debug=false;
			}
		}
		REP(j,n){
			C ic(c,abs(qs[j]-c));
			REP(i,m){
				// if(i==4 && j==2)debug=true;
				L l(ps[i],ps[(i+1)%m]);
				vector<P> ip=intersectionSC(l,ic);

				// if(i==4 && j==2){
				// 	cerr << i <<" " <<j <<endl;
				// 	cerr << c<<" "<<ps[i] << endl;				
				// 	cerr << abs(ps[i]-c)<<endl;
				// 	cerr << l[0]<<" "<<l[1]<<endl;	
				// 	cerr <<"--"<<endl;			
				// 	REP(k,ip.size())cerr << ip[k]<<endl;
				// }
				
				REP(k,ip.size()){
					D a=pfmod(arg(ip[k]-c)-arg(qs[j]-c));
					ma=min(ma,a);
				}

				// cerr << ma<<endl;
				// cerr <<endl;

				// if(i==4 && j==2)debug=false;
			}
		}

		cout << ma * 360.0/(2*M_PI)<<endl;
	}


	return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 1320
final_rank: 6

code_snippet: #include<bits/stdc++.h>

#define REP(i,s,n) for(int i=s;i<n;i++)
#define rep(i,n) REP(i,0,n)
#define EPS (1e-8) 
#define equals(a,b) (fabs((a)-(b))<EPS)

using namespace std;

static const int COUNTER_CLOCKWISE = 1;
static const int CLOCKWISE = -1;
static const int ONLINE_BACK = 2;
static const int ONLINE_FRONT = -2;
static const int ON_SEGMENT = 0;

class Point{
public:
  double x,y;

  Point(double x = 0,double y = 0): x(x),y(y){}

  Point operator + (Point p){return Point(x+p.x,y+p.y);}
  Point operator - (Point p){return Point(x-p.x,y-p.y);}
  Point operator * (double a){return Point(a*x,a*y);}
  Point operator / (double a){return Point(x/a,y/a);}
  Point operator * (Point a){ return Point(x * a.x - y * a.y, x * a.y + y * a.x); }

  bool operator < (const Point& p) const{ return !equals(x,p.x)?x<p.x:(!equals(y,p.y)&&y<p.y); }

  bool operator == (const Point& p)const{ return fabs(x-p.x) < EPS && fabs(y-p.y) < EPS; }

};

struct Segment{
  Point p1,p2;
  Segment(Point p1 = Point(),Point p2 = Point()):p1(p1),p2(p2){}
 bool operator == (const Segment& p)const { return ( p.p1 == p1 && p.p2 == p2 ) || ( p.p1 == p2 && p.p2 == p1 ); }
};

typedef Point Vector;
typedef Segment Line;
typedef vector<Point> Polygon;

ostream& operator << (ostream& os,const Point& a){ os << "(" << a.x << "," << a.y << ")"; }

ostream& operator << (ostream& os,const Segment& a){ os << "( " << a.p1 << " , " << a.p2 << " )"; }

double dot(Point a,Point b){ return a.x*b.x + a.y*b.y; }

double cross(Point a,Point b){ return a.x*b.y - a.y*b.x; }

double norm(Point a){ return a.x*a.x+a.y*a.y; }

double abs(Point a){ return sqrt(norm(a)); }

//rad は角度をラジアンで持たせること
Point rotate(Point a,double rad){ return Point(cos(rad)*a.x - sin(rad)*a.y,sin(rad)*a.x + cos(rad)*a.y); }

// 度をラジアンに変換
double toRad(double agl){ return agl*M_PI/180.0; }

// a => prev, b => cur, c=> next
// prev から cur へ行って next へ行く際の角度を求める
double getArg(Point a,Point b,Point c){
  double arg1 = atan2(b.y-a.y,b.x-a.x);
  double arg2 = atan2(c.y-b.y,c.x-b.x);
  double arg = fabs( arg1 - arg2 );
  while( arg > M_PI ) arg -= 2.0 * M_PI;
  return fabs(arg);
}

int ccw(Point p0,Point p1,Point p2){
  Point a = p1-p0;
  Point b = p2-p0;
  if(cross(a,b) > EPS)return COUNTER_CLOCKWISE;
  if(cross(a,b) < -EPS)return CLOCKWISE;
  if(dot(a,b) < -EPS)return ONLINE_BACK;
  if(norm(a) < norm(b))return ONLINE_FRONT;
  return ON_SEGMENT;
}

// p0 を p1 を基準に時計回りで回した時の p2 までの角度
double ccw_angle(Point p0,Point p1,Point p2){
  double ret = M_PI - getArg(p0,p1,p2);
  //cout << ret * 180 / M_PI << endl;
  if( ccw(p1,p0,p2) == COUNTER_CLOCKWISE ) ret = 2*M_PI - ret;
    return ret;
}


double cross3p(Point p,Point q,Point r) { return (r.x-q.x) * (p.y -q.y) - (r.y - q.y) * (p.x - q.x); }
  
bool collinear(Point p,Point q,Point r) { return fabs(cross3p(p,q,r)) < EPS; }
  
bool ccwtest(Point p,Point q,Point r)   { return cross3p(p,q,r) > 0; }
 
bool onSegment(Point p,Point q,Point r) { return collinear(p,q,r) && equals(sqrt(pow(p.x-r.x,2)+pow(p.y-r.y,2)) + sqrt(pow(r.x-q.x,2) + pow(r.y-q.y,2) ),sqrt(pow(p.x-q.x,2)+pow(p.y-q.y,2)) ) ; }


typedef pair<double,double> dd;
const double DINF = 1e20;
#define pow2(a) ((a)*(a))
bool LT(double a ,double b){ return !equals(a,b) && a < b; }
bool LTE(double a,double b){ return  equals(a,b) || a < b; }

dd calc(double x1,double y1,double vx1,double vy1,
        double x2,double y2,double vx2,double vy2,double r){
  double VX = (vx1-vx2), X = (x1-x2), VY = (vy1-vy2), Y = (y1-y2);
  double a = pow2(VX) + pow2(VY), b = 2*(X*VX+Y*VY), c = pow2(X) + pow2(Y) - pow2(r);
  dd ret = dd(DINF,DINF);
  double D = b*b - 4 * a * c;

  if( LT(D,0.0) ) return ret;

  if( equals(a,0.0) ) {
    if( equals(b,0.0) ) return ret;
    if( LT(-c/b,0.0)  ) return ret;
    ret.first = - c / b;
    return ret;
  }

  if( equals(D,0.0) ) D = 0;
  ret.first  = ( -b - sqrt( D ) ) / ( 2 * a );
  ret.second = ( -b + sqrt( D ) ) / ( 2 * a );
  if( !equals(ret.first,ret.second) && ret.first > ret.second ) swap(ret.first,ret.second);
  return ret;
}


Point c;
Polygon poly,qoly;

// type => 0 : CW, type => 1 : CCW
double calc(Polygon &A,Polygon &B,int type){
  double ret = DINF;
  rep(i,A.size()){
    double cost = DINF;
    rep(j,B.size()){
      Vector e = ( B[j] - B[(j+1)%(int)B.size()] ) / abs( B[j] - B[(j+1)%(int)B.size()] );
      dd tmp = calc(c.x,c.y,0,0,
                    B[j].x,B[j].y,e.x,e.y,abs(A[i]-c));
      vector<Point> vp;
      if( !equals(tmp.first ,DINF) ) vp.push_back(B[j]+e*tmp.first);
      if( !equals(tmp.second,DINF) ) vp.push_back(B[j]+e*tmp.second);
      rep(k,vp.size()) if( onSegment(B[j],B[(j+1)%(int)B.size()],vp[k]) ) {
        double theta = ccw_angle(A[i],c,vp[k]);
        cost = min(cost,(!type?theta:2*M_PI-theta));
      }
    }
    ret = min(ret,cost);
  }
  return ret;
}

void compute(){
  double mini = min(calc(poly,qoly,0),calc(qoly,poly,1));
  if( equals(mini,DINF) ) puts("360.0000000");
  else                    printf("%.10lf\n",mini * 180.0 / M_PI); 
}

int main(){
  int M,N;
  while( cin >> M >> N, M|N ){
    poly.resize(M); qoly.resize(N);
    rep(i,M) cin >> poly[i].x >> poly[i].y;
    rep(i,N) cin >> qoly[i].x >> qoly[i].y;
    cin >> c.x >> c.y;
    compute();
  }
  return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 1348
final_rank: 11

code_snippet: #include <iostream>
#include <cstdio>
#include <cassert>
#include <algorithm>
#include <complex>
#include <vector>
#include <cmath>
using namespace std;

#define EPS 1e-7
#define INF 360
#define PI M_PI


int N, M;

typedef complex<double> Point;

namespace std{
	bool operator < (const Point &a, const Point &b){
		return real(a) != real(b) ? real(a) < real(b) : imag(a) < imag(b);
	}
	Point operator / (const Point &p, const double &a){
		return Point(real(p)/a, imag(p)/a);
	}
	Point operator * (const Point &p, const double &a){
		return Point(real(p) * a, imag(p)*a);
	}
	bool operator == (const Point &a, const Point &b){
		return real(a) == real(b) && imag(a) == imag(b);
	}
}
typedef vector<Point> Polygon;
struct Line : public vector<Point>{
	Line(){}
	Line (const Point &a, const Point &b){
		push_back(a); push_back(b);
	}
};
struct Circle{
	Point c; double r;
	Circle(){}
	Circle(const Point &c, double r) : c(c), r(r){}
};

double distancePP(const Point &a, const Point &b){
	return sqrt((real(a)-real(b))*(real(a)-real(b)) + (imag(a)-imag(b))*(imag(a)-imag(b)));
}

double cross(const Point &a, const Point &b){
	return imag(conj(a)*b);
}

double dot(const Point &a, const Point &b){
 return real(conj(a) * b);
}

Point projection(const Line &l, const Point &p){
	double t = dot(p-l[0], l[0] - l[1]) / norm(l[0]-l[1]);
	return l[0] + t*(l[0]-l[1]);
}

vector<Point> crosspointLC(const Line &l, const Circle &c){
	vector<Point> ret;
	Point center = projection(l, c.c);
	double d = abs(center - c.c);
	double t = sqrt(c.r * c.r - d*d);
	if(isnan(t)) return ret;
	Point vect = (l[1] - l[0]);
	vect /= abs(vect);
	ret.push_back(center - vect*t);
	ret.push_back(center + vect * t);
	return ret;
}

bool is_point_on_line(Point a, Point b, Point c) {
	return abs(b-a) + EPS > max(abs(c-a), abs(c-b));
}

double calc(const Point &a, const Point &b, const Point &pp){
	double ta = arg(a-pp);
	double tb = arg(b-pp);
	while (tb < ta + EPS) {
		tb += 2 * M_PI;
	}
	return ((tb - ta)*180/PI);
}

double calc2(const Point &a, const Point &b, const Point &pp){
	double tb = arg(a-pp);
	double ta = arg(b-pp);
	while (tb < ta + EPS) {
		tb += 2 * M_PI;
	}
	return ((tb - ta)*180/PI);
}



int main(void){
	double cx, cy;
	while(cin>>M>>N, M || N){
		Polygon out, in;
		
		for(int i = 0; i < M; i++){
			double x, y;
			cin >> x >> y;
			out.push_back(Point(x, y));
		}
		for(int i = 0; i < N; i++){
			double x, y;
			cin >> x >> y;
			in.push_back(Point(x,y));
		}
		cin >> cx >> cy;
		double min_ans = INF;
		for(int i = 0; i < in.size(); i++){
			Point pp = Point(cx, cy);
			Circle c = Circle(pp, distancePP(pp, in[i]));
			for(int j = 0; j < out.size(); j++){
				Line l = Line(out[(j+1)%out.size()], out[j]);
				vector<Point> cp = crosspointLC(l, c);
				if(cp.empty()) continue;
				double c1 = 360, c2 = 360;
/*
cout << real(in[i]) << ":" << imag(in[i]) << " and "<< real(out[j]) << ":" << imag(out[j]) << " to "<< real(out[j+1]) << ":" << imag(out[j+1])<< endl;
cout << real(cp[0]) << ":" << imag(cp[0]) << " and "<< real(cp[1]) << ":" << imag(cp[1]) << endl;
*/
				if(is_point_on_line(out[(j+1)%out.size()], out[j], cp[0]))
					c1 = calc(in[i], cp[0], pp);
				if(is_point_on_line(out[(j+1)%out.size()], out[j], cp[1]))
					c2 = calc(in[i], cp[1], pp);
//cout << ":" << c1 << " : " << c2 << " : " << min_ans << endl;
				min_ans = min(min_ans, min(c1, c2));
			}
		}
		swap(in, out);
		for(int i = 0; i < in.size(); i++){
			Point pp = Point(cx, cy);
			Circle c = Circle(pp, distancePP(pp, in[i]));
			for(int j = 0; j < out.size(); j++){
				Line l = Line(out[(j+1)%out.size()], out[j]);
				vector<Point> cp = crosspointLC(l, c);
				if(cp.empty()) continue;
				double c1 = 360, c2 = 360;
				if(is_point_on_line(out[(j+1)%out.size()], out[j], cp[0]))
					c1 = calc2(in[i], cp[0], pp);
				if(is_point_on_line(out[(j+1)%out.size()], out[j], cp[1]))
					c2 = calc2(in[i], cp[1], pp);
				min_ans = min(min_ans, min(c1, c2));
			}
		}


		printf("%.9lf\n", min_ans);
	}
	
	
	return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 1356
final_rank: 13

code_snippet: #include <bits/stdc++.h>
#define REP(i,n) for(int i=0; i<(int)(n); ++i)

using namespace std;
typedef complex<double> Point;
const double EPS = 1e-6;
double dot(Point a, Point b){
    return real(conj(a) * b);
}
double cross(Point a, Point b){
    return imag(conj(a) * b);
}
int ccw(Point a, Point b, Point c) {
    b -= a; c -= a;
    double len = abs(b) * abs(c); // 速さが気になるときは1にする
    if (cross(b, c) > +len * EPS)   return +1; // 反時計回り
    if (cross(b, c) < -len * EPS)   return -1; // 時計回り
    if (dot(b, c) < 0)     return +2; // c--a--b の順番で一直線上
    if (norm(b) < norm(c)) return -2; // a--b--c の順番で一直線上
    return 0;                         // 点が線分ab上にある
}

double angle(Point a, Point b){
    double res = arg(conj(a) * b);
    if(res < 0) res += 2 * M_PI;
    return res;
}

struct Line : public vector<Point> {
    Line(const Point& a, const Point& b) {
        push_back(a); push_back(b);
    }
    Point vector() const {
        return back() - front();
    }
};
struct Circle {
    Point p;
    double r;
    Circle() {}
    Circle(Point p, double r) : p(p), r(r) { }
};
bool intersectSP(Line s, Point p) {
    return ccw(s[0], s[1], p) == 0;
}

Point projection(Line l, Point p){
    double t = dot(p - l[0], l.vector()) / norm(l.vector());
    return l[0] + t * l.vector();
}

vector<Point> crosspointLC(const Line &l, const Circle &c) {
    vector<Point> res;
    Point center = projection(l, c.p);
    double d = abs(center - c.p);
    double tt = c.r * c.r - d * d;
    if(tt < 0 && tt > -EPS) tt = 0;
    if(tt < 0) return res;
    double t = sqrt(tt);
    Point vect = l.vector();
    vect /= abs(vect);
    res.push_back(center - vect * t);
    if (t > EPS) {
        res.push_back(center + vect * t);
    }
    return res;
}

vector<Point> crosspointSC(const Line &s, const Circle &c) {
    vector<Point> ret;
    vector<Point> nret = crosspointLC(s, c);
    for (int i = 0; i < nret.size(); i++) {
        if (intersectSP(s, nret[i])) ret.push_back(nret[i]);
    }
    return ret;
}

int main(){
    int M, N;
    while(cin >> M >> N && M){
        vector<Point> ps(M);
        vector<Point> qs(N);
        REP(i, M){
            double x, y;
            cin >> x >> y;
            ps[i] = Point(x, y);
        }
        REP(i, N){
            double x, y;
            cin >> x >> y;
            qs[i] = Point(x, y);
        }
        double cx, cy;
        cin >> cx >> cy;
        Point cp(cx, cy);
        double ans = 2.0 * M_PI;
        for(int i = 0; i < N; i++){
            Circle C(cp, abs(qs[i] - cp)); // qs[i]の軌道
            for(int j = 0; j < M; j++){
                Line s(ps[j], ps[(j == M - 1 ? 0 : j + 1)]);
                vector<Point> crosspv = crosspointSC(s, C);
                for(Point crossp : crosspv){
                    //cout << "Circle : " << C.p << " " << C.r << " cross with " << s[0] << " " << s[1] << " at " << crossp << endl;
                    ///cout << "angle : " << angle(qs[i] - cp, crossp - cp) << endl;
                    ans = min(ans, angle(qs[i] - cp, crossp - cp));
                }
            }
        }
        for(int i = 0; i < M; i++){
            Circle C(cp, abs(ps[i] - cp)); // ps[i]の軌道
            for(int j = 0; j < N; j++){
                Line s(qs[j], qs[(j == N - 1 ? 0 : j + 1)]);
                vector<Point> crosspv = crosspointSC(s, C);
                for(Point crossp : crosspv){
                    //cout << "Circle : " << C.p << " " << C.r << " cross with " << s[0] << " " << s[1] << " at " << crossp << endl;
                    //cout << "angle : " << angle(crossp - cp, ps[i] - cp) << endl;
                    ans = min(ans, angle(crossp - cp, ps[i] - cp));
                }
            }
        }
        printf("%.7f\n", ans / M_PI * 180.0);
    }
    return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 1336
final_rank: 10

code_snippet: #include <iostream>
#include <algorithm>
#include <complex>
#include <cmath>
#include <cstdio>
#include <vector>
using namespace std;

typedef complex<double> P;
typedef pair<P,P> L;

const double EPS = 1e-8;

struct C{
  P c;
  double r;
  C(P c=P(0,0), double r=0.0):c(c),r(r){}
};

double dot(P a, P b){return real(conj(a)*b);}
double cross(P a, P b){return imag(conj(a)*b);}
bool equal(double a, double b){return fabs(a-b) < EPS;}

P proj(P p, L l){
  return l.first + dot(p - l.first, l.second - l.first) / norm(l.second - l.first) * (l.second - l.first);
}

bool isInterSP(L s, P p){
  if(dot(s.second - s.first, p - s.first) < -EPS) return equal(0.0, abs(p-s.first));
  if(dot(s.first - s.second, p - s.second) < - EPS) return equal(0.0, abs(p-s.second));
  return equal(0.0, abs(cross(s.second - s.first, p - s.first) / abs(s.second - s.first)));
}

vector<P> getInterCS(C c, L s){
  vector<P> res;
  P h = proj(c.c, s);
  double d = abs(c.c - h);
  if(d > c.r + EPS);
  else if(d > c.r - EPS){
    if(isInterSP(s, h)) res.push_back(h);
  } else {
    P v = s.second - s.first;
    v = (sqrt(c.r*c.r - d*d) / abs(v)) * v;
    if(isInterSP(s, h+v)) res.push_back(h+v);
    if(isInterSP(s, h-v)) res.push_back(h-v);
  }
  return res;
}

int n,m;
vector<P> v[2];
P ce;

double calc(P a, P b1, P b2){
  double res = arg(b2-a) - arg(b1-a);
  res *= 180.0 / M_PI;
  while(res < 0) res += 360.0;
  while(res > 360.0) res -= 360.0;
  return res;
}

void solve(){
  double ans = 360.0;
  for(int i=0;i<m;i++){
    C c = C(ce, abs(ce-v[1][i]));
    for(int j=0;j<n;j++){
      L l = L(v[0][j], v[0][(j+1)%n]);
      vector<P> cp = getInterCS(c, l);
      for(int k=0;k<cp.size();k++)
	ans = min(ans, calc(ce, v[1][i], cp[k]));
    }
  }

  for(int i=0;i<n;i++){
    C c = C(ce, abs(ce-v[0][i]));
    for(int j=0;j<m;j++){
      L l = L(v[1][j], v[1][(j+1)%m]);
      vector<P> cp = getInterCS(c, l);
      for(int k=0;k<cp.size();k++)
	ans = min(ans, calc(ce, cp[k], v[0][i]));
    }
  }


  printf("%.7f\n",ans);
}

int main(){
  while(cin >> n >> m && (n|m)){
    double x,y;
    for(int i=0;i<2;i++) v[i].clear();
    for(int i=0;i<n;i++){
      cin >> x >> y;
      v[0].push_back(P(x,y));
    }
    for(int i=0;i<m;i++){
      cin >> x >> y;
      v[1].push_back(P(x,y));
    }
    cin >> x >> y;
    ce = P(x,y);
    solve();
  }
}
accuracy: 1
time_ms: 10
memory_kb: 1352
final_rank: 9

code_snippet: #include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <complex>
#include <cstring>
#include <cstdlib>
#include <string>
#include <cmath>
#include <cassert>
#include <queue>
#include <set>
#include <map>
#include <valarray>
#include <bitset>
#include <stack>
using namespace std;

#define REP(i,n) for(int i=0;i<(int)n;++i)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)
#define ALL(c) (c).begin(), (c).end()
#define chmax(a,b) (a<(b)?(a=b,1):0)
#define chmin(a,b) (a>(b)?(a=b,1):0)
#define valid(y,x,h,w) (0<=y&&y<h&&0<=x&&x<w)
const int INF = 1<<29;
const double EPS = 1e-8;
const double PI = acos(-1);
typedef pair<int,int> pii;
typedef long long ll;


typedef complex<double> P;
namespace std {
  bool operator < (const P& a, const P& b) {
    // if (abs(a-b)<EPS) return 0;
    return real(a) != real(b) ? real(a) < real(b) : imag(a) < imag(b);
  }
}
double cross(const P& a, const P& b) {
  return imag(conj(a)*b);
}
double dot(const P& a, const P& b) {
  return real(conj(a)*b);
}
struct L : public vector<P> {
  L(const P &a, const P &b) {
    push_back(a); push_back(b);
  }
  L() {}
};
typedef vector<P> G;
#define curr(P, i) P[i]
#define next(P, i) P[(i+1)%P.size()]
struct C {
  P p; double r;
  C(const P &p, double r) : p(p), r(r) { }
};

int ccw(P a, P b, P c) {
  b -= a; c -= a;
  if (cross(b, c) > EPS)   return +1;       // counter clockwise
  if (cross(b, c) < -EPS)   return -1;       // clockwise
  if (dot(b, c) < -EPS)     return +2;       // c--a--b on line
  if (norm(b) < norm(c)) return -2;       // a--b--c on line
  return 0;
}

P rotate(const P &p, double ang) {
  return p * P(cos(ang), sin(ang));
}

P projection(const L &l, const P &p) {
  double t = dot(p-l[0], l[0]-l[1]) / norm(l[0]-l[1]);
  return l[0] + t*(l[0]-l[1]);
}
bool intersectSP(const L &s, const P &p) {
  return abs(s[0]-p)+abs(s[1]-p)-abs(s[1]-s[0]) < EPS; // triangle inequality
}

P crosspoint(const L &l, const L &m) {
  double A = cross(l[1] - l[0], m[1] - m[0]);
  double B = cross(l[1] - l[0], l[1] - m[0]);
  if (abs(A) < EPS && abs(B) < EPS) return m[0]; // same line
  if (abs(A) < EPS) assert(false); // !!!PRECONDITION NOT SATISFIED!!!
  return m[0] + B / A * (m[1] - m[0]);
}


vector<P> crosspointLC(const L &l, const C &c) {
  vector<P> ret;
  P center = projection(l, c.p);
  double d = abs(center - c.p);
  double t = sqrt(c.r * c.r - d * d);
  if (isnan(t)) { return ret; }
  P vect = (l[1] - l[0]);
  vect /= abs(vect);
  ret.push_back(center - vect * t);
  if (t > EPS) {
    ret.push_back(center + vect * t);
  }
  return ret;
}

vector<P> crosspointSC(const L &s, const C &c) {
  vector<P> ret;
  vector<P> nret = crosspointLC(s, c);
  FOR(it, nret)
    if (intersectSP(s, *it))
      ret.push_back(*it);
   return ret;
}

double angle(const P &a, const P &b) {        // テ」ツδ凖」ツつッテ」ツδ暗」ツδォテッツスツ?」ツ?凝」ツつ嘉」ツ?ソテ」ツ?淌」ツδ凖」ツつッテ」ツδ暗」ツδォテッツスツづ」ツ?ョティツァツ津・ツコツヲテ」ツ?ョティツィツ暗ァツョツ夕0,2pi)
  double ret = arg(b)-arg(a);
  return (ret>=0) ? ret : ret + 2*PI;
}

P p[10];
P q[10];
P c;
int main() {
  int m,n;
  while(cin >> m >> n, m||n) {
    REP(i,m) cin >> p[i].real() >> p[i].imag();    
    REP(i,n) cin >> q[i].real() >> q[i].imag();
    cin >> c.real() >> c.imag();
    double ans = 2*PI;
    REP(i,n) {
      REP(j,m) {
        vector<P> ps = crosspointSC(L(p[j],p[(j+1)%m]), C(c,abs(q[i]-c)));
        FOR(it, ps) {
          chmin(ans, angle(q[i]-c,*it-c));
        }
        ps = crosspointSC(L(q[i],q[(i+1)%n]), C(c,abs(p[j]-c)));
        FOR(it, ps) {
          chmin(ans, angle(*it-c,p[j]-c));
        }
      }
    }
    printf("%.10f\n", ans*180/PI);
  }
}
accuracy: 1
time_ms: 20
memory_kb: 1352
final_rank: 12

code_snippet: #include<algorithm>
#include<complex>
#include<cstdio>
#include<iostream>
#include<queue>

using namespace std;

#define rep(i, n) for (int i = 0; i < int(n); ++i)
template<class T> T at(vector<T> v, int i) {return v[i % v.size()];}

#define X real()
#define Y imag()

typedef long double D;
typedef complex<D> P;
struct L{P a, b;};
typedef vector<P> Pol;

const D EPS = 1e-8;
const D PI = acos(-1);

int sig(D a, D b = 0) {return a < b - EPS ? -1 : a > b + EPS ? 1 : 0;}
bool near(P a, P b) {return norm(a - b) < EPS;}

// 比較関数
namespace std {
  bool operator<(P a, P b) {return sig(a.X, b.X) ? a.X < b.X : a.Y < b.Y;}
}

D sr(D a) {return sqrt(max(a, (D)0));}

// 内積
D dot(P a, P b) {return a.X * b.X + a.Y * b.Y;}
// 外積
D det(P a, P b) {return a.X * b.Y - a.Y * b.X;}

// 線分のベクトル
P vec(L a) {return a.b - a.a;}

// 線分abに対する点cの位置
enum CCW{FRONT = 1, RIGHT = 2, BACK = 4, LEFT = 8, ON = 16};
int ccw(P a, P b, P c) {
  if (a == c || b == c) return ON;
  int s = sig(det(b - a, c - a));
  if (s) return s > 0 ? LEFT : RIGHT;
  return (a < b) == (b < c) ? FRONT : (c < a) == (a < b) ? BACK : ON;
}

// 有向角度
D arg(P base, P a, P b) {
  D ang = arg((b - base) / (a - base));
  return ang > 0 ? ang : ang + 2 * PI;
}

// 射影
P proj(P a, P b) {return a * dot(a, b) / norm(a);}
P perp(L l, P p) {return l.a + proj(vec(l), p - l.a);}

// 交点
P pLL(L a, L b) {return a.a + vec(a) * (det(vec(b), b.a - a.a) / det(vec(b), vec(a)));}

// 距離
D dLP(L l, P p) {return abs(det(vec(l), p - l.a)) / abs(vec(l));}

// 円
struct C{P c; D r;};

// 交差判定
bool iCL(C c, L l) {return sig(c.r, dLP(l, c.c)) >= 0;}

// 交点
pair<P, P> pCL(C c, L l) {
  P x = perp(l, c.c);
  P y = vec(l) / abs(vec(l)) * sr(c.r * c.r - norm(x - c.c));
  return make_pair(x - y, x + y);
}

int main() {
  while (true) {
    int n, m;
    cin >> n >> m;
    if (n == 0 && m == 0) break;
    Pol p(n), q(m);
    rep (i, n) cin >> p[i].X >> p[i].Y;
    rep (i, m) cin >> q[i].X >> q[i].Y;
    P c;
    cin >> c.X >> c.Y;
    D res = 2 * PI;
      rep (i, n) {
	if (near(c, p[i])) continue;
	C a = (C){c, abs(c - p[i])};
	rep (j, m) {
	  L s = (L){q[j], at(q, j + 1)};
	  if (!iCL(a, s)) continue;
	  pair<P, P> pp = pCL(a, s);
	  if (ccw(s.a, s.b, pp.first) == ON) {
	    res = min(res, arg(c, pp.first, p[i]));
	  }
	  if (ccw(s.a, s.b, pp.second) == ON) {
	    res = min(res, arg(c, pp.second, p[i]));
	  }
	}
      }
      swap(n, m);
      swap(p, q);
      rep (i, n) {
	if (near(c, p[i])) continue;
	C a = (C){c, abs(c - p[i])};
	rep (j, m) {
	  L s = (L){q[j], at(q, j + 1)};
	  if (!iCL(a, s)) continue;
	  pair<P, P> pp = pCL(a, s);
	  if (ccw(s.a, s.b, pp.first) == ON) {
	    res = min(res, arg(c, p[i], pp.first));
	  }
	  if (ccw(s.a, s.b, pp.second) == ON) {
	    res = min(res, arg(c, p[i], pp.second));
	  }
	}
      }
    printf("%.12Lf\n", res * 180 / PI);
  }
  return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 1280
final_rank: 4

code_snippet: #include<algorithm>
#include<complex>
#include<cstdio>
#include<iostream>
#include<queue>

using namespace std;

#define rep(i, n) for (int i = 0; i < int(n); ++i)
template<class T> T at(vector<T> v, int i) {return v[i % v.size()];}

#define X real()
#define Y imag()

typedef long double D;
typedef complex<D> P;
struct L{P a, b;};
typedef vector<P> Pol;

const D EPS = 1e-8;
const D PI = acos(-1);

int sig(D a, D b = 0) {return a < b - EPS ? -1 : a > b + EPS ? 1 : 0;}
bool near(P a, P b) {return norm(a - b) < EPS;}

// テヲツッツ氾ィツシツεゥツ鳴「テヲツ閉ー
namespace std {
  bool operator<(P a, P b) {return sig(a.X, b.X) ? a.X < b.X : a.Y < b.Y;}
  bool operator<(L a, L b) {return !near(a.a, b.a) ? a.a < b.a : a.b < b.b;}
}

D sr(D a) {return sqrt(max(a, (D)0));}

// テ・ツ??ァツゥツ?
D dot(P a, P b) {return a.X * b.X + a.Y * b.Y;}
// テ・ツ、ツ姪ァツゥツ?
D det(P a, P b) {return a.X * b.Y - a.Y * b.X;}

// テァツキツ堙・ツ按?」ツ?ョテ」ツδ凖」ツつッテ」ツδ暗」ツδォ
P vec(L a) {return a.b - a.a;}

// テァツキツ堙・ツ按?bテ」ツ?ォテ・ツッツセテ」ツ?凖」ツつ凝ァツつケcテ」ツ?ョテ、ツスツ催ァツスツョ
enum CCW{FRONT = 1, RIGHT = 2, BACK = 4, LEFT = 8, ON = 16};
int ccw(P a, P b, P c) {
  if (a == c || b == c) return ON;
  int s = sig(det(b - a, c - a));
  if (s) return s > 0 ? LEFT : RIGHT;
  return (a < b) == (b < c) ? FRONT : (c < a) == (a < b) ? BACK : ON;
}

// テヲツ慊嘉・ツ青妥ィツァツ津・ツコツヲ
D arg(P base, P a, P b) {
  D ang = arg((b - base) / (a - base));
  return ang > 0 ? ang : ang + 2 * PI;
}
L sortBase;
bool lessArg(P a, P b) {
  D ang1 = arg(sortBase.a, sortBase.b, a);
  D ang2 = arg(sortBase.a, sortBase.b, b);
  return sig(ang1, ang2) ? ang1 < ang2 : norm(a) > norm(b);
}

// テ・ツーツ?・ツスツア
P proj(P a, P b) {return a * dot(a, b) / norm(a);}
P perp(L l, P p) {return l.a + proj(vec(l), p - l.a);}
P refl(L l, P p) {return perp(l, p) * (D)2 - p;}

// テ、ツコツ、テ・ツキツョテ・ツ按、テ・ツョツ?
bool eqL(L a, L b) {return !sig(det(vec(a), vec(b))) && !sig(det(vec(a), b.a - a.a));}
bool iLL(L a, L b) {return sig(det(vec(a), vec(b))) || !sig(det(vec(a), b.a - a.a));}
bool iLLs(L a, L b) {return sig(det(vec(a), vec(b)));}
bool iLS(L a, L b) {return sig(det(vec(a), b.a - a.a)) * sig(det(vec(a), b.b - a.a)) <= 0;}
bool iLSs(L a, L b) {return sig(det(vec(a), b.a - a.a)) * sig(det(vec(a), b.b - a.a)) < 0;}
bool iSS(L a, L b) {
  int cwa = ccw(a.a, a.b, b.a) | ccw(a.a, a.b, b.b);
  int cwb = ccw(b.a, b.b, a.a) | ccw(b.a, b.b, a.b);
  return ((cwa | cwb) & ON) || ((cwa & cwb) == (LEFT | RIGHT));
}
bool iSSs(L a, L b) {
  int cwa = ccw(a.a, a.b, b.a) | ccw(a.a, a.b, b.b);
  int cwb = ccw(b.a, b.b, a.a) | ccw(b.a, b.b, a.b);
  return (cwa & cwb) == (LEFT | RIGHT);
}

// テ、ツコツ、テァツつケ
P pLL(L a, L b) {return a.a + vec(a) * (det(vec(b), b.a - a.a) / det(vec(b), vec(a)));}

// ティツキツ敕ゥツ崢「
D dLP(L l, P p) {return abs(det(vec(l), p - l.a)) / abs(vec(l));}
D dSP(L s, P p) {
  if (dot(vec(s), p - s.a) < 0) return abs(p - s.a);
  if (dot(vec(s), p - s.b) > 0) return abs(p - s.b);
  return dLP(s, p);
}
D dLL(L a, L b) {return iLL(a, b) ? 0 : dLP(a, b.a);}
D dLS(L a, L b) {return iLS(a, b) ? 0 : min(dLP(a, b.a), dLP(a, b.b));}
D dSS(L a, L b) {return iSS(a, b) ? 0 : min(min(dSP(a, b.a), dSP(a, b.b)), min(dSP(b, a.a), dSP(b, a.b)));}

// テ・ツ??
struct C{P c; D r;};

// 2テ・ツ??」ツ?ョテ、ツスツ催ァツスツョテゥツ鳴「テ、ツソツ?
enum RELATION{SAME = 1, CONTAIN = 2, OVER = 4, NO_CROSS = 8, ONE_CROSS = 16, ONE_CONTAIN_CROSS = 32, ONE_OVER_CROSS = 64, TWO_CROSS = 128};
int cRel(C c1, C c2) {
  D d = abs(c1.c - c2.c);
  if (near(c1.c, c2.c) && !sig(c1.r, c2.r)) return SAME;
  if (sig(d, c1.r - c2.r) < 0) return OVER;
  if (sig(d, c2.r - c1.r) < 0) return CONTAIN;
  if (!sig(d, c1.r - c2.r)) return ONE_OVER_CROSS;
  if (!sig(d, c2.r - c1.r)) return ONE_CONTAIN_CROSS;
  if (!sig(d, c1.r + c2.r)) return ONE_CROSS;
  if (sig(d, c1.r + c2.r) > 0) return NO_CROSS;
  return TWO_CROSS;
}

// テ、ツコツ、テ・ツキツョテ・ツ按、テ・ツョツ?
bool iCP(C c, P p) {return sig(abs(p - c.c), c.r) <= 0;}
bool iCL(C c, L l) {return sig(c.r, dLP(l, c.c)) >= 0;}
bool iCS(C c, L s) {return sig(c.r, dSP(s, c.c)) >= 0;}
bool iCSc(C c, L s) {return iCS(c, s) && sig(c.r, max(abs(s.a - c.c), abs(s.b - c.c))) >= 0;}
bool iCC(C a, C b) {return sig(abs(a.c - b.c), a.r + b.r) <= 0;}
bool iCCc(C a, C b) {return iCC(a, b) && sig(abs(a.c - b.c), abs(a.r - b.r)) >= 0;}

// テ、ツコツ、テァツつケ
pair<P, P> pCC(C a, C b) {
  D x = (norm(a.c - b.c) + a.r * a.r - b.r * b.r) / (2 * abs(a.c - b.c));
  P e = (b.c - a.c) / abs(b.c - a.c);
  P y = e * P(0, sr(a.r * a.r - x * x));
  return make_pair(a.c + e * x - y, a.c + e * x + y);
}
pair<P, P> pCL(C c, L l) {
  P x = perp(l, c.c);
  P y = vec(l) / abs(vec(l)) * sr(c.r * c.r - norm(x - c.c));
  return make_pair(x - y, x + y);
}

// ティツァツ津」ツ?ョテ・ツ??・ツ、ツ姪・ツ按、テ・ツョツ?ティツァツ誕bテ」ツ?ョテ・ツ??ゥツδィテ」ツ?ォテ」ツ?づ」ツつ古」ツ?ーテヲツュツ」テ」ツ??ィツセツコテ、ツクツ甘」ツ?ッ0テ」ツ??・ツ、ツ姪ゥツδィテ」ツ?ッティツイツ?
int sAP(P a, P b, P c) {return sig(det(a, c)) - sig(det(b, c)) - sig(det(a, b));}

// テ・ツ、ツ堙ィツァツ津・ツスツ「テ」ツ?ョテゥツ敖「テァツゥツ?
D aPol(Pol vp) {
  D ret = 0;
  rep (i, vp.size()) ret += det(vp[i], at(vp, i + 1));
  return ret / 2;
}

// テ・ツ、ツ堙ィツァツ津・ツスツ「テ」ツ?ョテ・ツ??・ツ、ツ姪・ツ按、テ・ツョツ?テ・ツ??ゥツδィ:1テ」ツ??・ツ堕ィテ、ツクツ?0テ」ツ??・ツ、ツ姪ゥツδィ:-1
int sGP(Pol pol, P p) {
  int side = -1;
  rep (i, pol.size()) {
    P p0 = pol[i] - p, p1 = at(pol, i + 1) - p;
    if (ccw(p0, p1, 0) == ON) return 0;
    if (p0.Y > p1.Y) swap(p0, p1);
    if (sig(p0.Y) <= 0 && 0 < sig(p1.Y) && sig(det(p0, p1)) > 0) side *= -1;
  }
  return side;
}

// テ・ツ?クテ・ツ個?
Pol convexHull(Pol p) {
  int m = -1, n = p.size();
  if (n < 3) return p;
  vector<P> q(n * 2);
  sort(p.begin(), p.end());
  for (int i = 0; i < n; q[++m] = p[i++])
    for (; m > 0 && ccw(q[m - 1], q[m], p[i]) != LEFT; --m);
  for (int i = n - 2, r = m; i >= 0; q[++m] = p[i--])
    for (; m > r && ccw(q[m - 1], q[m], p[i]) != LEFT; --m);
  q.resize(m);
  return q;
}

// テ・ツ?クテ・ツ個?」ツつォテ」ツδε」ツδ?
Pol convexCut(Pol p, L l) {
  vector<P> q;
  rep (i, p.size()) {
    if (ccw(l.a, l.b, p[i]) != RIGHT) q.push_back(p[i]);
    L s = {p[i], at(p, i + 1)};
    if (iLSs(l, s)) q.push_back(pLL(l, s));
  }
  return q;
}

// テァツキツ堙・ツ按?」ツつ津」ツδ榲」ツδシテ」ツつクテ」ツ?凖」ツつ?
vector<L> merge(vector<L> s) {
  rep (i, s.size()) if (s[i].b < s[i].a) swap(s[i].a, s[i].b);
  sort(s.begin(), s.end());
  rep (i, s.size()) rep (j, i) if (iSS(s[i], s[j]) && !iLL(s[i], s[j])) {
    s[j].b = max(s[i].b, s[j].b);
    s.erase(s.begin() + i--);
    break;
  }
  return s;
}

// テァツキツ堙・ツ按?」ツつ「テ」ツδャテ」ツδウテ」ツつクテ」ツδ。テ」ツδウテ」ツδ?テゥツ堋」テ」ツ?ョテァツつケテ」ツ?クテ」ツ?ョティツセツコテ」ツ?ョテ」ツ?ソテ」ツつ津ヲツ個?」ツ?、
vector<vector<int> > sArr(vector<L> s, vector<P> &vp) {
  s = merge(s);
  rep (i, s.size()) {
    vp.push_back(s[i].a);
    vp.push_back(s[i].b);
  }
  rep (i, s.size()) rep (j, i) if (iSS(s[i], s[j])) vp.push_back(pLL(s[i], s[j]));
  sort(vp.begin(), vp.end());
  vp.erase(unique(vp.begin(), vp.end(), near), vp.end());
  vector<vector<int> > g(vp.size());
  rep (i, s.size()) {
    vector<pair<D, int> > v;
    rep (j, vp.size()) if (ccw(s[i].a, s[i].b, vp[j]) == ON) {
      v.push_back(make_pair(norm(vp[j] - s[i].a), j));
    }
    sort(v.begin(), v.end());
    rep (j, v.size() - 1) {
      g[v[j + 1].second].push_back(v[j].second);
      g[v[j].second].push_back(v[j + 1].second);
    }
  }
  return g;
}

int main() {
  while (true) {
    int n, m;
    cin >> n >> m;
    if (n == 0 && m == 0) break;
    Pol p(n), q(m);
    rep (i, n) cin >> p[i].X >> p[i].Y;
    rep (i, m) cin >> q[i].X >> q[i].Y;
    P c;
    cin >> c.X >> c.Y;
    D res = 2 * PI;
      rep (i, n) {
	if (near(c, p[i])) continue;
	C a = (C){c, abs(c - p[i])};
	rep (j, m) {
	  L s = (L){q[j], at(q, j + 1)};
	  if (!iCL(a, s)) continue;
	  pair<P, P> pp = pCL(a, s);
	  if (ccw(s.a, s.b, pp.first) == ON) {
	    res = min(res, arg(c, pp.first, p[i]));
	  }
	  if (ccw(s.a, s.b, pp.second) == ON) {
	    res = min(res, arg(c, pp.second, p[i]));
	  }
	}
      }
      swap(n, m);
      swap(p, q);
      rep (i, n) {
	if (near(c, p[i])) continue;
	C a = (C){c, abs(c - p[i])};
	rep (j, m) {
	  L s = (L){q[j], at(q, j + 1)};
	  if (!iCL(a, s)) continue;
	  pair<P, P> pp = pCL(a, s);
	  if (ccw(s.a, s.b, pp.first) == ON) {
	    res = min(res, arg(c, p[i], pp.first));
	  }
	  if (ccw(s.a, s.b, pp.second) == ON) {
	    res = min(res, arg(c, p[i], pp.second));
	  }
	}
      }
    printf("%.12Lf\n", res * 180 / PI);
  }
  return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 1292
final_rank: 5

code_snippet: #include <cstdio>
#include <complex>
#include <cmath>
#include <algorithm>
#include <vector>
using namespace std;

typedef complex<double> P;
typedef const P &rP;

double pi2;

vector<double> intrarg(rP s, double r, rP p, rP q){
	vector<double> ret;
	P v = q - p;
	P w = p - s;
	double a = norm(v);
	double b = real(v) * real(w) + imag(v) * imag(w);
	double c = norm(w) - r * r;
	double D = b * b - a * c;
	double t;
	if(D >= 0.0){
		D = sqrt(D);
		for(double sgn = -1.0; sgn < 2.0; sgn += 2.0){
			t = (-b + sgn * D) / a;
			if(t > 0.0 && t < 1.0){
				ret.push_back(arg(w + t * v));
			}
		}
	}
	return ret;
}

double difarg(double a, double b){
	a -= b;
	while(a < 0.0) a += pi2;
	while(a >= pi2) a -= pi2;
	return a;
}

int main(){
	pi2 = acos(-1.0) * 2.0;
	
	int m, n;
	double x, y;
	while(scanf("%d%d", &m, &n), m){
		vector<P> p(m + 1), q(n + 1);
		for(int i = 0; i < m; ++i){
			scanf("%lf%lf", &x, &y);
			p[i] = P(x, y);
		}
		p[m] = p[0];
		for(int i = 0; i < n; ++i){
			scanf("%lf%lf", &x, &y);
			q[i] = P(x, y);
		}
		q[n] = q[0];
		scanf("%lf%lf", &x, &y);
		P c(x, y);

		double ans = pi2;

		for(int i = 0; i < n; ++i){
			double r1 = abs(q[i] - c);
			double base1 = arg(q[i] - c);
			for(int j = 0; j < m; ++j){
				double r2 = abs(p[j] - c);
				double base2 = arg(p[j] - c);

				vector<double> ret = intrarg(c, r1, p[j], p[j+1]);
				for(int k = 0; k < ret.size(); ++k){
					ans = min(ans, difarg(ret[k], base1));
				}

				ret = intrarg(c, r2, q[i], q[i+1]);
				for(int k = 0; k < ret.size(); ++k){
					ans = min(ans, difarg(base2, ret[k]));
				}
			}
		}

		printf("%.9f\n", ans / pi2 * 360.0);
	}
}
accuracy: 1
time_ms: 10
memory_kb: 1212
final_rank: 2

code_snippet: #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;
}
accuracy: 1
time_ms: 410
memory_kb: 876
final_rank: 3

code_snippet: #include<iostream>
#include<algorithm>
#include<complex>
#include<vector>
#include<cmath>
#define REP(i,b,n) for(int i=b;i<n;i++)
#define rep(i,n)   REP(i,0,n)
#define NEXT(i,n)  ((i+1)%(n))
#define mp         make_pair
#define pb         push_back
using namespace std;

typedef complex<double> P;

const double pi = acos(-1);

pair<double,double> check(double dx,double dy,double rx,double ry,double r,
			  bool &flag){
  double a=(dx*dx+dy*dy),b=-2*rx*dx-2*ry*dy,c=rx*rx+ry*ry-r*r;
  double D=b*b-4*a*c;
  if (D < 0)return mp(-1,-1);
  flag=true;
  return mp((-b-sqrt(D))/(2*a),(-b+sqrt(D))/(2*a));
}

inline P getnorm(P a){
  return a/abs(a);
}

bool isp(P a,P b,P c){
  return abs(a-c)+abs(b-c) < abs(a-b)+1e-10;
}


void getdata(vector<P> &p,vector<P> &e,vector<double> &a,bool flag){
  rep(i,p.size()){
    double r = abs(p[i]);
    double ori=arg(p[i]);
    rep(j,e.size()){
      bool cansolve=false;
      P norm=getnorm(e[NEXT(j,e.size())]-e[j]);
      pair<double,double> tmp=check(norm.real(),norm.imag(),-e[j].real(),-e[j].imag(),r,cansolve);
      if (!cansolve)continue;
      rep(k,2){
	P point=e[j]+tmp.first*norm;
	if (isp(e[j],e[NEXT(j,e.size())],point)){
	  double t = arg(point);
	  if (flag){
	    if (t <ori)t+=2*pi;
	    a.pb(t-ori);
	  }else {
	    if (ori < t)t-=2*pi;
	    a.pb(ori-t);
	  }
	}
	swap(tmp.first,tmp.second);
      }
    }
  }
}

double solve(vector<P> &p,vector<P> &e){//cx,cy=0,0
  vector<double> a;
  a.pb(2*pi);
  getdata(p,e,a,true);
  getdata(e,p,a,false);
  sort(a.begin(),a.end());
  return a[0]*180/pi;
}


main(){
  int n,m;
  while(cin>>n>>m && n){
    vector<P> e(n),p(m);
    rep(i,e.size()){
      double x,y;cin>>x>>y;e[i]=P(x,y);
    }
    rep(i,p.size()){
      double x,y;cin>>x>>y;p[i]=P(x,y);
    }
    double cx,cy;
    cin>>cx>>cy;
    P minus=P(cx,cy);
    rep(i,e.size())e[i]-=minus;
    rep(i,p.size())p[i]-=minus;
    printf("%.7lf\n",solve(p,e));
  }

}
accuracy: 1
time_ms: 30
memory_kb: 1004
final_rank: 1