#include <iostream>
#include <set>
#include <vector>
#include <map>
#include <string>
#include <math.h>
#include <queue>
#include <stack>

#define N 50

using namespace std;

// ある地点のサイコロのつまれた状態を保持
stack<pair<int,int> > loc[N][N];
// 入力をqueueで保持
queue<pair<int,int> > input;

// サイコロの上面がNだった時の側面の数字dice_tf[N][0~3]で少ないもの順に上から見て左回りで保持
int dice_tf[7][4]={
	{0,0,0,0},
	{2,3,5,4},
	{1,4,6,3},
	{1,2,6,5},
	{1,5,6,2},
	{1,3,6,4},
	{2,4,5,3}
};

// 転がる方向，４方向の値を保持
// 向き	dx	dy	上から見て
// 0	 0	 1	下方向
// 1	 1	 0　右方向
// 2	 0	-1　上方向
// 3	-1	 0	左方向
int dx[4]={0,1,0,-1};
int dy[4]={1,0,-1,0};

// 現在の高さ地図を表示
void printloc(){
	for(int y=(N/2)-10;y<(N/2)+10;y++){
		for(int x=(N/2)-10;x<(N/2)+10;x++){
			if((loc[y][x].size()-1)!=0) 
				cout << (loc[y][x].size()-1);
			else
				cout << " ";
		}cout << endl;
	}
}

// x,y地点の一番上にあるサイコロが転がるかどうか
// 転がるならばそちらに転がす
void rollandfall(int x,int y){
	int pi;
	int deg=-1;
	int max=-1;
	int num;

	// トップにあるサイコロの上面と前面から，前面が側面の対応テーブルの何番目に当たるのかを選ぶ
	// piにそれを保持
	for(int i=0;i<4;i++){
		if(dice_tf[loc[y][x].top().first][i]==loc[y][x].top().second){
			pi=i;
			break;
		}
	}

	// piから上から左回りに捜査し，転がることができる最大の目の番号と方向0~3を得る
	for(int i=0;i<4;i++){
		num=dice_tf[loc[y][x].top().first][(pi+i)%4];
		if(num>3){
			if((loc[y][x].size()-1)>loc[y+dy[i]][x+dx[i]].size()){
				if(max<num){
					deg=i;
					max=num;
				}
			}
		}
	}

	// maxの値とその向きがわかる．
	// maxが-1ならそれ以上転がりおちることはないので再起がストップ
	if(max!=-1){
		// 転がった場合の上面と前面の値を次の変数で保持，初期値はとりあえず現在の値
		int next_t=loc[y][x].top().first;
		int next_f=loc[y][x].top().second;

		// もし，方向が0か1，すなわち前面か背面に転がる場合（上からみたら上か下）
		if(deg%2==0){
			// 前面に転がるなら転がった場合の"次の前面"は"現在の上面"の値になる．
			if(deg==0)	next_f=next_t;
			// 背面に転がる場合の"次の前面"の値は”現在の上面”の”裏側”の値なので
			// ７から"現在の上面"の値を引いた値にする．
			else		next_f=7-next_t;
		}
		// それ以外(左右)ならば前面の値は同じ

		// "次の上面"の値は7から"転がる方向の値"を引いた値になる
		next_t=7-max;
		
		// 転がる方向の座標にサイコロを追加する
		loc[y+dy[deg]][x+dx[deg]].push(make_pair(next_t,next_f));
		// x,yにあるサイコロを取り出す
		loc[y][x].pop();
		
		// 転がる方向の座標で転がり判定を再起でかける．
		rollandfall(x+dx[deg],y+dy[deg]);
	}

}

// 入力を保持したキューの先頭をマップの中央に落とす．
void drop(){
	pair<int,int> dice;
	dice=input.front();
	input.pop();
	loc[N/2][N/2].push(make_pair(dice.first,dice.second));
	rollandfall(N/2,N/2);
}

// 上を向いている目を数え上げる
void countup(){
	// ヒストグラムを初期化，0番目を便宜上作成する
	int hist[7]={0,0,0,0,0,0,0};

	// 地図を全部走査して数え上げる
	for(int x=0;x<N;x++){
		for(int y=0;y<N;y++){
			if(!loc[y][x].empty()){
				hist[loc[y][x].top().first]++;
			}
		}
	}
	
	// 0番を除く頻度を表示させる
	for(int i=1;i<=6;i++){
		cout << hist[i];
		if(i!=6) cout << " ";
	}
	cout << endl;
}


