// Original C++ solution (slower):
#include <iostream>

#include <cstdio>

#include <cstdlib>

#include <cmath>

#include <cstring>

#include <vector>

#include <algorithm>

using namespace std;



typedef long long int lint;

struct {

	int nDice, tmp_score, last_score;

} mp[201][201] = { };



int opposide[7] = { 0, 6, 5, 4, 3, 2, 1 };

int right_side[7][7] = {{ },

						{0, 0, 3, 5, 2, 4},

						{0, 4, 0, 1, 6, 0, 3},

						{0, 2, 6, 0, 0, 1, 5},

						{0, 5, 1, 0, 0, 6, 2},

						{0, 3, 0, 6, 1, 0, 4},

						{0, 0, 4, 2, 5, 3}};

int final_score[7] = { };



void roll(int top, int front, int row, int col);



int main()

{

	int n = 0;

	while(scanf("%d", &n) == 1 && n != 0)

	{

		int top = 0, front = 0;

		for(int i = 0; i < 201; i++)

			for(int j = 0; j < 201; j++)

				mp[i][j].nDice = mp[i][j].tmp_score = mp[i][j].last_score = 0;

		for(int i = 1; i < 7; i++)

			final_score[i] = 0;

		while(n-- > 0)

		{

			scanf("%d %d", &top, &front);

			mp[100][100].nDice++;

			final_score[mp[100][100].tmp_score]--;

			mp[100][100].last_score = mp[100][100].tmp_score;

			mp[100][100].tmp_score = top;

			final_score[top]++;

			roll(top, front, 100, 100);

		}

		for(int i = 1; i < 7; i++)

			printf("%d%s", final_score[i], i == 6? "\n" : " ");

	}

	return 0;

}



void roll(int top, int front, int row, int col)

{

	int dire = 0;

	for(int i = 4; i < 7; i++)

	{

		if(i != top && i != opposide[top])

		{

			if(i == front && mp[row + 1][col].nDice + 1 < mp[row][col].nDice)

					dire = dire > i ? dire : i;

			else if(i == opposide[front] && mp[row - 1][col].nDice + 1 < mp[row][col].nDice)

					dire = dire > i ? dire : i;

			else if(i == right_side[top][front] && mp[row][col + 1].nDice + 1 < mp[row][col].nDice)

					dire = dire > i ? dire : i;

			else if(i == opposide[right_side[top][front]] && mp[row][col - 1].nDice + 1 < mp[row][col].nDice)

					dire = dire > i ? dire : i;

		}

	}

	if(dire > 0)

	{

		mp[row][col].nDice--;

		final_score[mp[row][col].tmp_score]--;

		mp[row][col].tmp_score = mp[row][col].last_score;

		final_score[mp[row][col].tmp_score]++;

		if(dire == front)

		{

			mp[row + 1][col].nDice++;

			final_score[mp[row + 1][col].tmp_score]--;

			final_score[opposide[front]]++;

			mp[row + 1][col].last_score = mp[row + 1][col].tmp_score;

			mp[row + 1][col].tmp_score = opposide[front];

			roll(opposide[front], top, row + 1, col);

		}

		else if(dire == opposide[front])

		{

			mp[row - 1][col].nDice++;

			final_score[mp[row - 1][col].tmp_score]--;

			mp[row - 1][col].last_score = mp[row - 1][col].tmp_score;

			mp[row - 1][col].tmp_score = front;

			final_score[mp[row - 1][col].tmp_score]++;

			roll(front, opposide[top], row - 1, col);

		}

		else if(dire == right_side[top][front])

		{

			mp[row][col + 1].nDice++;

			final_score[mp[row][col + 1].tmp_score]--;

			mp[row][col + 1].last_score = mp[row][col + 1].tmp_score;

			mp[row][col + 1].tmp_score = opposide[right_side[top][front]];

			final_score[mp[row][col + 1].tmp_score]++;

			roll(opposide[right_side[top][front]], front, row, col + 1);

		}

		else if(dire == opposide[right_side[top][front]])

		{

			mp[row][col - 1].nDice++;

			final_score[mp[row][col - 1].tmp_score]--;

			mp[row][col - 1].last_score = mp[row][col - 1].tmp_score;

			mp[row][col - 1].tmp_score = right_side[top][front];

			final_score[mp[row][col - 1].tmp_score]++;

			roll(right_side[top][front], front, row, col - 1);

		}

	}

}

// Optimized solution to the same problem (faster):
/*

 * Author:heroming

 * File:heroming.cpp

 * Time:2012-7-17 13:29:51

 */

#include <iostream>

#include <cstdio>

#include <string>

#include <cstring>

#include <cmath>

#include <algorithm>

#include <vector>

using namespace std;



#define SZ(v) ((int)(v).size())

const int MAXN = 30, MID = 15;

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

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

const int OPPO[] = {0, 6, 5, 4, 3, 2, 1};

const int LEFT[7][7] = {{0, 0, 0, 0, 0, 0, 0}, {0, 0, 4, 2, 5, 3, 0}, {0, 3, 0, 6, 1, 0, 4}, {0, 5, 1, 0, 0, 6, 2}, {0, 2, 6, 0, 0, 1, 5}, {0, 4, 0, 1, 6, 0, 3}, {0, 0, 3, 5, 2, 4, 0}};



int n, t, f, A[7], B[7];

int P[MAXN][MAXN][MAXN][2];

int T[MAXN][MAXN];



void fall(int x, int y, int z, int top, int front)

{

        int ff = front;

        memset(B, -1, sizeof(B));

        for (int k = 0; k < 4; ++ k)

        {

                if (ff >= 4 && ff <= 6)

                        B[ff] = k;

                ff = LEFT[top][ff];

        }

        for (int i = 6; i >= 4; -- i)

        {

                if (B[i] == -1)

                        continue;

                int k = B[i];

                int a = x + dx[k];

                int b = y + dy[k];

                if (T[a][b] < z)

                {

                        int tt;

                        if (k == 0)

                                tt = top;

                        else if (k == 2)

                                tt = OPPO[top];

                        else

                                tt = front;

                        fall(a, b, T[a][b], OPPO[i], tt);

                        return;

                }

        }



        P[x][y][z + 1][0] = top;

        P[x][y][z + 1][1] = front;

        ++ T[x][y];

}



int main()

{

        while (scanf("%d", &n) != EOF && n)

        {

                memset(P, 0, sizeof(P));

                memset(T, 0, sizeof(T));

                for (int i = 0; i < n; ++ i)

                {

                        scanf("%d%d", &t, &f);

                        fall(MID, MID, T[MID][MID], t, f);

                }

                memset(A, 0, sizeof(A));

                for (int i = 0; i < MAXN; ++ i)

                        for (int j = 0; j < MAXN; ++ j)

                                ++ A[P[i][j][T[i][j]][0]];

                printf("%d", A[1]);

                for (int i = 2; i <= 6; ++ i)

                        printf(" %d", A[i]);

                printf("\n");

        }

        return 0;

}

// Fastest known solution for this problem: