#define _CRT_SECURE_NO_WARNINGS
#define _USE_MATH_DEFINES

#include <iostream>
#include <algorithm>
#include <functional>
#include <string>
#include <queue>
#include <cmath>
#include <stack>
#include <numeric>
#include <ctime>
#include <algorithm>
#include <set>
#include <stdio.h>
#include <map>

using namespace std;
typedef long long int lint;

class Point {
public:
	pair<double, double> p;
	double arg;

	Point(){
		p.first = p.second = 0.0;
		arg = 0.0;
	}
};

struct LessPoint : public binary_function<Point, Point, bool> {
	bool operator () (const Point &pLeft, const Point &pRight) {
		return pLeft.arg > pRight.arg;
	}
};

bool IsClockwise(Point p1, Point p2, Point p3)
{
	pair<double, double> v1, v2;

	v1.first = p2.p.first - p1.p.first;
	v1.second = p2.p.second - p1.p.second;
	v2.first = p3.p.first - p1.p.first;
	v2.second = p3.p.second - p1.p.second;

	if(v1.first * v2.second - v2.first * v1.second < 0) return true;
	return false;
}

int main()
{
	int n, i;

	while(1){
		cin >> n;
		if(n == 0) break;

		Point *po;
		po = new Point[n];
		
		int nmin;				//最小のy座標を持つ点の番号
		double min = 2000.0;	//最小のy座標

		//find p_0
		for(i = 0; i < n; i++){
			scanf("%lf,%lf", &(po[i].p.first), &(po[i].p.second));
			if(po[i].p.second < min){
				nmin = i;
				min = po[i].p.second;
			}
		}
		//sort by argument
		priority_queue<Point, vector<Point>, LessPoint> qu;
		for(i = 0; i < n; i++){
			if(i == nmin) continue;

			po[i].arg = atan2(po[i].p.second - po[nmin].p.second, po[i].p.first - po[nmin].p.first);
			qu.push(po[i]);
		}

		stack<Point> st;

		//push p0 and p1
		st.push(po[nmin]);
		st.push(qu.top());
		qu.pop();

		while(!qu.empty()){
			Point top, under;	// S[top] and S[top - 1]
			while(1){
				top = st.top();
				st.pop();
				under = st.top();
				st.push(top);
				if(!IsClockwise(under, top, qu.top())) break;
				st.pop();
			}
			st.push(qu.top());
			qu.pop();
		}
		cout << n - st.size() << endl;
	}

	return 0;
}