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 <bits/stdc++.h>
using namespace std;
const int dx[]={0,1,0,-1,1,-1,-1,1};
const int dy[]={-1,0,1,0,1,1,-1,-1};
const int INF = 1<<30;
const double EPS = 1e-15;
#define PB push_back
#define mk make_pair
#define fi first
#define se second
#define ll long long
#define reps(i,j,k) for(int i = (j); i < (k); i++)
#define rep(i,j) reps(i,0,j)
#define MOD 1000000007
typedef pair<int,int> Pii;
typedef pair<int,Pii> P;
typedef vector<int> vi;
typedef vector<vi> vvi;
struct Point{
    double x,y;
    Point(){}
    Point(double _x,double _y){
        x = _x;
        y = _y;
    }
    Point operator + (Point p){
        return Point(x+p.x,y+p.y);
    }
  
    Point operator - (Point p){
        return Point(x-p.x,y-p.y);
    }
  
    Point operator * (double k){
        return Point(k*x,k*y);
    }
  
    Point operator / (double k){
        return Point(x/k,y/k);
    }
 
    bool operator<(const Point &p)const{
        return x!=p.x?x<p.x:y<p.y;
    }
  
};
double dot(Point p, Point q){
    return p.x*q.x+p.y*q.y;
}
  
double cross(Point p,Point q){
    return p.x*q.y-q.x*p.y;
}
  
double norm(Point p){
    return p.x*p.x+p.y*p.y;
}
  
double pabs(Point p){
    return sqrt(norm(p));
}
typedef vector<Point> Polygon;
struct Line : Polygon{
    Line(){}
    Line(Point p,Point q){
        PB(p);
        PB(q);  
    }
};
struct Circle{
    Point p; //中心点
    double r; //半径
    Circle(){}
    Circle(Point _p,double _r){
        p = _p;
        r = _r;
    }
};
int ccw(Point a,Point b,Point c){
    b = b-a;
    c = c-a;
    if(cross(b,c) > 0)return +1; //a→b で反時計に折れてc ccw
    if(cross(b,c) < 0)return -1; //a→b で時計に折れてc ccw
    if(dot(b,c) < 0)return +2; // c--a--b;
    if(pabs(b)<pabs(c))return -2; //a--b--c
    return 0; //a--c--b
}
bool intersectSS(Line l,Line m){
    //lとmが交差してるかどうか
    return (ccw(l[0],l[1],m[0])*ccw(l[0],l[1],m[1])<=0)&&
            (ccw(m[0],m[1],l[0])*ccw(m[0],m[1],l[1])<=0);
}

bool intersectLL(Line l,Line m){
	return fabs(cross(l[1]-l[0],m[1]-m[0])) > EPS || //平行でない
			fabs(cross(l[1]-l[0],m[0]-l[0])) < EPS; //同一の線
}


double TriangleArea(Point a,Point b,Point c){
    b = b - a;
    c = c - a;
    return cross(b,c)*0.5; //負になることもあるので注意
}
 
double VertexArea(Polygon v){
    double subArea = 0.0;
    rep(i,v.size()-1){
        subArea += TriangleArea(v[0],v[i],v[i+1]);
    }
    return subArea; //負になることもあるので注意
}

Point crosspoint(Line l,Line m){
    if(intersectSS(l,m) == false)return Point(INF,INF);
    return m[0]+(m[1]-m[0])*cross(l[1]-l[0],l[1]-m[0])/cross(l[1]-l[0],m[1]-m[0]);
}
 
Polygon ConvexHull(Polygon v){
	int n = v.size();
	int k = 0;
	sort(v.begin(),v.end());
	Polygon e(2*n);
	for(int i=0;i<n;e[k++]=v[i++])
		while(k>=2&&ccw(e[k-2],e[k-1],v[i])<=0)k--;
	for(int i=n-2,t=k+1;i>=0;e[k++]=v[i--])
		while(k>=t&&ccw(e[k-2],e[k-1],v[i])<=0)k--;
	e.resize(k-1);
	return e;
}

int main(){
	int N;
	while(scanf("%d",&N),N){
		Polygon v;
		rep(i,N){
			double x,y;
			scanf("%lf,%lf",&x,&y);
			v.PB(Point(x,y));
		}
		printf("%d\n",N-ConvexHull(v).size());
	}
    return 0;
}