#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;}
}

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> p){
	
	sort(p.begin(),p.end());
	vector<P> ret(p.size()*2);
	
	int k=0;
	for(int i=0;i<p.size();i++){
		while(k>1 && !ccw(ret[k-2],ret[k-1],p[i]))k--;
		ret[k]=p[i];k++;
	}
	
	int t=k;
	for(int i=p.size()-2;i>=0;i--){
		while(k>t && !ccw(ret[k-2],ret[k-1],p[i]))k--;
		ret[k]=p[i];k++;
	}
	
	return vector<P>(ret.begin(), ret.begin()+k-1);
}

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;
	}
}