#include <iostream>
#include <cstring>

#define N first
#define H second
#define mk(x, y) make_pair(x, y)

using namespace std;

typedef pair<int, int> pii;

enum drctY {
	NONE = 0, UP, DOWN, LEFT, RIGHT
};
struct _X {
			int back, front;
			int left, right;
			int bottom, top;
};
struct _Y {
			int top, bottom;
			int front, back;
			int left, right;
};
struct _Z {
			int back, front;
			int top, bottom;
			int left, right;
};
class Dice {
private :
	void Swap( int &a, int &b ) { int t = a; a = b; b = t; }
public :
	union {
		_X X;
		_Y Y;
		_Z Z;
		int d[6];
	};
	Dice ( int t, int bt, int f, int bk, int l, int r )
		{ Y.top = t; Y.bottom = bt; Y.front = f; Y.back = bk; Y.left = l; Y.right = r; }
	void RotLeftX	( int n );
	void RotLeftY	( int n );
	void RotLeftZ	( int n );
	void RotRightX	( int n );
	void RotRightY	( int n );
	void RotRightZ	( int n );
	drctY SearchDrctY( int n );
};

void Dice::RotLeftX ( int n ) {
	int m[] = { 2, 1, 3 }; // f, bt, bk
	for(int i=0; i < n; ++i) {
		for(int j=0; j < 3; ++j) Swap(d[0], d[m[j]]); // t
	}
}
void Dice::RotLeftY ( int n ) {
	int m[] = { 2, 5, 3 }; // f, r, bk
	for(int i=0; i < n; ++i) {
		for(int j=0; j < 3; ++j) Swap(d[4], d[m[j]]); // l
	}
}
void Dice::RotLeftZ ( int n ) {
	int m[] = { 5, 0, 4 }; // r, t, l
	for(int i=0; i < n; ++i) {
		for(int j=0; j < 3; ++j) Swap(d[1], d[m[j]]); // bt
	}
}
void Dice::RotRightX ( int n ) {
	int m[] = { 3, 1, 2 }; // bk, bt, f
	for(int i=0; i < n; ++i) {
		for(int j=0; j < 3; ++j) Swap(d[0], d[m[j]]); // t
	}
}
void Dice::RotRightY ( int n ) {
	int m[] = { 3, 5, 2 }; // bk, r, f
	for(int i=0; i < n; ++i) {
		for(int j=0; j < 3; ++j) Swap(d[4], d[m[j]]); // l
	}
}
void Dice::RotRightZ ( int n ) {
	int m[] = { 4, 0, 5 }; // l, t, r
	for(int i=0; i < n; ++i) {
		for(int j=0; j < 3; ++j) Swap(d[1], d[m[j]]); // bt
	}
}
drctY Dice::SearchDrctY( int n ) {
	if(Y.back == n)		return UP;
	if(Y.front == n)	return DOWN;
	if(Y.left == n)		return LEFT;
	if(Y.right == n)	return RIGHT;
	return NONE;
}

// right
int me[][6] = { // [top][front]
///   1, 2, 3, 4, 5, 6
	{ 0, 3, 5, 2, 4, 0 }, // 1
	{ 4, 0, 1, 6, 0, 3 }, // 2
	{ 2, 6, 0, 0, 1, 5 }, // 3
	{ 5, 1, 0, 0, 6, 2 }, // 4
	{ 3, 0, 6, 1, 0, 4 }, // 5
	{ 0, 4, 2, 5, 3, 0 }  // 6
};

const int X = 25;
const int Y = 25;
const int Width = X * 2 + 1;
const int Height = Y * 2 + 1;
pii fd[Height][Width];

int main( void )
{
	int n;
	while(cin >> n, n) {
		int top, front;
		cin >> top >> front;

		memset(fd, 0, sizeof(fd));

		fd[Y][X] = mk(top, 1);
		
		for(int i=1; i < n; ++i) {
			cin >> top >> front;
			Dice dice(top, 7-top, front, 7-front, 7 - me[top-1][front-1], me[top-1][front-1]);

			bool hit = true;
			
			int nx, ny, nh;
			nx = X; ny = Y, nh = fd[Y][X].H + 1;
			while(hit) {
				hit = false;

				for(int j=6; j >= 4; --j) {
					if(j == dice.Y.top || j == dice.Y.bottom) continue;
					const int dx[] = { 0, 0, 0, -1, 1 };
					const int dy[] = { 0, -1, 1, 0, 0 };
					int dd = (int)dice.SearchDrctY(j);
					
					int mx = nx + dx[dd];
					int my = ny + dy[dd];
					
					if(nh - fd[my][mx].H >= 2) {
						nx = mx;
						ny = my;
						nh = fd[my][mx].H + 1;
						hit = true;
						if		(dd == UP)	dice.RotRightX(1);
						else if	(dd == DOWN)	dice.RotLeftX(1);
						else if	(dd == LEFT)	dice.RotLeftZ(1);
						else if	(dd == RIGHT)dice.RotRightZ(1);
						break;
					}
				}
			}
			fd[ny][nx] = mk(dice.Y.top, nh);
		}

		int count[7] = { 0 };
		for(int y=0; y < Height; ++y)
			for(int x=0; x < Width; ++x) ++count[fd[y][x].N];

		for(int i=1; i <= 5; ++i)
			cout << count[i] << ' ';
		cout << count[6] << endl;
	}
	return 0;
}

Measured memory_bytes: 0