//http://mayokoex.hatenablog.com/entry/2016/04/12/164341
//を参考
#include<bits/stdc++.h>
using namespace std;
typedef vector<int> vi;
enum Dir
  {
    TOP,BOTTOM,FRONT,BACK,LEFT,RIGHT//0,1,2,3,4,5の順
  };
int trans[6]={-1,-1,3,1,2,0};//回す方向を決める数がtopかbottomにある場合はそもそも回せない.
int memo[6][4]={{3,5,4,2},{3,1,4,6},{1,2,6,5},{1,5,6,2},{1,3,6,4},{2,4,5,3}};//[上面][その他の配置について]
//上面が決まっていれば,右回りにどのような順序で数字が並ぶかは一意に決まる.
int dx[4]={-1,0,1,0};
int dy[4]={0,-1,0,1};
template<typename A,size_t N,typename T>
void Fill(A (&array)[N],const T &val)
{
  std::fill( (T*)array,(T*)(array+N),val );
}
const int MAXN=205;
int field[MAXN][MAXN][MAXN];

class Dice
{
public:
  Dice(){d.resize(6);}
  Dice(int top,int front)
  {
    d.resize(6);
    setting(top,front);
  }
  int find(int num) const
  {
    //指定された数字がどの面にあるかを教える
    for(int i=0;i<6;i++) if(num==d[i])return i;
    assert(0);
    return -1;
  }
  int get(int dir) const
  {
    //指定された面にどの数字があるかを教える
    return d[dir];
  }
  void setting(int top,int front)
  {
    d[TOP]=top;
    d[BOTTOM]=7-top;
    d[FRONT]=front;
    d[BACK]=7-front;
    int index=0;
    for (; index < 4; ++index)
      {
	if(memo[top-1][index]==front) break;
      }
    d[RIGHT]=memo[top-1][(index+1)%4];
    d[LEFT]=7-d[RIGHT];
  }
  void rotate(int dir)
  {
    vector<int> nextd=d;
    if(dir==0)//左面方向に転がる
      {
	nextd[TOP]=d[LEFT];
	nextd[LEFT]=d[BOTTOM];
	nextd[BOTTOM]=d[RIGHT];
	nextd[RIGHT]=d[TOP];
      }
    if(dir==1)//正面方向に転がる
      {
	nextd[TOP]=d[FRONT];
	nextd[FRONT]=d[BOTTOM];
	nextd[BOTTOM]=d[BACK];
	nextd[BACK]=d[TOP];
      }
    if(dir==2)//右面方向に転がる
      {
	nextd[TOP]=d[RIGHT];
	nextd[LEFT]=d[TOP];
	nextd[RIGHT]=d[BOTTOM];
	nextd[BOTTOM]=d[LEFT];
      }
    if(dir==3)//背面方向に転がる
      {
	nextd[TOP]=d[BACK];
	nextd[FRONT]=d[TOP];
	nextd[BOTTOM]=d[FRONT];
	nextd[BACK]=d[BOTTOM];
      }
    d=nextd;
  }
private:
  vector<int> d;//TOP,BOTTOM,FRONT,BACK,LEFT,RIGHTの順に詰め込まれる
};

int main(void)
{
  int N;
  while(cin >> N && N)
    {
      memset(field,0,sizeof(field));
      for (int i = 0; i < N; ++i)
	{
	  int t,f;
	  cin >> t >> f;
	  Dice dice(t,f);
	  int y=MAXN/2,x=MAXN/2;//投下地点は常に固定.万が一同じ方向に転がり続けた時のために,y,xの原点は(100,100)ぐらいとした.
	  for (int h = MAXN-1; MAXN>=0;)
	    {
	      if(h==0)
		{
		  field[h][y][x]=dice.get(TOP);//最初の投下だとこうなる
		  break;
		}
	      if(field[h-1][y][x]==0)//一マス下に何もないならサイコロがあるまで落ち続ける
		{
		  h--;
		  continue;
		}
	      bool ok=true;
	      for (int num = 6; num>=4; num--)
		{
		  //数字が高い順に回転できるかチェック
		  int d=dice.find(num);
		  if(d==BOTTOM || d==TOP) continue;
		  int dir=trans[d];
		  int ny=y+dy[dir],nx=x+dx[dir];
		  if(field[h-1][ny][nx]==0)//転がる先の一マス下に何もない
		    {
		      dice.rotate(dir);
		      h--;
		      y=ny,x=nx;
		      ok=false;//まだ落ち続けられる
		      break;
		    }
		}
	      if(ok)//もう落ちれない
		{
		  field[h][y][x]=dice.get(TOP);
		  break;
		}
	    }
	}
      vector<int> ans(6,0);
      for (int y = 0; y < MAXN; ++y)
	{
	  for (int x = 0; x < MAXN; ++x)
	    {
	      for(int h=MAXN-1;h>=0;h--)
		{
		  //同じx,yについては,一番高いところにあるものだけ数える.
		  if(field[h][y][x]>0)
		    {
		      ans[field[h][y][x]-1]++;
		      break;
		    }
		}
	    }
	}
      for(int i=0;i<6;i++)
	{
	  cout << ans[i];
	  if(i!=5) cout << ' ';
	}
      cout << endl;
    }
  return 0;
 
}



Measured memory_bytes: 36764