void solve(){
	while(!input.empty()){
//		printloc();
		drop();
	}
	countup();
}

int main(void){
	int n;

	while(true){
		cin >> n;
		if(n==0) return 0;

		for(int x=0;x<N;x++){
			for(int y=0;y<N;y++){
				//地図を初期化する
				while(!loc[y][x].empty()){
					loc[y][x].pop();
				}
				//便宜上0,0で初期を埋める
				loc[y][x].push(make_pair(0,0));
			}
		}
		
		for(int i=0;i<n;i++){
			int t;
			int f;
			cin >> t;
			cin >> f;
			input.push(make_pair(t,f));
		}

		solve();
	}

	return 0;
}
### Prompt

Your task is to create a Cpp solution to the following problem:

Professor Random, known for his research on randomized algorithms, is now conducting an experiment on biased dice. His experiment consists of dropping a number of dice onto a plane, one after another from a fixed position above the plane. The dice fall onto the plane or dice already there, without rotating, and may roll and fall according to their property. Then he observes and records the status of the stack formed on the plane, specifically, how many times each number appears on the faces visible from above. All the dice have the same size and their face numbering is identical, which we show in Figure C-1.

<image>

Figure C-1: Numbering of a die

The dice have very special properties, as in the following.

(1) Ordinary dice can roll in four directions, but the dice used in this experiment never roll in the directions of faces 1, 2 and 3; they can only roll in the directions of faces 4, 5 and 6. In the situation shown in Figure C-2, our die can only roll to one of two directions.

<image>

Figure C-2: An ordinary die and a biased die

(2) The die can only roll when it will fall down after rolling, as shown in Figure C-3. When multiple possibilities exist, the die rolls towards the face with the largest number among those directions it can roll to.

<image>

Figure C-3: A die can roll only when it can fall

(3) When a die rolls, it rolls exactly 90 degrees, and then falls straight down until its bottom face touches another die or the plane, as in the case [B] or [C] of Figure C-4.

(4) After rolling and falling, the die repeatedly does so according to the rules (1) to (3) above.

<image>

Figure C-4: Example stacking of biased dice

For example, when we drop four dice all in the same orientation, 6 at the top and 4 at the front, then a stack will be formed as shown in Figure C-4.

<image>

Figure C-5: Example records

After forming the stack, we count the numbers of faces with 1 through 6 visible from above and record them. For example, in the left case of Figure C-5, the record will be "0 2 1 0 0 0", and in the right case, "0 1 1 0 0 1".

Input

The input consists of several datasets each in the following format.

> n
>  t1  f1
>  t2  f2
>  ...
>  tn  fn
>

Here, n (1 ≤ n ≤ 100) is an integer and is the number of the dice to be dropped. ti and fi (1 ≤ ti, fi ≤ 6) are two integers separated by a space and represent the numbers on the top and the front faces of the i-th die, when it is released, respectively.

The end of the input is indicated by a line containing a single zero.

Output

For each dataset, output six integers separated by a space. The integers represent the numbers of faces with 1 through 6 correspondingly, visible from above. There may not be any other characters in the output.

Sample Input


4
6 4
6 4
6 4
6 4
2
5 3
5 3
8
4 2
4 2
4 2
4 2
4 2
4 2
4 2
4 2
6
4 6
1 5
2 3
5 3
2 4
4 2
0


Output for the Sample Input


0 1 1 0 0 1
1 0 0 0 1 0
1 2 2 1 0 0
2 3 0 0 0 0






Example

Input

4
6 4
6 4
6 4
6 4
2
5 3
5 3
8
4 2
4 2
4 2
4 2
4 2
4 2
4 2
4 2
6
4 6
1 5
2 3
5 3
2 4
4 2
0


Output

0 1 1 0 0 1
1 0 0 0 1 0
1 2 2 1 0 0
2 3 0 0 0 0

### Response

