#include<iostream>
#include<cmath>
#include<algorithm>
#include<vector>
#include<cassert>
#include<cstdio>
#include<climits>

#define REP(i,s,n) for(int i=s;i<n;i++)
#define rep(i,n) REP(i,0,n)
#define IINF (INT_MAX)

using namespace std;

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

enum FACE { TOP, BOTTOM, FRONT, BACK, LEFT, RIGHT };
template <class T>
class dice {
public:
  dice() {
    id[TOP] = 0; id[FRONT] = 1; id[LEFT] = 2;
    id[RIGHT] = 3; id[BACK] = 4; id[BOTTOM] = 5;
  }
  T& operator[] (FACE f) { return var[id[f]]; }
  const T& operator[] (FACE f) const { return var[id[f]]; }
  bool operator==(const dice<T>& b) const {
    const dice<T> &a = *this;
    return a[TOP] == b[TOP] && a[BOTTOM] == b[BOTTOM] &&
      a[FRONT] == b[FRONT] && a[BACK] == b[BACK] &&
      a[LEFT] == b[LEFT] && a[RIGHT] == b[RIGHT];
  }
  void roll_x() { roll(TOP, BACK, BOTTOM, FRONT); }
  void roll_y() { roll(TOP, LEFT, BOTTOM, RIGHT); }
  void roll_z() { roll(FRONT, RIGHT, BACK, LEFT); }
  vector<dice> all_rolls() {
    vector<dice> ret;
    for (int k = 0; k < 6; (k&1?roll_y():roll_x()),++k)
      for (int i = 0; i < 4; roll_z(), ++i)
        ret.push_back(*this);
    return ret;
  }
  bool equivalent_to(const dice& di) {
    for (int k = 0; k < 6; (k&1?roll_y():roll_x()),++k)
      for (int i = 0; i < 4; roll_z(), ++i)
        if (*this == di) return true;
    return false;
  }

private:
  void roll(FACE a, FACE b, FACE c, FACE d) {
    T tmp = id[a];
    id[a] = id[b]; id[b] = id[c];
    id[c] = id[d]; id[d] = tmp;
  }
  T var[6];
  int id[6];
};

FACE face[] = {TOP,BOTTOM,FRONT,BACK,LEFT,RIGHT};

dice<int> makeDice(int top,int front)
{
  dice<int> ret;
  ret[TOP] = top, ret[BOTTOM] = 5-top;
  ret[FRONT] = front, ret[BACK] = 5-front;
  int idx = IINF;
  for(int i=0;i<4;i++)
    {
      if(around[top][i] == front)
	{
	  idx = i+1;
	  break;
	}
    }
  assert(idx != IINF);
  idx %= 4;
  ret[RIGHT] = around[top][idx], ret[LEFT] = 5-around[top][idx];
  return ret;
}

const int diff = 250;
int field[500][500];
int height[500][500];
FACE dir[] = {FRONT,RIGHT,BACK,LEFT};
int dx[] = {0,1,0,-1};
int dy[] = {1,0,-1,0};

void dfs(int x,int y,dice<int>& obj)
{
  int decide = IINF;
  rep(i,4)
    {
      FACE f = dir[i];
      if(obj[f] == 3 || obj[f] == 4 || obj[f] == 5)
	{
	  if(decide == IINF || obj[dir[decide]] < obj[f])
	    {
	      if(height[y][x] > height[y+dy[i]][x+dx[i]])
		{
		  decide = i;
		}
	    }
	}
    }

  if(decide == IINF)
    {
      height[y][x]++;
      field[y][x] = obj[TOP];
      return;
    }

  if(decide == 0)
    {
      obj.roll_x();
    }
  else if(decide == 1)
    {
      obj.roll_y();
    }
  else if(decide == 2)
    {
      obj.roll_x();      obj.roll_x();      obj.roll_x();
    }
  else
    {
      obj.roll_y();      obj.roll_y();      obj.roll_y();
    }
  dfs(x+dx[decide],y+dy[decide],obj);

}

int main()
{
  int n;
  while(cin >> n,n)
    {
      rep(i,500)rep(j,500)field[i][j] = IINF,height[i][j] = 0;
      int t,f;
      rep(i,n)
	{
	  cin >> t >> f;
	  t--,f--;
	  dice<int> obj = makeDice(t,f);
	  dfs(diff,diff,obj);
	}
      
      int ans[6];
      rep(i,6)ans[i] = 0;
      rep(y,500)
	{
	  rep(x,500)
	    {
	      if(field[y][x] == IINF)continue;
	      ans[field[y][x]]++;
	    }
	}
      rep(i,6)
	{
	  if(i)cout << " ";
	  cout << ans[i];
	}
      cout << endl;

    }
  return 0;
}

Measured memory_bytes: 3112