Problem: Some of you know an old story of Voronoi Island. There were N liege lords and they are always involved in territorial disputes. The residents of the island were despaired of the disputes.

One day, a clever lord proposed to stop the disputes and divide the island fairly. His idea was to divide the island such that any piece of area belongs to the load of the nearest castle. The method is called Voronoi Division today.

Actually, there are many aspects of whether the method is fair. According to one historian, the clever lord suggested the method because he could gain broader area than other lords.

Your task is to write a program to calculate the size of the area each lord can gain. You may assume that Voronoi Island has a convex shape.



Input

The input consists of multiple datasets. Each dataset has the following format:

N M
Ix1 Iy1
Ix2 Iy2
...
IxN IyN
Cx1 Cy1
Cx2 Cy2
...
CxM CyM


N is the number of the vertices of Voronoi Island; M is the number of the liege lords; (Ixi, Iyi) denotes the coordinate of the i-th vertex; (Cxi, Cyi ) denotes the coordinate of the castle of the i-the lord.

The input meets the following constraints: 3 ≤ N ≤ 10, 2 ≤ M ≤ 10, -100 ≤ Ixi, Iyi, Cxi, Cyi ≤ 100. The vertices are given counterclockwise. All the coordinates are integers.

The last dataset is followed by a line containing two zeros. This line is not a part of any dataset and should not be processed.

Output

For each dataset, print the area gained by each liege lord with an absolute error of at most 10-4 . You may output any number of digits after the decimal point. The order of the output areas must match that of the lords in the input.

Example

Input

3 3
0 0
8 0
0 8
2 2
4 2
2 4
0 0


Output

9.0
11.5
11.5

Solution (in CPP):

Solution:
#include <cstdio>
#include <iostream>
#include <vector>
#include <list>
#include <cmath>
#include <fstream>
#include <algorithm>
#include <string>
#include <queue>
#include <set>
#include <map>
#include <complex>
#include <iterator>
#include <cstdlib>
#include <cstring>
#include <sstream>

using namespace std;

#define EPS (1e-10)
#define EQ(a,b) (abs((a) - (b)) < EPS)
#define EQV(a,b) (EQ((a).real(),(b).real()) && EQ((a).imag(),(b).imag()))

typedef complex<double> P;
typedef pair<P,P> Edge;
typedef long long ll;

const double PI=4*atan(1.0);
const int MAX_SIZE = 10000;

