#include <iostream>
#include <cstdlib>
#include <vector>
#include <map>
#include <algorithm>
using namespace std;

// [a,b] のどれかの整数を返す.
int random(int a, int b){
	int range = b - a + 1;
	return rand() % range + a;
}

int H[4][6] = {
	{1,5,2,3,0,4}, // North : 奥へ移動   ( y:-1 )
	{3,1,0,5,4,2}, // East  : 右へ移動   ( x:+1 )
	{2,1,5,0,4,3}, // West  : 左へ移動   ( x:-1 )
	{4,0,2,3,5,1}, // South : 手前へ移動 ( y:+1 )
};

int dx[4] = {0,1,-1,0};
int dy[4] = {-1,0,0,1};

// サイコロライブラリ
// d[0] := top,   d[1] := front 
// d[2] := right, d[3] := left
// d[4] := back,  d[5] := bottom
enum{TOP, FRONT, RIGHT, LEFT, BACK, BOTTOM};
struct Cube{
	vector<int> d;
	// コンストラクタで初期化
	Cube(vector<int> v){ d = v; }
	Cube(){ d = vector<int>(6); }
	// dirの方向に回転したダイスの状態を返す.
	Cube roll(int dir){
		Cube result = (*this);
		vector<int> d_(6);
    	for(int i = 0 ; i < 6 ; i++ ){
        	d_[i] = d[ H[dir][i] ];
    	}
    	result.d = d_;
    	return result;
    }
};

// get_dice[t][f] := t(=top), f(=front) のダイスの状態を返す.
Cube get_dice[7][7];
// d_to_f[dir] := 向き dir に対応するダイスの面を返す.
int d_to_f[4] = {0};
			
void foo(){
	d_to_f[0] = BACK;
	d_to_f[1] = RIGHT;
	d_to_f[2] = LEFT;
	d_to_f[3] = FRONT;
	
	bool memo[7][7] = {false};
	vector<int> v;
	for(int i=1 ; i <= 6 ; i++ ) v.push_back(i);
	Cube c(v);
	
	// ランダムに転がして get_dice[6][6] を計算.(全部で24通り)
	int cnt=0;
	while( cnt < 24 ){
		int t = c.d[TOP];
		int f = c.d[FRONT];
		if( !memo[t][f] ){
			memo[t][f] = true;
			cnt++;
			get_dice[t][f] = c;
		}
		c = c.roll( random(0,3) );
	}
}

// (サイコロ,高さ)
typedef pair<Cube,int> State;
State s[300][300];

// 初期化
void ini(){
	for(int y=0 ; y < 300 ; y++ ){
		for(int x=0 ; x < 300 ; x++ ){
			s[y][x] = State( Cube() , 0 );
		}
	}
}

// s[y][x] に サイコロ c を落とす.
void fall(Cube c, int x, int y){
	vector<int> v;
	// 4 方向で落ちる方向を調べる.
	for(int i=0 ; i < 4 ; i++ ){
		int mx = x + dx[i];
		int my = y + dy[i];
		if( s[my][mx].second < s[y][x].second ){
			v.push_back(i);
		}
	}
		
	if( v.empty() ){ // 落ちる方向がないとき
		s[y][x].first = c;
		s[y][x].second++;
	}else{
		int max_num = 0;
		for(int i=0 ; i < v.size() ; i++ ){
			// dir := 転がる向き, num := 転がる向きに対応する面に書かれた数値
			int dir = v[i];
			int num = c.d[ d_to_f[dir] ];
			max_num = max( max_num , num );
		}
		
		if( max_num < 4 ){ // 落ちる方向がないとき
			s[y][x].first = c;
			s[y][x].second++;
		}else{
			// 数値が4以上の一番大きい方向に転がる
			for(int i=0 ; i < v.size() ; i++ ){
				// dir := 転がる向き, num := 転がる向きに対応する面に書かれた数値
				int dir = v[i];
				int num = c.d[ d_to_f[dir] ];
				if( num == max_num ){
					int mx = x + dx[dir];
					int my = y + dy[dir];
					Cube c_ = c.roll(dir);
					fall(c_,mx,my);
					return ;
				}
			}
		}
	}
}

int main(){
	// get_dice の計算
	foo();
	int n;
	
	while( cin >> n , n ){
		// 初期化
		ini();
		
		// n 個のサイコロを落とす.
		for(int i=0 ; i < n ; i++ ){
			int t, f;
			cin >> t >> f;
			Cube c = get_dice[t][f];
			fall(c,150,150);
		}
		
		// 数える
		int ans[7] = {0};
		for(int y=0 ; y < 300 ; y++ ){
			for(int x=0 ; x < 300 ; x++ ){
				if( s[y][x].second == 0 ) continue;
				int top = s[y][x].first.d[TOP];
				ans[top]++;
			}
		}
		// 解を出力
		for(int i=1 ; i <= 6 ; i++ ){
			cout << ans[i];
			if( i == 6 ){
				cout << endl;
			}else{
				cout << " ";
			}
		}
	}
}

Measured memory_bytes: 6848