#include <bits/stdc++.h>
#define DIMN 600
using namespace std;
struct punct {
int x , y;
} e[2*DIMN] , origine;
struct idk{
punct fst,scd;
} v[DIMN];
int a[DIMN][2*DIMN],dp[2*DIMN];
long double PI = 3.14159265359;
int modul (int x){
if (x>=0)
return x;
return -x;
}
int cadran (punct a){
if (a.x>=0 && a.y>=0)
return 1;
if (a.x<=0 && a.y>=0)
return 2;
if (a.x<0 && a.y<=0)
return 3;
return 4;
}
int cmp (punct a,punct b){ /// return 1 = ordinea buna
int ca=cadran (a),cb=cadran(b);
if (ca!=cb)
return ca<=cb;
if (ca ==1){ /// unghiuri sub 90
if (a.y * b.x != b.y * a.x)
return a.y * b.x < b.y * a.x;
/// ELSE
return (a.y * a.y + a.x * a.x) <= (b.y * b.y + b.x * b.x);
}
else if (ca==2) { /// unghiuri de 90 +
if (modul(a.y * b.x) != modul(b.y * a.x))
return modul(a.y * b.x) >= modul(b.y * a.x);
/// ELSE
return (a.y * a.y + a.x * a.x) <= (b.y * b.y + b.x * b.x);
}
else if (ca==3){
if (modul(a.y * b.x) != modul(b.y * a.x))
return modul(a.y * b.x) <= modul(b.y * a.x);
/// ELSE
return (a.y * a.y + a.x * a.x) <= (b.y * b.y + b.x * b.x);
}
else {
if (modul(a.y * b.x) != modul(b.y * a.x))
return modul(a.y * b.x) >= modul(b.y * a.x);
/// ELSE
return (a.y * a.y + a.x * a.x) <= (b.y * b.y + b.x * b.x);
}
}
long double det (long double x1,long double y1,long double x2,long double y2,long double x3,long double y3 ){
return (x2 - x1) * (y3 - y1) - (x3 - x1) * (y2 - y1);
}
int segm (long double x3,long double y3,long double x1,long double y1 , long double x2 , long double y2){
long double d = det (x1,y1,x2,y2,x3,y3);
if (d!=0.0)
return 0;
if (x1 == x3 && y1 == y3)
return 1;
if (x2 == x3 && y2 == y3)
return 1;
if ((x3 - x1) * (x3 - x2) < 0.0 || (y3 - y1) * (y3 - y2) < 0.0)
return 1;
return 0;
}
int intersectie_segmente (long double x1,long double y1,long double x2,long double y2,long double x3,long double y3,long double x4,long double y4){
long double d1,d2,d3,d4;
if (segm (x1,y1,x3,y3,x4,y4) || segm (x2,y2,x3,y3,x4,y4) || segm (x3,y3,x1,y1,x2,y2) || segm (x4,y4,x1,y1,x2,y2))
return 1;
d1 = det (x3,y3,x4,y4,x1,y1);
d2 = det (x3,y3,x4,y4,x2,y2);
d3 = det (x1,y1,x2,y2,x3,y3);
d4 = det (x1,y1,x2,y2,x4,y4);
if (d1 * d2 < 0 && d3 * d4 < 0)
return 1;
return 0;
}
int intersectie (punct p1 , punct p2 , punct q1 , punct q2){
int a,b,c;
long double x,y;
a = p1.y - p2.y;
b = p2.x - p1.x;
c = p1.x * (-a) - p1.y * b;
if (cadran(p2) < 3){ /// y ul lui tinde spre infinit
y = 20000.0;
x = 1.0 * (-c - b * y) / (1.0 * a);
}
else {
y = -20000;
x = 1.0 * (-c - b * y) / (1.0 * a);
}
return intersectie_segmente (0.0,0.0, x , y , 1.0 * q1.x , 1.0 * q1.y , 1.0 * q2.x , 1.0 * q2.y );
}
long double degrees (punct x){ /// cate grade (0..360) de la 0 0 la x
if (cadran(x) == 1)
return ( atan((1.0 * x.y) / (1.0 * x.x)) * 180.0 ) / PI;
else if (cadran(x) == 2)
return 180.0 - ( atan((1.0 * x.y) / (-1.0 * x.x)) ) * 180.0 / PI;
else if (cadran(x) == 3)
return 180.0 + ( atan((-1.0 * x.y) / (-1.0 * x.x)) ) * 180.0 / PI;
else
return 360.0 - ( atan((-1.0 * x.y) / (1.0 * x.x)) ) * 180.0 / PI ;
}
int main()
{
ifstream fin ("laser.in");
ofstream fout ("laser.out");
int n,i,ev=0,nr,j,k,aux,x1,y1,x2,y2;
long double l , r;
fin >> n;
for (i=1;i<=n;i++){
fin >> x1 >> y1 >> x2 >> y2;
ev++;
e[ev].x = x1;
e[ev].y = y1;
ev++;
e[ev].x = x2;
e[ev].y = y2;
v[i].fst.x = x1;
v[i].scd.x = x2;
v[i].fst.y = y1;
v[i].scd.y = y2;
}
for (i=1;i<=n;i++)
fin>>a[i][2*n+1];
sort (e + 1 , e + ev + 1 , cmp); /// sort unghi
e[ev+1] = e[1];
for (i=1;i<=ev;i++){
/// ce drepte sunt in bucata asta
for (j=1;j<=n;j++){
//if (i == 6 && j == 2)
// printf ("a");
/// ca bis sa intersecteaze segm j , ambele semidrepte
/// O -> e[i] si O -> e[i+1] trb sa intersecteze segmentul
if (intersectie(origine , e[i] , v[j].fst , v[j].scd) && intersectie(origine , e[i+1] , v[j].fst , v[j].scd) ){
a[j][i] = 1;
//printf ("%d %d\n",i,j);
}
}
}
/// a[j][i] = 1 -> bisectoarea i intersecteaza segmentul i
/// am construit matricea de coeficienti
/// solve gauss
i=j=1;
while (i<=n && j<=2*n){
for (k=i;k<=n;k++){
if (a[k][j]!=0)
break;
}
if (k>n){ /// variabila libera
j++;
}
else {
/// interschimb linia i cu k
for (aux = 1; aux <= 2*n+1; aux++)
swap(a[i][aux] , a[k][aux]);
/// stii ca a[i][j] = 1
for (k=i+1;k<=n;k++){
if (a[k][j] == 1){
for (aux=2*n+1;aux;aux--)
a[k][aux] = (a[k][aux] ^ a[i][aux]);
}
}
i++;
j++;
}
}
/// ai facut sistemul sa devina un triunghi intors
nr = 0;
for (i=n;i;i--){
for (j=1;j<=2*n;j++){
if (a[i][j]!=0) /// nu e 0
break;
}
dp[j] = a[i][2*n+1]; /// dp[j] => trag sau nu la poz j
nr+=dp[j];
for (aux = i-1 ; aux ; aux-- ){
a[aux][2 * n + 1] = a[aux][2*n+1] ^ (a[i][2*n+1] * a[i][j]);
}
}
fout << nr << "\n";
for (i=1;i<=2*n;i++){
if (dp[i]){ /// TREBUIE SA IEI IN CALCUL BISECTOAREA UNGHIULUI E[I] -> E[I+1]
if (i!=2*n){
l = degrees (e[i]);
r = degrees (e[i+1]);
fout << setprecision(6) << fixed << (r - l)/2 + l << "\n";
}
else {
l = degrees (e[1]);
r = - (360.0 - degrees (e[2*n]));
if ((r + l) / 2.0 < 0)
fout << setprecision(6) << fixed << ( 360.0 + (r + l) / 2.0 ) << "\n";
else fout << setprecision(6) << fixed << ( (r + l) / 2.0 ) << "\n";
}
}
}
return 0;
}