// 内積
double dot(P a, P b) {
  return (a.real() * b.real() + a.imag() * b.imag());
}
// 外積
double cross(P a, P b) {
  return (a.real() * b.imag() - a.imag() * b.real());
}
// 点cが直線ab上にあるかないか
int is_point_on_line(P a, P b, P c) {
  return EQ( cross(b-a, c-a), 0.0 );
}
// 2直線の直行判定
int is_orthogonal(P a1, P a2, P b1, P b2) {
  return EQ( dot(a1-a2, b1-b2), 0.0 );
}
// 2直線の平行判定
int is_parallel(P a1, P a2, P b1, P b2) {
  return EQ( cross(a1-a2, b1-b2), 0.0 );
}
// 点a,bを通る直線と点cの間の距離
double distance_l_p(P a, P b, P c) {
  return abs(cross(b-a, c-a)) / abs(b-a);
}
// 点a,bを端点とする線分と点cとの距離
double distance_ls_p(P a, P b, P c) {
  if ( dot(b-a, c-a) < EPS ) return abs(c-a);
  if ( dot(a-b, c-b) < EPS ) return abs(c-b);
  return abs(cross(b-a, c-a)) / abs(b-a);
}
// 点が多角形の中に存在するかどうか
bool isInPolygon(vector<P> &points,P s){
	if(points.size()==1)return false;
	vector<P> v;
	for(int i=0;i<(int)points.size();i++)v.push_back(points[i]-s);
	int sign=0;
	for(int i=1;i<=(int)v.size();i++){
		int prv=(i-1+v.size())%v.size();
		int cur=i%v.size();
		double c=cross(v[prv],v[cur]);
		if(EQ(c,0))continue;
		else if(sign==0){
			if(c>0)sign=1;
			else sign=-1;
		}
		else{
			if(sign==-1&&c>0)return false;
			else if(sign==1&&c<0)return false;
		}
	}
	return true;
}
struct Rec{
	vector<P> p;
};
// a1,a2を端点とする線分とb1,b2を端点とする線分の交差判定
int is_intersected_ls(P a1, P a2, P b1, P b2) {
    // 線分が平行な場合は重なっていないことにする
    if(abs(cross(a2-a1,b2-b1)) < EPS){
        return 0;
    }
    return ( cross(a2-a1, b1-a1) * cross(a2-a1, b2-a1) < EPS ) &&
        ( cross(b2-b1, a1-b1) * cross(b2-b1, a2-b1) < EPS );
}
// aとbの矩形が接しているかどうか(どちらかがどちからを含んでいるものもふくむ
bool isTouchRectangle(Rec &a,Rec &b){
	// aの各頂点がbの中に存在しているかチェック
	for(int i=0;i<4;i++)if(isInPolygon(b.p,a.p[i]))return true;
	// 逆
	for(int i=0;i<4;i++)if(isInPolygon(a.p,b.p[i]))return true;
	// 各辺が他方のどれかの辺と接しているか
	for(int i=0;i<4;i++){
		int curi=i;
		int prvi=(i-1+4)%4;
		for(int j=0;j<4;j++){
			int curj=j;
			int prvj=(j-1+4)%4;
			if(is_intersected_ls(a.p[curi],a.p[prvi],b.p[curj],b.p[prvj]))return true;
		}
	}
	return false;
}
// a1,a2を端点とする線分とb1,b2を端点とする線分の交点計算
P intersection_ls(P a1, P a2, P b1, P b2) {
  P b = b2-b1;
  double d1 = abs(cross(b, a1-b1));
  double d2 = abs(cross(b, a2-b1));
  double t = d1 / (d1 + d2);

  return a1 + (a2-a1) * t;
}
// a1,a2を通る直線とb1,b2を通る直線の交差判定
int is_intersected_l(P a1, P a2, P b1, P b2) {
  return !EQ( cross(a1-a2, b1-b2), 0.0 );
}
// a1,a2を通る直線とb1,b2を通る直線の交点計算
P intersection_l(P a1, P a2, P b1, P b2) {
  P a = a2 - a1; P b = b2 - b1;
  return a1 + a * cross(b, b1-a1) / cross(b, a);
}
// 単位ベクトルを求める
P normalVector(P p){
	return p/abs(p);
}
// 法線ベクトルを求める
P unitVector(P a){
	return P(-a.imag(),a.real());
}
// 単位法線ベクトルを求める
P unitNormalVector(P tmp){
	P e=P(-tmp.imag(),tmp.real());
	e/=abs(e);
	return e;
}
// 座標の回転(座標pにある点を,半時計回りにa(ラジアン)回転)
P roundPoint(P p,double a){
	return P(cos(a)*p.real()-sin(a)*p.imag(),sin(a)*p.real()+cos(a)*p.imag());
}
/*
円周と線分の交差判定
*/
bool isCircleCrossLine(P a,P b,P c,double r){
	double d1 = abs(a-c);
	double d2 = abs(b-c);
    // 線分が中に含まれるとき、ここのコメントアウトをはずせばtrue(交差)となる
	//if(d1<r&&d2<r)
	//	return true;
	double d = distance_ls_p(a,b,c);
	return (EQ(d,r)||d<r);
}
// 三角形の内部に点があるかどうか
// 外積の正負がすべて同じなら内部に点あり
bool isInTriangle(P p1,P p2,P p3,P s){
	P a=p1-s;
	P b=p2-s;
	P c=p3-s;
	return ((cross(a,b)>0&&cross(b,c)>0&&cross(c,a)>0)||(cross(a,b)<0&&cross(b,c)<0&&cross(c,a)<0));
}
// 矩形の中に点が存在するかどうか
bool isInRectangle(P p1,P p2,P p3,P p4,P s){
	P a=p1-s;
	P b=p2-s;
	P c=p3-s;
    P d=p4-s;
	return ((cross(a,b)>0&&cross(b,c)>0&&cross(c,d)>0&&cross(d,a)>0)
        ||(cross(a,b)<0&&cross(b,c)<0&&cross(c,d)<0&&cross(d,a)<0));
}
// 三角形の面積を座標から計算
double calcAreaOfTriangle(P a,P b,P c){
	return abs((b.real()-a.real())*(c.imag()-a.imag()) - (c.real()-a.real())*(b.imag()-a.imag()))/2;
}
// 与えられた円の範囲内に点が存在するかどうか
bool isContainingDot(P c,double r,P a){
	return (((c.real()-a.real())*(c.real()-a.real())
		+(c.imag()-a.imag())*(c.imag()-a.imag())<r*r)
		||EQ((c.real()-a.real())*(c.real()-a.real())
		+(c.imag()-a.imag())*(c.imag()-a.imag()),r*r));
}
// 多角形の面積公式
double calcPolygonArea(vector<P> p){
  double sum=0;
  for(int i = 0; i < p.size(); i++)
    sum+=cross(p[i],p[(i+1)%(p.size())]);
  return sum/2;
}
// 2ベクトル間の角度
// aからbへ左周りで何度か(0->2*PI)
double diffAngle(P a,P b){
    double angle=atan2(cross(a,b),dot(a,b));
    if(angle<0)
        return 2*PI+angle;
    return angle;
}
// 2つのベクトルの重なっている部分の長さを返す
// もし重なっていなければ0を返す
double multipleLength(P a,P b,P c,P d){
    Edge e1=make_pair(a,b);
    Edge e2=make_pair(c,d);
    // 平行であるかどうか
    if(!(is_parallel(e1.first,e2.first,e1.second,e2.second)
        &&is_parallel(e1.first,e1.second,e2.first,e2.second)))
        return 0;
    double dist=0;
    // 両方乗っている
    if(EQ(distance_ls_p(e1.first,e1.second,e2.first),0)&&EQ(distance_ls_p(e1.first,e1.second,e2.second),0))
        dist=abs(e2.first-e2.second);
    else if(EQ(distance_ls_p(e2.first,e2.second,e1.first),0)&&EQ(distance_ls_p(e2.first,e2.second,e1.second),0))
        dist=abs(e1.first-e1.second);
    else if(EQ(distance_ls_p(e1.first,e1.second,e2.first),0)){
        // どちらが線上にあるか
        if(EQ(distance_ls_p(e2.first,e2.second,e1.first),0))
            dist=abs(e1.first-e2.first);
        else
            dist=abs(e1.second-e2.first);
    }
    else if(EQ(distance_ls_p(e1.first,e1.second,e2.second),0)){
        if(EQ(distance_ls_p(e2.first,e2.second,e1.first),0))
            dist=abs(e1.first-e2.second);
        else
            dist=abs(e1.second-e2.second);
    }
    return dist;
}
// 2点を通る半径rの円の中点を求める
pair<P,P> calcCircleCenterPoint(P dot1,P dot2,double r){
    double v=abs(dot1-dot2);
    double x = sqrt(r*r - (v/2)*(v/2));
    // 二組の単位法線ベクトル
    P hose[2];
    double x1=-(dot1.imag()-dot2.imag());
    double y1=(dot1.real() - dot2.real());
    hose[0]=P(x1,y1);
    double y2=-y1;
    double x2=-x1;
    hose[1]=P(x2,y2);
    double dd1=abs(hose[0]);
    double dd2=abs(hose[1]);
    hose[0]/=dd1;hose[0]*=x;
    hose[1]/=dd2;hose[1]*=x;
    P tmp=(dot1+dot2);
    tmp/=2;
    hose[0]+=tmp;
    hose[1]+=tmp;
    return make_pair(hose[0],hose[1]);
}
// 4線分が端点以外でクロスしているかどうかを判定
bool checkCross(const vector<Edge> &vec){
    for(int i=0;i<vec.size();i++){
        for(int j=i+1;j<vec.size();j++){
            // 線分がクロスしているかどうか
            if(is_intersected_ls(vec[i].first,vec[i].second,vec[j].first,vec[j].second)){
                // している場合、端点以外でクロスしているなら、false
                P p=intersection_ls(vec[i].first,vec[i].second,vec[j].first,vec[j].second);
                if(!(EQ(p,vec[i].first)||EQ(p,vec[i].second)))
                    return false;
            }
        }
    }
    return true;
}
// 引き数で与えられた4つの点が矩形を作るどうかを判定
bool checkRec(const vector<P> &squ){
    vector<int> v;
    for(int i=0;i<squ.size();i++)v.push_back(i);
    do{
        vector<Edge> ve;
        for(int i=0;i<4;i++)
            ve.push_back(make_pair(squ[v[i]],squ[v[(i+1)%4]]));
        // ここですべての線分がクロスするかどうかを計算
        if(checkCross(ve)){
            // 線分の長さを確認
            if(EQ(abs(ve[0].first-ve[0].second),abs(ve[2].first-ve[2].second)))
                if(EQ(abs(ve[1].first-ve[1].second),abs(ve[3].first-ve[3].second)))
                    // 直行
                    if(is_orthogonal(ve[0].first,ve[0].second,ve[1].first,ve[1].second))
                        if(is_orthogonal(ve[2].first,ve[2].second,ve[3].first,ve[3].second))
                        return true;
        }
    }while(next_permutation(v.begin(),v.end()));
    return false;
}
// 引き数で与えられた4つの点が正方形を作るかどうかを判定
bool checkSqu(const vector<P> &squ){
    vector<int> v;
    for(int i=0;i<squ.size();i++)v.push_back(i);
    do{
        vector<Edge> ve;
        for(int i=0;i<4;i++)
            ve.push_back(make_pair(squ[v[i]],squ[v[(i+1)%4]]));
        // ここですべての線分がクロスするかどうかを計算
        if(checkCross(ve)){
            // 線分の長さを確認
            double d=abs(ve[0].first-ve[0].second);
            for(int i=1;i<4;i++){
                double d2=abs(ve[i].first-ve[i].second);
                if(!EQ(d,d2))return false;
            }
            // 直行確認
            if(is_orthogonal(ve[0].first,ve[0].second,ve[1].first,ve[1].second))
                if(is_orthogonal(ve[2].first,ve[2].second,ve[3].first,ve[3].second))
                    return true;
        }
    }while(next_permutation(v.begin(),v.end()));
    return false;
}
// 二円の共通接線を構成する4直線を求める(二円はお互い接したりどちらかをふくんだりしない)
vector<pair<P,P> > calcCommonTangentialLine(P p1,double r1,P p2,double r2){
	vector<pair<P,P> > res;
	if(r1>r2){
		swap(r1,r2);
		swap(p1,p2);
	}
	// 共通外接線
	{
		double d=abs(p1-p2);
		double a=abs(r1-r2);
		double b=sqrt(d*d-a*a);
		double sita=acos(b/d);
		P e=normalVector(roundPoint((roundPoint((p2-p1),sita)),PI/2));
		res.push_back(make_pair(e*r1+p1,e*r2+p2));
		P e2=normalVector(roundPoint((roundPoint((p2-p1),-sita)),-PI/2));
		res.push_back(make_pair(e2*r1+p1,e2*r2+p2));
	}
	// 共通内接線
	{
		P cp=(r1*p1+r2*p2)/(r1+r2);
		double u=abs(cp-p1);
		double sita=acos(r1/u);
		P e=normalVector(roundPoint(cp-p1,sita));
		res.push_back(make_pair(e*r1+p1,-e*r2+p2));
		P e2=normalVector(roundPoint(cp-p1,-sita));
		res.push_back(make_pair(e2*r1+p1,-e2*r2+p2));
	}
	return res;
}
/*
  与えられた3点a,b,c,をa->b->cと進むとき
  a->bで時計方向に折れて,b->c
  a->bで半時計方向に折れて,b->c
  a->bで逆を向いてaを通り越してb->c
  a->bでそのままb->c
  a->bで逆を向いてb->c
  のどれであるかを判定
*/
int ccw(P a,P b, P c){
  b-=a;c-=a;
  if(cross(b,c)>0&&!EQ(cross(b,c),0))return 1;// counter clockwise
  if(cross(b,c)<0&&!EQ(cross(b,c),0))return -1;// clockwise
  if(dot(b,c)<0&&!EQ(dot(b,c),0))return 2; // c-a-b on line
  if(!EQ(abs(b),abs(c))&&abs(b)<abs(c))return -2; // a-b-c on line
  return 0;
}
// 凸多角形の切断を行う
// lineのfirst側から見て左の多角形が返る
// 多角形は上が+y,右が+xの座標系で座標を時計周りに格納したvectorで表す
// lineは基本的にmakeDivisorで作成
vector<P> convex_cut(vector<P> polygon,pair<P,P> line){
  vector<P> resPolygon;
  int n=polygon.size();
  for(int i=0;i<n;i++){
    P A=polygon[i];
    P B=polygon[(i+1)%n];
    if(ccw(line.first,line.second,A)!=-1)
      resPolygon.push_back(A);
    if(ccw(line.first,line.second,A)*ccw(line.first,line.second,B)<0)
      resPolygon.push_back(intersection_l(A,B,line.first,line.second));
  }
  return resPolygon;
}
// convex_cutの補助関数
// a側の凸多角形を残すような切断ラインを作成
pair<P,P> makeDivisor(P a, P b){
  P mid=(a+b);mid/=2;
  P base=unitNormalVector(b-a);
  base*=-1000000;
  P p1=base;p1+=mid;
  base*=-1;
  P p2=base;p2+=mid;
  return make_pair(p1,p2);
}

