Problem: “Hey, what’s up? It’s already 30 minutes past eleven!”

“I’m so sorry, but actually I got lost. I have no idea where I am now at all and I got tired wandering around. Please help!”

- Today you came to the metropolis to play with your friend. But she didn’t show up at the appointed time. What happened to her? After some uncomfortable minutes, finally you managed to get her on line, and have been just notified that she’s been lost in the city.

You immediately told her not to move, and asked her what are around her to figure out where she is. She told the names of some famous land marks, in the order where she caught in her sight while she made a full turn counterclockwise without moving around.

Fortunately, today you have a map of the city. You located all the land marks she answered on the map, but want to know in which district of the city she’s wandering.

Write a program to calculate the area where she can be found, as soon as you can!



Input

Each input case is given in the format below:


N
x1 y1
...
xN yN
l1 . . . lN


An integer N in the first line specifies the number of land marks she named (N ≤ 10). The following N lines specify the x- and y-coordinates of the land marks in the city. Here you modeled the city as an unbounded two- dimensional plane. All coordinate values are integers between 0 and 100, inclusive. The last line of a test case specifies the order in which she found these land marks in a counterclockwise turn.

A single line containing zero indicates the end of input. This is not a part of the input and should not be processed.

Output

Your program should output one line for each test case.

The line should contain the case number followed by a single number which represents the area where she can be found. The value should be printed with the fifth digit after the decimal point, and should not contain an absolute error greater than 10-5 .

If there is no possible area found under the given condition, output “No area” in a line, instead of a number. If you cannot bound the area, output “Infinity”.

Example

Input

8
1 0
2 0
3 1
3 2
2 3
1 3
0 2
0 1
1 2 3 4 5 6 7 8
8
1 0
2 0
3 1
3 2
2 3
1 3
0 2
0 1
4 3 2 1 8 7 6 5
4
0 0
1 0
1 1
0 1
1 2 3 4
0


Output

Case 1: 10.00000
Case 2: No area
Case 3: Infinity

Solution (in CPP):

Solution:
#include <iostream>
#include <iomanip>
#include <complex>
#include <vector>
#include <algorithm>
#include <cmath>
#include <array>
using namespace std;
const double EPS = 1e-6;
const double INF = 1e7;
#define EQ(n,m) (abs((n)-(m)) < EPS)
#define X real()
#define Y imag()

typedef complex<long 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(){}
};
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;
    }
}

long double dot(P a, P b){
    return (conj(a)*b).X;
}
long 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

}

bool isParallel(const P &a, const P &b){
    return abs(cross(a,b)) < EPS;
}
bool isParallel(const L &a, const L &b){
    return isParallel(a[1]-a[0], b[1]-b[0]);
}
P crosspointLL(const L &l, const L &m) {
  long double A = cross(l[1]-l[0], m[1]-m[0]);
  long double B = cross(l[1]-l[0], l[1]-m[0]);
  return m[0] + B/A *(m[1]-m[0]);
}

long double getarea(const VP &poly){
    long double ret = 0;
    for (int i=0; i<(int)poly.size(); i++){ 
        ret += cross(poly[i], poly[(i+1)%poly.size()]);
    }
    return ret*0.5;
}

VP convex_cut(const VP& p, const L& l){
    VP ret;
    int n = p.size();
    for(int i=0; i<n; i++){
        P curr = p[i];
        P next = p[(i+1)%n];
        if(ccw(l[0], l[1], curr) != -1) ret.push_back(curr);
        if(ccw(l[0], l[1], curr) *ccw(l[0], l[1], next) == -1){
            ret.push_back(crosspointLL(L(curr, next), l));
        }
    }
    return ret;
}

int main(){
    for(int dn=1; ; dn++){
        int n;
        cin >> n;
        if(n == 0) break;

        VP p(n);
        for(int i=0; i<n; i++){
            int x,y;
            cin >> x >> y;
            p[i] = P(x, y);
        }
        vector<int> ord(n);
        for(int i=0; i<n; i++){
            cin >> ord[i];
            ord[i]--;
        }
        vector<int> next(n);
        for(int i=0; i<n; i++){
            next[ord[i]] = ord[(i+1)%n];
        }

        VP sq{P(-INF, -INF), P(INF, -INF), P(INF, INF), P(-INF, INF)};
        long double ans = 0;
        for(int i=0; i<(1<<n); i++){
            VP poly = sq;
            for(int j=0; j<n; j++){
                L cut(p[ord[j]], p[ord[(j+1)%n]]);
                if((i & 1<<j) != 0) swap(cut[0], cut[1]);
                poly = convex_cut(poly, cut);
            }
            if(poly.empty()) continue;
            
            P center(0, 0);
            for(const P &p: poly){
                center += p;
            }
            center /= poly.size();
            vector<pair<long double, int> > angle(n);
            for(int i=0; i<n; i++){
                angle[i] = make_pair(arg(p[i]-center), i);
            }
            sort(angle.begin(), angle.end());
            bool ok = true;
            for(int i=0; i<n-1; i++){
                if(next[angle[i].second] != angle[(i+1)%n].second){
                    ok = false;
                    break;
                }
            }
            if(!ok) continue;
            
            bool isinf = false;
            for(const P &p: poly){
                if(EQ(abs(p.X), INF) || EQ(abs(p.Y), INF)){
                    isinf = true;
                    break;
                }
            }
            long double area = getarea(poly);
            if(area > 0){
                if(isinf){
                    ans = -1;
                    break;
                }else{
                    ans += area;
                }
            }
        }

        cout << "Case " << dn << ": ";
        if(EQ(ans, 0)){
            cout << "No area" << endl;
        }else if(ans < 0){
            cout << "Infinity" << endl;
        }else{
            cout << fixed << setprecision(5);
            cout << ans << endl;
        }
    }
    return 0;
}