#include <vector>
#include <iostream>
#include <utility>
#include <algorithm>
#include <string>
#include <deque>
#include <tuple>
#include <queue>
#include <functional>
#include <cmath>
#include <iomanip>
#include <map>
#include <set>
#include <numeric>
#include <unordered_map>
#include <unordered_set>
#include <complex>
#include <iterator>
#include <array>
//cin.sync_with_stdio(false);
//streambuf
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<double, double> pdd;
using vi = vector<int>;
using vll = vector<ll>;
using vpii = vector<pii>;
using ti3 = tuple<int, int, int>;
using vti3 = vector<ti3>;
template<class T, int s>using va = vector<array<T, s>>;
template<class T, class T2> using umap = unordered_map<T, T2>;
template<class T> using uset = unordered_set<T>;
template<class T, class S> void cmin(T &a, const S &b) { if (a > b)a = b; }
template<class T, class S> void cmax(T &a, const S &b) { if (a < b)a = b; }
#define ALL(a) a.begin(),a.end()
#define rep(i,a) for(int i=0;i<a;i++)
#define rep1(i,a) for(int i=1;i<=a;i++)
#define rrep(i,a) for(int i=(a)-1;i>=0;i--)
#define rrep1(i,a) for(int i=a;i;i--)
const ll mod = 1000000007;
#define REP rep
template<class T>using heap = priority_queue<T, vector<T>, greater<T>>;
template<class T>using pque = priority_queue<T, vector<T>, function<T(T, T)>>;
template <class T>
inline void hash_combine(size_t & seed, const T & v) {
	hash<T> hasher;
	seed ^= hasher(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
}
namespace std {
	template<typename S, typename T> struct hash<pair<S, T>> {
		inline size_t operator()(const pair<S, T> & v) const {
			size_t seed = 0;
			hash_combine(seed, v.first);
			hash_combine(seed, v.second);
			return seed;
		}
	};
	// Recursive template code derived from Matthieu M.
	template <class Tuple, size_t Index = std::tuple_size<Tuple>::value - 1>
	struct HashValueImpl{
		static void apply(size_t& seed, Tuple const& tuple){
			HashValueImpl<Tuple, Index - 1>::apply(seed, tuple);
			hash_combine(seed, std::get<Index>(tuple));
		}
	};
	template <class Tuple>
	struct HashValueImpl<Tuple, 0>{
		static void apply(size_t& seed, Tuple const& tuple){
			hash_combine(seed, std::get<0>(tuple));
		}
	};
	template <typename ... TT>
	struct hash<std::tuple<TT...>>{
		size_t operator()(std::tuple<TT...> const& tt) const{
			size_t seed = 0;
			HashValueImpl<std::tuple<TT...> >::apply(seed, tt);
			return seed;
		}
	};
}
template<class T>int id(vector<T> &a, T b) {
	return lower_bound(ALL(a), b) - a.begin();
}
//end of lib
int r[6][6];
int main() {
	vi x = { 0,1,0,-1,0 }, off{ 1,1,0,0 };
	rep1(i, 6)rep1(j, 6) {
		if (i == j || i + j == 7)continue;
		int t = 1, f = 5, r = 4;
		if (i == 6)t = 6, r = 3;
		else if (i != 1) {
			while (f != i) {
				swap(f, r);
				r = 7 - r;
			}
			swap(t, f);
			f = 7 - f;
		}
		while (f != j) {
			swap(f, r);
			r = 7 - r;
		}
		::r[i][j] = r;
	}
	int n;
	while (cin >> n, n) {
		umap<pii, vector<pii>> m;
		vpii s(n);
		rep(i, n)cin >> s[i].first >> s[i].second;
		for (auto &si : s) {
			pii s2 = si;
			pii pos = {}, to = {};
			for (;;) {
				int h = m[pos].size();
				int t = 0, d = -1;
				to = pos;
				rep(i, 4) {
					if (m[pii{ pos.first + x[i],pos.second + x[i + 1] }].size() < h) {
						int t2 = (i & 1 ? r[s2.first][s2.second] : s2.second);
						if (off[i])t2 = 7 - t2;
						if (t2 < 4)continue;
						if (t < t2)t = t2, d = i;
					}
				}
				if (t == 0) {
					m[pos].push_back(s2);
					break;
				}
				pii s3;
				switch (d) {
				case 0:
					s3 = { 7 - t,7 - s2.first };
					break;
				case 1:
					s3 = { 7 - t,s2.second };
					break;
				case 2:
					s3 = { 7 - t,s2.first };
					break;
				case 3:
					s3 = { 7 - t,s2.second };
					break;
				}
				s2 = s3;
				pos = { pos.first + x[d],pos.second + x[d + 1] };
			}
		}
		vi ans(7);
		for (auto &x : m) {
			if (!x.second.empty())ans[x.second.back().first]++;
		}
		rep1(i, 5)cout << ans[i] << " ";
		cout << ans[6] << endl;
	}
}

Measured memory_bytes: 3132