```cpp
#include <iostream>
#include <set>
#include <vector>
#include <map>
#include <string>
#include <math.h>
#include <queue>
#include <stack>

#define N 50

using namespace std;

// ある地点のサイコロのつまれた状態を保持
stack<pair<int,int> > loc[N][N];
// 入力をqueueで保持
queue<pair<int,int> > input;

// サイコロの上面がNだった時の側面の数字dice_tf[N][0~3]で少ないもの順に上から見て左回りで保持
int dice_tf[7][4]={
	{0,0,0,0},
	{2,3,5,4},
	{1,4,6,3},
	{1,2,6,5},
	{1,5,6,2},
	{1,3,6,4},
	{2,4,5,3}
};

// 転がる方向，４方向の値を保持
// 向き	dx	dy	上から見て
// 0	 0	 1	下方向
// 1	 1	 0　右方向
// 2	 0	-1　上方向
// 3	-1	 0	左方向
int dx[4]={0,1,0,-1};
int dy[4]={1,0,-1,0};

// 現在の高さ地図を表示
void printloc(){
	for(int y=(N/2)-10;y<(N/2)+10;y++){
		for(int x=(N/2)-10;x<(N/2)+10;x++){
			if((loc[y][x].size()-1)!=0) 
				cout << (loc[y][x].size()-1);
			else
				cout << " ";
		}cout << endl;
	}
}

// x,y地点の一番上にあるサイコロが転がるかどうか
// 転がるならばそちらに転がす
void rollandfall(int x,int y){
	int pi;
	int deg=-1;
	int max=-1;
	int num;

	// トップにあるサイコロの上面と前面から，前面が側面の対応テーブルの何番目に当たるのかを選ぶ
	// piにそれを保持
	for(int i=0;i<4;i++){
		if(dice_tf[loc[y][x].top().first][i]==loc[y][x].top().second){
			pi=i;
			break;
		}
	}

	// piから上から左回りに捜査し，転がることができる最大の目の番号と方向0~3を得る
	for(int i=0;i<4;i++){
		num=dice_tf[loc[y][x].top().first][(pi+i)%4];
		if(num>3){
			if((loc[y][x].size()-1)>loc[y+dy[i]][x+dx[i]].size()){
				if(max<num){
					deg=i;
					max=num;
				}
			}
		}
	}

	// maxの値とその向きがわかる．
	// maxが-1ならそれ以上転がりおちることはないので再起がストップ
	if(max!=-1){
		// 転がった場合の上面と前面の値を次の変数で保持，初期値はとりあえず現在の値
		int next_t=loc[y][x].top().first;
		int next_f=loc[y][x].top().second;

		// もし，方向が0か1，すなわち前面か背面に転がる場合（上からみたら上か下）
		if(deg%2==0){
			// 前面に転がるなら転がった場合の"次の前面"は"現在の上面"の値になる．
			if(deg==0)	next_f=next_t;
			// 背面に転がる場合の"次の前面"の値は”現在の上面”の”裏側”の値なので
			// ７から"現在の上面"の値を引いた値にする．
			else		next_f=7-next_t;
		}
		// それ以外(左右)ならば前面の値は同じ

		// "次の上面"の値は7から"転がる方向の値"を引いた値になる
		next_t=7-max;
		
		// 転がる方向の座標にサイコロを追加する
		loc[y+dy[deg]][x+dx[deg]].push(make_pair(next_t,next_f));
		// x,yにあるサイコロを取り出す
		loc[y][x].pop();
		
		// 転がる方向の座標で転がり判定を再起でかける．
		rollandfall(x+dx[deg],y+dy[deg]);
	}

}

// 入力を保持したキューの先頭をマップの中央に落とす．
void drop(){
	pair<int,int> dice;
	dice=input.front();
	input.pop();
	loc[N/2][N/2].push(make_pair(dice.first,dice.second));
	rollandfall(N/2,N/2);
}

// 上を向いている目を数え上げる
void countup(){
	// ヒストグラムを初期化，0番目を便宜上作成する
	int hist[7]={0,0,0,0,0,0,0};

	// 地図を全部走査して数え上げる
	for(int x=0;x<N;x++){
		for(int y=0;y<N;y++){
			if(!loc[y][x].empty()){
				hist[loc[y][x].top().first]++;
			}
		}
	}
	
	// 0番を除く頻度を表示させる
	for(int i=1;i<=6;i++){
		cout << hist[i];
		if(i!=6) cout << " ";
	}
	cout << endl;
}


void solve(){
	while(!input.empty()){
//		printloc();
		drop();
	}
	countup();
}

int main(void){
	int n;

	while(true){
		cin >> n;
		if(n==0) return 0;

		for(int x=0;x<N;x++){
			for(int y=0;y<N;y++){
				//地図を初期化する
				while(!loc[y][x].empty()){
					loc[y][x].pop();
				}
				//便宜上0,0で初期を埋める
				loc[y][x].push(make_pair(0,0));
			}
		}
		
		for(int i=0;i<n;i++){
			int t;
			int f;
			cin >> t;
			cin >> f;
			input.push(make_pair(t,f));
		}

		solve();
	}

	return 0;
}
```