Problem: Hit n nails one by one at the coordinates P1 (x1, y1), P2 (x2, y2), P3 (x3, y3), ..., Pn (xn, yn) on the flat plate, and put them on the rubber band ring. Surround it with a single rubber band so that all the nails fit inside. At this time, the rubber bands must not intersect.

Create a program that reads the coordinates of the nails and outputs the number of nails that are not in contact with the rubber band when the nail is surrounded by the rubber band as described above. The rubber band shall expand and contract sufficiently. You may not hit more than one nail at the same coordinates. In addition, it is assumed that the nails covered with rubber bands are connected by a straight line, and that no more than three nails are lined up on the straight line. For example, there can be no input as shown in Figure 1. As shown in Figure 2, it is possible for nails without rubber bands to line up in a straight line.

<image> | <image>
--- | ---
Figure 1 | Figure 2



However, each coordinate value is a real number between -1000.0 and 1000.0. Also, n is an integer between 3 and 100.

Hint

Below is a diagram for the second sample input.

<image>
---



Input

Given multiple datasets. Each dataset is given in the following format:


n
x1, y1
x2, y2
...
...
xn, yn


When n is 0, it indicates the end of input. The number of datasets does not exceed 50.

Output

For each dataset, output the number of nails that are not in contact with the rubber. For example, if there is an input representing the four nails shown in Fig. 3, it will be surrounded as shown in Fig. 4, so the number of nails that are not in contact with the rubber band is one.

<image> | <image>
--- | ---
Figure 3 | Figure 4


Example

Input

4
1.0,0.0
0.0,1.0
2.0,1.0
1.0,2.0
9
-509.94,892.63
567.62,639.99
-859.32,-64.84
-445.99,383.69
667.54,430.49
551.12,828.21
-940.2,-877.2
-361.62,-970
-125.42,-178.48
0


Output

0
3

Solution (in CPP):

Solution:
#include<iostream>
#include<cmath>
#include<vector>
#include<algorithm>
using namespace std;

// 度->ラジアンの変換
#define DEGtoRAD(X) (X*PI)/180.0
// 円周率
const double PI = 2 * acos(0.0);
// 許容誤差.問題によって変える
const double EPS = 1e-9;

struct point{
    double x, y;
    point(){ x = y = 0.0;}
    point(double _x, double _y) : x(_x), y(_y) {}

    // 不等号のオーバーロード.x座標,y座標で昇順ソート
    bool operator < (const point other) const{
        if(fabs(x - other.x) > EPS)
            return x < other.x;
        else
            return y < other.y;
    }

    // 等号のオーバーロード.
    bool operator == (const point other) const{
        return fabs(x - other.x) < EPS &&
                fabs(y - other.y) < EPS;
    }
};

// 2つのpoint間の距離 std::hypotenuse(斜辺)を利用
double dist(point p1, point p2){
    return hypot(p1.x - p2.x, p1.y - p2.y);
}

// ベクトル
struct vec{
    double x, y;
    vec(double _x, double _y) : x(_x), y(_y) {}
};

// 2つのpoint a,b をvec a->b に変換
vec toVec(point a, point b){
    return vec(b.x - a.x, b.y - a.y);
}

// vecの外積
double cross(vec v1, vec v2){
    return v1.x * v2.y - v1.y * v2.x;
}

bool ccw(point p, point q, point r){
    return cross(toVec(p, q), toVec(p, r)) > 0;
}

// 3つのpointが単一直線上にあるかどうかの判定
bool collinear(point p, point q, point r){
    return fabs(cross(toVec(p, q), toVec(p, r))) < EPS;
}

// 凸包を求めるのに用いる一連の関数
point pivot(0.0, 0.0);

// Graham's Scanの前準備で必要な,pivotからの偏角でソートするときに必要な比較関数
bool angleCmp(point a, point b){
    // 偏角が同じ(pivot,a,bが単一直線上に乗っている)場合は,pivotからの距離が近い方を優先
    if(collinear(pivot, a, b)){
        return dist(pivot, a) < dist(pivot, b);
    }

    double d1x = a.x - pivot.x, d1y = a.y - pivot.y;
    double d2x = b.x - pivot.x, d2y = b.y - pivot.y;

    return (atan2(d1y, d1x) - atan2(d2y, d2x)) < 0;
}

// 与えられた点群から凸包を求める(Graham's Scan)
vector<point> ConvexHull(vector<point> P){
    int i, j, n = (int)P.size();

    // 点群が3つしかない場合,P[0]をPに加える(輪っかのイメージ)
    if(n <= 3){
        if(!(P[0] == P[n-1]))  P.push_back(P[0]);
        return P;
    }

    // pivotを定める.最下,最右の点
    int P0 = 0;
    for(i = 1; i < n; i++){
        if(P[i].y < P[P0].y || 
           (P[i].y == P[P0].y && P[i].x > P[P0].x)){
               P0 = i;
        }
    }

    // P[0]とpivotとして選ばれたP[P0]をスワップ
    point temp = P[0];
    P[0] = P[P0];
    P[P0] = temp;

    pivot = P[0];
    sort(++P.begin(), P.end(), angleCmp);

    vector<point> S;
    S.push_back(P[n-1]);
    S.push_back(P[0]);
    S.push_back(P[1]);
    
    i = 2;
    while(i < n){
        j = (int)S.size() - 1;

        if(ccw(S[j-1], S[j], P[i]))
            S.push_back(P[i++]);
        else
            S.pop_back();
    }

    return S;
}

int main(){
    int n;
    vector<point> p, ch;
    while(1){
        scanf("%d", &n);
        if(n == 0)  break;

        p.clear();
        ch.clear();
        double x, y;
        for(int i = 0; i < n; i++){
            scanf("%lf,%lf", &x, &y);
            p.push_back(point(x,y));
        }

        ch = ConvexHull(p);
        
        printf("%d\n", n-ch.size()+1);
    }

    return 0;
}