1 /**************************************************************
2 Problem: 1020
3 User: Tunix
4 Language: C++
5 Result: Accepted
6 Time:92 ms
7 Memory:32544 kb
8 ****************************************************************/
9
10 //BZOJ 1020
11 #include<cmath>
12 #include<vector>
13 #include<cstdio>
14 #include<cstring>
15 #include<cstdlib>
16 #include<iostream>
17 #include<algorithm>
18 #define rep(i,n) for(int i=0;i<n;++i)
19 #define F(i,j,n) for(int i=j;i<=n;++i)
20 #define D(i,j,n) for(int i=j;i>=n;--i)
21 #define pb push_back
22 using namespace std;
23 inline int getint(){
24 int v=0,sign=1; char ch=getchar();
25 while(ch<‘0‘||ch>‘9‘){ if (ch==‘-‘) sign=-1; ch=getchar();}
26 while(ch>=‘0‘&&ch<=‘9‘){ v=v*10+ch-‘0‘; ch=getchar();}
27 return v*sign;
28 }
29 const int N=30,M=40,MAXQ=1e6,INF=~0u>>2;
30 const double eps=1e-16;
31 typedef long long LL;
32 typedef double db;
33 /******************tamplate*********************/
34 int dcmp(db p){if(fabs(p)<eps) return 0;else return p>eps?1:-1;}
35 int n,m;
36 db ans;
37 struct Point{
38 db x,y;
39 Point(){}
40 Point(db x,db y):x(x),y(y){}
41 void Read(){scanf("%lf %lf",&x,&y);}
42 }temp[N];
43 Point operator + (const Point &a,const Point &b){return Point(a.x+b.x,a.y+b.y);}
44 Point operator - (const Point &a,const Point &b){return Point(a.x-b.x,a.y-b.y);}
45 Point operator * (const Point &a,db p){return Point(a.x*p,a.y*p);}
46 Point operator / (const Point &a,db p){return Point(a.x/p,a.y/p);}
47 bool operator == (const Point &a,const Point &b){return !dcmp(a.x-b.x)&&!dcmp(a.y-b.y);}
48 typedef Point Vector;
49 double Dot(const Vector &a,const Vector &b){return a.x*b.x+a.y*b.y;}
50 double Len(const Vector &a){return sqrt(Dot(a,a));}
51 double Cross(const Vector &a,const Vector &b){return a.x*b.y-a.y*b.x;}
52 Vector Normal(const Vector &a){return Vector(-a.y,a.x);}
53 bool On(const Point &a,const Point &b,const Point &c){
54 return !dcmp(Cross(b-a,c-a))&&
55 dcmp((a.x-b.x)*(a.x-c.x))<=0&&dcmp((a.y-b.y)*(a.y-c.y))<=0;
56 }
57 bool inter(const Point &a,const Point &b,const Point &c,const Point &d){
58 return dcmp(Cross(c-a,b-a)*Cross(d-a,b-a))<=0 && dcmp(Cross(a-c,d-c)*Cross(b-c,d-c))<=0;
59 }
60 Point getinter(const Point &a,const Vector &b,const Point &c,const Vector &d){
61 Vector u=a-c;
62 double t=Cross(d,u)/Cross(b,d);
63 return a+b*t;
64 }
65 struct Seg{
66 Point a,b;
67 Seg(){}
68 Seg(const Point &a,const Point &b):a(a),b(b){}
69 }queue[MAXQ];
70 struct Polygon{
71 Point p[M];
72 int tot;
73 bool In(Point &point){
74 int total=0;
75 F(i,1,tot)
76 if (On(point,p[i],p[i%tot+1]))
77 return true;
78 Point Ray=Point(-10001,point.y+0.1);
79 point.y+=0.1;
80 F(i,1,tot)
81 total=total+inter(Ray,point,p[i],p[i%tot+1]);
82 point.y-=0.1;
83 return total&1;
84 }
85 }island[N];
86 struct near{
87 Point P;
88 double dis;
89 near(){}
90 near(const Point &a,double b):P(a),dis(b){}
91 };
92 near DISPS(const Point &a,const Point &b,const Point &c){
93 if (b==c) return near(b,Len(b-a));
94 Vector v1=c-b,v2=a-b,v3=a-c;
95 if (dcmp(Dot(v1,v2))<=0) return near(b,Len(v2));
96 if (dcmp(Dot(v1,v3))>=0) return near(c,Len(v3));
97 Vector v=Normal(b-c);
98 Point ans=getinter(a,v,b,v1);
99 return near(ans,Len(a-ans));
100 }
101 bool check(Point &P){
102 F(i,1,n)
103 if (island[i].In(P))
104 return true;
105 return false;
106 }
107 near Find(Point &P){
108 if (check(P)) return near(P,0);
109 near ans1;
110 ans1.dis=1<<30;
111 F(i,1,n)
112 F(j,1,island[i].tot){
113 near get=DISPS(P,island[i].p[j],island[i].p[j%island[i].tot+1]);
114 if (dcmp(ans1.dis-get.dis)>=0) ans1=get;
115 }
116 ans=max(ans,ans1.dis);
117 return ans1;
118 }
119 void read(){
120 n=getint(); m=getint();
121 F(i,1,m) temp[i].Read();
122 F(i,1,n){
123 island[i].tot=getint();
124 F(j,1,island[i].tot)
125 island[i].p[j].Read();
126 }
127 }
128 void search(){
129 int front=0,rear=0;
130 F(i,1,m-1)
131 queue[++rear]=Seg(temp[i],temp[i+1]),Find(temp[i]);
132 Find(temp[m]);
133 Seg head;
134 while(front!=rear){
135 head=queue[front=front%MAXQ+1];
136 Point p1=Find(head.a).P,p2=Find(head.b).P,
137 l=head.a,r=head.b,mid=(l+r)/2;
138 while(Len(r-l)>1e-4){
139 Point mid=(r+l)/2;
140 if (Len(mid-p1)<Len(mid-p2)) l=mid;
141 else r=mid;
142 }
143 double nowans=max(Len(l-p1),Len(l-p2));
144 Find(l);
145 if (ans+0.005<nowans)
146 queue[rear=rear%MAXQ+1]=Seg(head.a,mid),
147 queue[rear=rear%MAXQ+1]=Seg(mid,head.b);
148 }
149 }
150 int main(){
151 #ifndef ONLINE_JUDGE
152 freopen("1020.in","r",stdin);
153 freopen("1020.out","w",stdout);
154 #endif
155 read();
156 search();
157 printf("%.2lf\n",ans);
158 return 0;
159 }