P cp[100];
int N,M;
int main(){
  while(cin>>N>>M&&(N|M)){
    double x,y;
    vector<P> initPol;
    for(int i=0;i<N;i++){
      cin>>x>>y;
      initPol.push_back(P(x,y));
    }
    for(int i=0;i<M;i++){
      cin>>x>>y;
      cp[i]=P(x,y);
    }
    // 各城ごとにボロノイ領域を求める
    for(int i=0;i<M;i++){
      vector<P> curPol=initPol;
      for(int j=0;j<M;j++){
	if(i==j)continue;
	curPol=convex_cut(curPol,makeDivisor(cp[i],cp[j]));
      }
      printf("%.10f\n",calcPolygonArea(curPol));
    }
  }
  // while(cin>>xs[0]>>ys[0]>>xs[1]>>ys[1]>>xs[2]>>ys[2]&&(xs[0]|xs[1]|xs[2]|ys[0]|ys[1]|ys[2])){
  //   for(int i=0;i<3;i++)ps[i]=P(xs[i],ys[i]);a
  //   vector<P> init;
  //   init.push_back(P(0,0));init.push_back(P(0,10000));
  //   init.push_back(P(10000,10000));init.push_back(P(10000,0));
  //   init=convex_cut(init,makeDivisor(ps[0],ps[1]));
  //   init=convex_cut(init,makeDivisor(ps[0],ps[2]));
  //   double S=abs(calcPolygonArea(init));
  //   printf("%d %.10f\n",cnt,S/100000000);
  //   cnt++;
  // }

  return 0;
}