#include<cstdio>
#include<algorithm>
#include<vector>
#include<string>
#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<complex>
#include<stack>
#include<cmath>

using namespace std;

#define reps(i,f,n) for(int i=f;i<int(n);i++)
#define rep(i,n) reps(i,0,n)

#define X real()
#define Y imag()
typedef complex<double> P;

/*
namespace std{
	bool operator<(const P &a, const P &b){return a.X==b.X ? a.Y<b.Y : a.X<b.X;}
}*/
namespace std{
    bool operator<(const P &a, const P &b){
        return real(a)!=real(b)?real(a)<real(b):imag(a)<imag(b);
    }
}

double cross(P a,P b){return a.X*b.Y-a.Y*b.X;}
bool ccw(P a,P b,P c){return cross(b-a,c-a)>=0;}
vector<P> convex_VP(vector<P> ps) {
    int n = ps.size(), k = 0;
     
    if (n <= 1) return ps;
     
    sort(ps.begin(),ps.end());
    vector<P> qs(n * 2);
    for (int i = 0; i < n; qs[k++] = ps[i++]) {
        while (k > 1 && !ccw(qs[k-2],qs[k-1],ps[i])) k--;
    }
    for (int i = n - 2, t = k; i >= 0; qs[k++] = ps[i--]) {
        while (k > t && !ccw(qs[k-2],qs[k-1],ps[i])) k--;
    }
     
    vector<P> res(qs.begin(), qs.begin() + k - 1);
    return res;
}
int main(){
	
	while(1){
		int n;
		cin>>n;
		if(n==0)break;
		
		vector<P> p;
		rep(i,n){
			double a,b;
			scanf("%lf,%lf",&a,&b);
			p.push_back(P(a,b));
		}
		
		vector<P> convex = convex_VP(p);
		rep(i,convex.size()){
			printf("%lf %lf\n",convex[i].X,convex[i].Y);
		}
		cout<<(int)p.size()-(int)convex.size()<<endl;
	}
}