Problem:
Biased Dice
Professor Random, known for his research on randomized algorithms, is now conducting an experiment on biased dice.  His experiment consists of dropping a number of dice onto a plane, one after another from a fixed position above the plane.  The dice fall onto the plane or dice already there, without rotating, and may roll and fall according to their property.  Then he observes and records the status of the stack formed on the plane, specifically, how many times each number appears on the faces visible from above. All the dice have the same size and their face numbering is identical, which we show in Figure C-1.
Figure C-1: Numbering of a die
The dice have very special properties, as in the following.
(1) Ordinary dice can roll in four directions, but the dice used in this experiment never roll in the directions of faces 1, 2 and 3; they can only roll in the directions of faces 4, 5 and 6.  In the situation shown in Figure C-2, our die can only roll to one of two directions.
Figure C-2: An ordinary die and a biased die
(2) The die can only roll when it will fall down after rolling, as shown in Figure C-3.  When multiple possibilities exist, the die rolls towards the face with the largest number among those directions it can roll to.
Figure C-3: A die can roll only when it can fall
(3) When a die rolls, it rolls exactly 90 degrees, and then falls straight down until its bottom face touches another die or the plane, as in the case [B] or [C] of Figure C-4.
(4) After rolling and falling, the die repeatedly does so according to the rules (1) to (3) above.
Figure C-4: Example stacking of biased dice
For example, when we drop four dice all in the same orientation, 6 at the top and 4 at the front, then a stack will be formed as shown in Figure C-4.
Figure C-5: Example records
After forming the stack, we count the numbers of faces with 1 through 6 visible from above and record them.  For example, in the left case of Figure C-5, the record will be "0 2 1 0 0 0", and in the right case, "0 1 1 0 0 1".
Input
The input consists of several datasets each in the following format.
n
t
1
f
1
t
2
f
2
...
t
n
f
n
Here,
n
(1 ≤
n
≤ 100) is an integer and is the number of the dice to be dropped.
t
i
and
f
i
(1 ≤
t
i
,
f
i
≤ 6) are two integers separated by a space and represent the numbers on the top and the front faces of the
i
-th die, when it is released, respectively.
The end of the input is indicated by a line containing a single zero.
Output
For each dataset, output six integers separated by a space. The integers represent the numbers of faces with 1 through 6 correspondingly, visible from above. There may not be any other characters in the output.
Sample Input
4
6 4
6 4
6 4
6 4
2
5 3
5 3
8
4 2
4 2
4 2
4 2
4 2
4 2
4 2
4 2
6
4 6
1 5
2 3
5 3
2 4
4 2
0
Output for the Sample Input
0 1 1 0 0 1
1 0 0 0 1 0
1 2 2 1 0 0
2 3 0 0 0 0

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
using namespace std;

const long long MOD1 = 1000000007;
const long long MOD2 = 998244353;
#define all(v) v.begin(), v.end()
#define rall(a) a.rbegin(), a.rend()
#define fi first
#define se second
// #define endl "\n"

#define chmax(x, y) x = max(x, y)
#define chmin(x, y) x = min(x, y)

template <typename T>
using vc = vector<T>; // prioriy_queueに必要なのでここにこれ書いてます
template <typename T>
using vv = vc<vc<T>>;
#define int long long
using ll = long long;
ll INF = 2e18;

#ifdef ONLINE_JUDGE
// ジャッジ環境ではデバッグマクロを無効化
#define debug_x(x) \
    do             \
    {              \
    } while (0)
#define debug_vc(v) \
    do              \
    {               \
    } while (0)
#define debug_vv(v) \
    do              \
    {               \
    } while (0)
#else
// ローカルではデバッグ出力
#define debug_x(x) cout << #x << " = " << (x) << endl
#define debug_vc(v)                    \
    {                                  \
        cout << #v << endl;            \
        ll n = size(v);                \
        rep(i, n) cout << v[i] << ' '; \
        cout << endl;                  \
    } // 一次元配列を出力する
#define debug_vv(v)                                        \
    {                                                      \
        cout << #v << endl;                                \
        ll n = size(v);                                    \
        rep(i, n)                                          \
        {                                                  \
            rep(j, size(v[i])) { cout << v[i][j] << ' '; } \
            cout << endl;                                  \
        }                                                  \
    } // 二次元配列を出力する
#endif

#define rep(i, n) for (ll i = 0; i < (n); ++i)
#define rrep(i, n) for (ll i = 1; i <= (n); ++i)
#define drep(i, n) for (ll i = (n) - 1; i >= 0; --i)
#define nfor(i, s, n) for (ll i = s; i < n; i++)        // i=s,s+1...n-1 ノーマルfor
#define dfor(i, s, n) for (ll i = (s) - 1; i >= n; i--) // s-1スタートでnまで落ちる

using ld = long double;
using bl = bool;

template <class T>
using pq = priority_queue<T, vc<T>>; // 大きい順
template <class T>
using pq_g = priority_queue<T, vc<T>, greater<T>>; // 小さい順

using vl = vc<ll>;
using vvl = vv<ll>;
using vvvl = vv<vl>;
using vvvvl = vv<vvl>;
using vs = vc<string>;
using vvs = vv<string>;
using vb = vc<bl>;
using vvb = vv<bl>;
using vvvb = vv<vb>;
using vld = vc<ld>;
using vvld = vv<ld>;
using vvvld = vv<vld>;
using P = pair<ll, ll>;
using vP = vc<P>;
using vvP = vc<vP>;
using vvvP = vv<vP>;

#define pb push_back

#define YES cout << "Yes" << endl
#define NO cout << "No" << endl
#define YN                     \
    {                          \
        cout << "Yes" << endl; \
    }                          \
    else                       \
    {                          \
        cout << "No" << endl;  \
    } // if(a==b)YN;
#define dame cout << -1 << endl

string dir = "DRUL"; // 第4象限の場合

bool out_grid(ll i, ll j, ll h, ll w)
{ // trueならcontinue
    return (!(0 <= i && i < h && 0 <= j && j < w));
}

bl solve()
{
    ll n;
    cin >> n;
    if (n == 0)
        return 0;
    vl t(n), f(n);
    rep(i, n)
    {
        cin >> t[i] >> f[i];
    }
    vvl die = {{}, {2, 3, 5, 4}, {1, 4, 6, 3}, {1, 2, 6, 5}, {1, 5, 6, 2}, {1, 3, 6, 4}, {2, 4, 5, 3}};
    map<P, ll> h;
    for (ll x = -200; x <= 200; x++)
    {
        for (ll y = -200; y <= 200; y++)
        {
            h[{x, y}] = 0;
        }
    }
    map<P, ll> me;
    vl ans(7);
    vl di = {1, 0, -1, 0}; // vl di={1,1,0,-1,-1,-1,0,1};
    vl dj = {0, 1, 0, -1}; // vl dj={0,1,1,1,0,-1,-1,-1};
    rep(i, n)
    {
        ll top = t[i];
        ll front = f[i];
        P cur = {0, 0};
        // cout << "====================" << endl;
        while (true)
        {
            // debug_x(top);
            // debug_x(front);
            // debug_vc(ans);
            // debug_x(cur.fi);
            // debug_x(cur.se);
            // debug_x(h[cur]);
            // debug_x(me[cur]);
            ll dirIdx = -1;
            ll maxMe = -1;
            rep(j, 4)
            {
                if (die[top][j] == front)
                {
                    dirIdx = j;
                }
            }
            rep(k, 4)
            {
                auto [ii, jj] = cur;
                ll ni = ii + di[k];
                ll nj = jj + dj[k];
                P nex = {ni, nj};
                // debug_x(ni);
                // debug_x(nj);
                // debug_x(h[cur]);
                // debug_x(h[nex]);
                // debug_x(die[top][(dirIdx + k) % 4]);
                if (h[cur] - h[nex] <= 0)
                    continue;
                maxMe = max(maxMe, die[top][(dirIdx + k) % 4]);
            }
            if (maxMe <= 3)
            {
                h[cur]++;
                ans[me[cur]]--;
                ans[top]++;
                me[cur] = top;
                break;
            }
            rep(k, 4)
            {
                auto [ii, jj] = cur;
                ll ni = ii + di[k];
                ll nj = jj + dj[k];
                if (h[{ii, jj}] - h[{ni, nj}] <= 0)
                    continue;
                if (die[top][(dirIdx + k) % 4] != maxMe)
                    continue;
                cur = {ni, nj};
                if (k == 0)
                {
                    front = top;
                }
                if (k == 2)
                {
                    front = 7 - top;
                }
                top = 7 - maxMe;
                break;
            }
        }
    }

    rrep(i, 6)
    {
        cout << ans[i];
        if (i != 6)
            cout << ' ';
    }
    cout << endl;

    return 1;
}

signed main()
{
    // g++ -std=c++20 -g -fsanitize=undefined,address
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    while (true)
    {
        if (!solve())
            break;
    }

    return 0;
}

/*
shift+alt+Fで成形
f2で変数名変更

スニペット
basic
 m:atcoder以外用
 ma:ABC/ARC用
 mahc:AHC用
math
 floor:床関数
 ceil:天井関数
 comv:二項係数
 modpow: a^b mod m
 GCD:最大公約数
 extGCD:拡張ユークリッド互除法
 PFD:素因数分解
 isprime:エラトステネスの篩
 matrixpow:行列累乗
data_structure
 seg:セグメント木
technic
 Compress:座標圧縮
 runlength:ランレングス圧縮
graph
 warshall:ワーシャルフロイド法
 dfs:深さ優先探索
 bfs:幅優先探索
 LCA:最近共通祖先
*/
accuracy: 1
time_ms: 3990
memory_kb: 13372
final_rank: 18

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
#define dbg(x) 
#define ALL(v) v.begin(), v.end()

using pii = pair<int,int>;
constexpr int m = 201;
int offset = 100;
array<array<vector<pii>,7>,7> nx;
array<array<vector<pii>,7>,7> dir;

void solve()
{
  int n;
  cin >> n;
  if (n == 0) exit(0);
  dbg("HELLO")
  
    vector height(m, vector<int>(m));
    vector top(m, vector<int>(m));
  for (int i = 0; i < n; ++i) {
    int t,f;
    cin >> t >> f;
    int x=offset, y=offset;

    while (true) {
      int k = nx[t][f].size();
      assert(nx[t][f].size() == dir[t][f].size());
      dbg(k)
      int ma = -1;

      for (int j = 0; j < k; ++j) {
        dbg(j)
        int x2 = x + dir[t][f][j].first;
        int y2 = y + dir[t][f][j].second;
        if (height[y2][x2] < height[y][x]
            && (ma == -1 || 7-nx[t][f][j].first > 7-nx[t][f][ma].first)) {
          ma = j;
        }
        dbg(j)
      }
      if (ma == -1) {
        top[y][x] = t;
        height[y][x]++;
        break;
      }
      else {
        dbg(dir[t][f].size())
        dbg(nx[t][f].size())
        dbg(ma)
        x += dir[t][f].at(ma).first;
        dbg("A")
        y += dir[t][f].at(ma).second;
        dbg("B")
        tie(t,f) = nx[t][f].at(ma);
        dbg("D")
      }
    }
  }
  vector<int> ans(7);
  for (int i = 0; i < m; ++i) {
    for (int j = 0; j < m; ++j) {
      ans[top[i][j]]++;
    }
  }
  for (int i = 1; i <= 6; ++i) {
    cout << ans[i] << " \n"[i==6];
  }
//   if (n==100) {
//     for (int i = 0; i < m; ++i) {
//         for (int j = 0; j < m; ++j) {
//             cout << height[i][j];
//         }
//         cout << '\n';
//     }
//   }
  dbg("X")
}

array<int,7> left(array<int,7> v) {
  array<int, 7> ret;
  ret[1] = v[3];
  ret[2] = v[2];
  ret[3] = v[6];
  ret[4] = v[1];
  ret[5] = v[5];
  ret[6] = v[4];
  return ret;
}

array<int,7> right(array<int,7> v) {
  array<int, 7> ret;
  ret[1] = v[4];
  ret[2] = v[2];
  ret[3] = v[1];
  ret[4] = v[6];
  ret[5] = v[5];
  ret[6] = v[3];
  return ret;
}
array<int,7> up(array<int,7> v) {
  array<int, 7> ret;
  ret[1] = v[2];
  ret[2] = v[6];
  ret[3] = v[3];
  ret[4] = v[4];
  ret[5] = v[1];
  ret[6] = v[5];
  return ret;
}

array<int,7> down(array<int,7> v) {
  array<int, 7> ret;
  ret[1] = v[5];
  ret[2] = v[1];
  ret[3] = v[3];
  ret[4] = v[4];
  ret[5] = v[6];
  ret[6] = v[2];
  return ret;
}

int main()
{
  array<array<int,7>,7> x;
  x[1][2] = 3;
  x[1][3] = 5;
  x[1][4] = 2;
  x[1][5] = 4;
  x[2][1] = 4;
  x[2][3] = 1;
  x[2][4] = 6;
  x[2][6] = 3;
  x[3][1] = 2;
  x[3][2] = 6;
  x[3][5] = 1;
  x[3][6] = 5;
  x[4][1] = 5;
  x[4][2] = 1;
  x[4][5] = 6;
  x[4][6] = 2;
  x[5][1] = 3;
  x[5][3] = 6;
  x[5][4] = 1;
  x[5][6] = 4;
  x[6][2] = 4;
  x[6][3] = 2;
  x[6][4] = 5;
  x[6][5] = 3;
  for (int t = 1; t <= 6; ++t) {
    for (int f = 1; f <= 6; ++f) {
      array<int,7> vec;
      fill(ALL(vec), 0);
      vec[1] = t;
      vec[2] = f;
      vec[3] = x[t][f];
      vec[4] = 7 - vec[3];
      vec[5] = 7 - vec[2];
      vec[6] = 7 - vec[1];
      {
        auto res = left(vec);
        if (4 <= res[6] && res[6] <= 6) {
          dir[t][f].emplace_back(-1, 0);
          nx[t][f].emplace_back(res[1], res[2]);
        }
      }
      {
        auto res = right(vec);
        if (4 <= res[6] && res[6] <= 6) {
          dir[t][f].emplace_back(1, 0);
          nx[t][f].emplace_back(res[1], res[2]);
        }
      }
      {
        auto res = up(vec);
        if (4 <= res[6] && res[6] <= 6) {
          dir[t][f].emplace_back(0,-1);
          nx[t][f].emplace_back(res[1], res[2]);
        }
      }
      {
        auto res = down(vec);
        if (4 <= res[6] && res[6] <= 6) {
          dir[t][f].emplace_back(0, 1);
          nx[t][f].emplace_back(res[1], res[2]);
        }
      }
    }
  }
  while (true) solve();
}
accuracy: 1
time_ms: 10
memory_kb: 3780
final_rank: 7

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}

#include <unistd.h>

namespace fastio {
static constexpr uint32_t SZ = 1 << 17;
char ibuf[SZ];
char obuf[SZ];
char out[100];
// pointer of ibuf, obuf


uint32_t pil = 0, pir = 0, por = 0;

struct Pre {
    char num[10000][4];
    constexpr Pre() : num() {
        for (int i = 0; i < 10000; i++) {
            int n = i;
            for (int j = 3; j >= 0; j--) {
                num[i][j] = n % 10 | '0';
                n /= 10;
            }
        }
    }
} constexpr pre;

inline void load() {
    memmove(ibuf, ibuf + pil, pir - pil);
    pir = pir - pil + fread(ibuf + pir - pil, 1, SZ - pir + pil, stdin);
    pil = 0;
    if (pir < SZ)
        ibuf[pir++] = '\n';
}

inline void flush() {
    fwrite(obuf, 1, por, stdout);
    por = 0;
}

void rd(char &c) {
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
}

void rd(string &x) {
    x.clear();
    char c;
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
    do {
        x += c;
        if (pil == pir)
            load();
        c = ibuf[pil++];
    } while (!isspace(c));
}

template <typename T> void rd_real(T &x) {
    string s;
    rd(s);
    x = stod(s);
}

template <typename T> void rd_integer(T &x) {
    if (pil + 100 > pir)
        load();
    char c;
    do
        c = ibuf[pil++];
    while (c < '-');
    bool minus = 0;
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (c == '-') {
            minus = 1, c = ibuf[pil++];
        }
    }
    x = 0;
    while ('0' <= c) {
        x = x * 10 + (c & 15), c = ibuf[pil++];
    }
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (minus)
            x = -x;
    }
}

void rd(int &x) {
    rd_integer(x);
}
void rd(ll &x) {
    rd_integer(x);
}
void rd(i128 &x) {
    rd_integer(x);
}
void rd(uint &x) {
    rd_integer(x);
}
void rd(ull &x) {
    rd_integer(x);
}
void rd(u128 &x) {
    rd_integer(x);
}
void rd(double &x) {
    rd_real(x);
}
void rd(long double &x) {
    rd_real(x);
}

template <class T, class U> void rd(pair<T, U> &p) {
    return rd(p.first), rd(p.second);
}
template <size_t N = 0, typename T> void rd_tuple(T &t) {
    if constexpr (N < std::tuple_size<T>::value) {
        auto &x = std::get<N>(t);
        rd(x);
        rd_tuple<N + 1>(t);
    }
}
template <class... T> void rd(tuple<T...> &tpl) {
    rd_tuple(tpl);
}

template <size_t N = 0, typename T> void rd(array<T, N> &x) {
    for (auto &d : x)
        rd(d);
}
template <class T> void rd(vector<T> &x) {
    for (auto &d : x)
        rd(d);
}

void read() {}
template <class H, class... T> void read(H &h, T &...t) {
    rd(h), read(t...);
}

void wt(const char c) {
    if (por == SZ)
        flush();
    obuf[por++] = c;
}
void wt(const string s) {
    for (char c : s)
        wt(c);
}
void wt(const char *s) {
    size_t len = strlen(s);
    for (size_t i = 0; i < len; i++)
        wt(s[i]);
}

template <typename T> void wt_integer(T x) {
    if (por > SZ - 100)
        flush();
    if (x < 0) {
        obuf[por++] = '-', x = -x;
    }
    int outi;
    for (outi = 96; x >= 10000; outi -= 4) {
        memcpy(out + outi, pre.num[x % 10000], 4);
        x /= 10000;
    }
    if (x >= 1000) {
        memcpy(obuf + por, pre.num[x], 4);
        por += 4;
    } else if (x >= 100) {
        memcpy(obuf + por, pre.num[x] + 1, 3);
        por += 3;
    } else if (x >= 10) {
        int q = (x * 103) >> 10;
        obuf[por] = q | '0';
        obuf[por + 1] = (x - q * 10) | '0';
        por += 2;
    } else
        obuf[por++] = x | '0';
    memcpy(obuf + por, out + outi + 4, 96 - outi);
    por += 96 - outi;
}

template <typename T> void wt_real(T x) {
    ostringstream oss;
    oss << fixed << setprecision(15) << double(x);
    string s = oss.str();
    wt(s);
}

void wt(int x) {
    wt_integer(x);
}
void wt(ll x) {
    wt_integer(x);
}
void wt(i128 x) {
    wt_integer(x);
}
void wt(uint x) {
    wt_integer(x);
}
void wt(ull x) {
    wt_integer(x);
}
void wt(u128 x) {
    wt_integer(x);
}
void wt(double x) {
    wt_real(x);
}
void wt(long double x) {
    wt_real(x);
}

template <class T, class U> void wt(const pair<T, U> val) {
    wt(val.first);
    wt(' ');
    wt(val.second);
}
template <size_t N = 0, typename T> void wt_tuple(const T t) {
    if constexpr (N < std::tuple_size<T>::value) {
        if constexpr (N > 0) {
            wt(' ');
        }
        const auto x = std::get<N>(t);
        wt(x);
        wt_tuple<N + 1>(t);
    }
}
template <class... T> void wt(tuple<T...> tpl) {
    wt_tuple(tpl);
}
template <class T, size_t S> void wt(const array<T, S> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}
template <class T> void wt(const vector<T> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}

void print() {
    wt('\n');
}
template <class Head, class... Tail> void print(Head &&head, Tail &&...tail) {
    wt(head);
    if (sizeof...(Tail))
        wt(' ');
    print(forward<Tail>(tail)...);
}
void __attribute__((destructor)) _d() {
    flush();
}
} // namespace fastio


using fastio::flush;
using fastio::print;
using fastio::read;

inline void first(bool i = true) {
    print(i ? "first" : "second");
}
inline void Alice(bool i = true) {
    print(i ? "Alice" : "Bob");
}
inline void Takahashi(bool i = true) {
    print(i ? "Takahashi" : "Aoki");
}
inline void yes(bool i = true) {
    print(i ? "yes" : "no");
}
inline void Yes(bool i = true) {
    print(i ? "Yes" : "No");
}
inline void No() {
    print("No");
}
inline void YES(bool i = true) {
    print(i ? "YES" : "NO");
}
inline void NO() {
    print("NO");
}
inline void Yay(bool i = true) {
    print(i ? "Yay!" : ":(");
}
inline void Possible(bool i = true) {
    print(i ? "Possible" : "Impossible");
}
inline void POSSIBLE(bool i = true) {
    print(i ? "POSSIBLE" : "IMPOSSIBLE");
}

/**
 * @brief Fast IO
 */

pair<int,int> Top[6] = {{2,3},{3,1},{1,2},{5,6},{6,4},{4,5}};

int H[201][201] = {};
int B[201][201] = {};

struct Dice {
    int A[6];
    int X, Y;

    Dice(int P, int Q) {
        A[0] = P, A[1] = Q;
        rep(i,0,6) {
            int F[4] = {Top[i].first, Top[i].second, 7-Top[i].first, 7-Top[i].second};
            rep(j,0,4) {
                if (P == F[j] && Q == (F[(j+1)%4])) {
                    A[2] = i + 1;
                }
            }
        }
        rep(i,3,6) A[i] = 7 - A[5-i];
        X = 100, Y = 100;
    }
};

void Rot1(Dice& D) {
    D.X++;
    Dice Ret(D.A[4],D.A[0]);
    rep(i,0,6) D.A[i] = Ret.A[i];
}

void Rot2(Dice& D) {
    D.Y++;
    Dice Ret(D.A[3],D.A[1]);
    rep(i,0,6) D.A[i] = Ret.A[i];
}

void Rot3(Dice& D) {
    D.Y--;
    Dice Ret(D.A[2],D.A[1]);
    rep(i,0,6) D.A[i] = Ret.A[i];
}

void Rot4(Dice& D) {
    D.X--;
    Dice Ret(D.A[1],D.A[5]);
    rep(i,0,6) D.A[i] = Ret.A[i];
}

void Rot(Dice& D, int ID) {
    if (ID == 1) Rot1(D);
    if (ID == 2) Rot2(D);
    if (ID == 3) Rot3(D);
    if (ID == 4) Rot4(D);
    return;
}

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

bool Roll(Dice& D) {
    rrep(i,4,7) {
        rep(j,1,5) {
            if (D.A[j] != i) continue;
            int X = D.X, Y = D.Y;
            int NX = X + dx[j], NY = Y + dy[j];
            if (H[NX][NY] < H[X][Y]) {
                Rot(D,j);
                return true;
            }
        }
    }
    return false;
}

int main() {
while(1) {
    int N;
    cin >> N;
    if (N == 0) return 0;
    rep(i,0,201) rep(j,0,201) H[i][j] = 0, B[i][j] = 0;
    rep(i,0,N) {
        int P, Q;
        cin >> P >> Q;
        Dice D(P,Q);
        while(1) {
            if (!Roll(D)) break;
        }
        H[D.X][D.Y]++;
        B[D.X][D.Y] = D.A[0];
    }
    int ANS[6] = {};
    rep(i,0,201) {
        rep(j,0,201) {
            if (B[i][j] >= 1) ANS[B[i][j] - 1]++;
        }
    }
    rep(i,0,6) cout << ANS[i] << (i == 5 ? '\n' : ' ');
}
}
accuracy: 1
time_ms: 10
memory_kb: 3736
final_rank: 5

code_snippet: #line 1 "main.cpp"
#include<bits/stdc++.h>
using namespace std;

#line 1 "/mnt/c/Users/hope_/ComPro/Libraries/Library/other/Dice.hpp"
// 面と変数の対応付けは Dice Stamp (https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2703) における
// (l, r, f, b, d, u) から (xn, xp, yn, yp, zn, zp) に置き換えたものとする。（右手座標系）
// 面の値（Label）のみを保持。一致判定などにおいて向きは非考慮。
// Verified Link1: Dice Stamp (https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2703)

struct Dice{
    static constexpr int arr[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 xnL, xpL, ynL, ypL, znL, zpL; // labels
    int xco, yco, zco; // x, y, z coordinate (for rolling the dice)

    Dice() : xnL(2), xpL(5), ynL(3), ypL(4), znL(6), zpL(1), xco(0), yco(0), zco(0) {}
    
    Dice(int xn, int xp, int yn, int yp, int zn, int zp, int xco = 0, int yco = 0, int zco = 0) :
    xnL(xn), xpL(xp), ynL(yn), ypL(yp), znL(zn), zpL(zp), xco(xco), yco(yco), zco(zco) {}

    // after initialization, make normal dice (set -1 to unknown label)
    // 右手座標系
    void makeNormalDice(int xn, int xp, int yn, int yp, int zn, int zp){
        if(xn == -1 && xp != -1){ xn = 7 - xp; }
        if(xp == -1 && xn != -1){ xp = 7 - xn; }
        if(yn == -1 && yp != -1){ yn = 7 - yp; }
        if(yp == -1 && yn != -1){ yp = 7 - yn; }
        if(zn == -1 && zp != -1){ zn = 7 - zp; }
        if(zp == -1 && zn != -1){ zp = 7 - zn; }
        if(xn == -1){
            assert(xp == -1 && yn != -1 && zn != -1);
            xp = arr[zp][yp];
            xn = 7 - xp;
        }
        if(yn == -1){
            assert(yp == -1 && xn != -1 && zn != -1);
            yp = arr[xp][zp];
            yn = 7 - yp;
        }
        if(zn == -1){
            assert(zp == -1 && xn != -1 && yn != -1);
            zp = arr[yp][xp];
            zn = 7 - zp;
        }
        xnL = xn, xpL = xp;
        ynL = yn, ypL = yp;
        znL = zn, zpL = zp;
    }

    // shift 4 params to left.
    // (a, b, c, d) -> (b, c, d, a)
    void shift(int& a, int& b, int& c, int& d){
        int tmp = a;
        a = b, b = c, c = d, d = tmp;
    }

    void rotXY(bool clockwise = false){
        if(clockwise) shift(xpL, ypL, xnL, ynL);
        else shift(xpL, ynL, xnL, ypL);
    }
    void rotYZ(bool clockwise = false){
        if(clockwise) shift(ypL, zpL, ynL, znL);
        else shift(ypL, znL, ynL, zpL);
    }
    void rotXZ(bool clockwise = false){
        if(clockwise) shift(xpL, zpL, xnL, znL);
        else shift(xpL, znL, xnL, zpL);
    }

    // roll dice
    void rotB(){ rotYZ(true); yco++; }
    void rotF(){ rotYZ(false);  yco--; }
    void rotR(){ rotXZ(true); xco++; }
    void rotL(){ rotXZ(false);  xco--; }

    friend ostream& operator<<(ostream& os, const Dice& dice){
        os << "(xnL, xpL, ynL, ypL, znL, zpL) = (";
        os << dice.xnL << ", " << dice.xpL << ", ";
        os << dice.ynL << ", " << dice.ypL << ", ";
        os << dice.znL << ", " << dice.zpL << "), "; 
        os << "(x, y, z) = (" << dice.xco << ", " << dice.yco << ", " << dice.zco << ")"; 
        return os;
    }
};
#line 5 "main.cpp"

int main(){
    while(1){
        int N; cin >> N;
        if(N == 0) break;
        const int MAX_N = 210;
        const int CTR = 105;
        vector<vector<int>> height(MAX_N, vector<int>(MAX_N, 0));
        vector<vector<int>> val(MAX_N, vector<int>(MAX_N, 0));

        for(int i = 0; i < N; i++){
            int t, f; cin >> t >> f;
            Dice dice;
            dice.makeNormalDice(-1, f, -1, -1, -1, t);
            dice.xco = CTR, dice.yco = CTR;
            dice.zco = height[CTR][CTR] + 1;
            // cout << dice << endl;
            while(1){
                bool flag = 0;
                for(int j = 6; j >= 4; j--){
                    if(dice.xnL == j && dice.zco > height[dice.xco - 1][dice.yco] + 1){
                        dice.rotL();
                        dice.zco = height[dice.xco][dice.yco] + 1;
                        flag = 1; break;
                    }
                    if(dice.xpL == j && dice.zco > height[dice.xco + 1][dice.yco] + 1){
                        dice.rotR();
                        dice.zco = height[dice.xco][dice.yco] + 1;
                        flag = 1; break;
                    }
                    if(dice.ynL == j && dice.zco > height[dice.xco][dice.yco - 1] + 1){
                        dice.rotF();
                        dice.zco = height[dice.xco][dice.yco] + 1;
                        flag = 1; break;
                    }
                    if(dice.ypL == j && dice.zco > height[dice.xco][dice.yco + 1] + 1){
                        dice.rotB();
                        dice.zco = height[dice.xco][dice.yco] + 1;
                        flag = 1; break;
                    }
                }
                if(!flag) break;
            }
            height[dice.xco][dice.yco] = dice.zco;
            val[dice.xco][dice.yco] = dice.zpL;
            // cout << dice << " " << height[dice.xco][dice.yco] << endl;
        }

        vector<int> ans(6);
        for(int i = 0; i < MAX_N; i++){
            for(int j = 0; j < MAX_N; j++){
                if(val[i][j] != 0) ans[val[i][j] - 1]++;
            }
        }

        for(int i = 0; i < 6; i++){
            cout << ans[i];
            if(i != 6 - 1) cout << " ";
        }
        cout << endl;
    }
}
accuracy: 1
time_ms: 10
memory_kb: 3704
final_rank: 3

code_snippet: #include<bits/stdc++.h>
using namespace std;

struct Dice{
    static constexpr int arr[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 a, b, c, d, e, f;
    
    Dice(int x, int y) : a(x), c(y) {
        //cout << x << " " << y << endl;
        d = 7 - c;
        f = 7 - a;
        e = arr[x][y];
        b = 7 - e;
        //cout << a << b << c << d << e << f << endl;
    }
    void rotU(){
        int tmp = a;
        a = c;
        c = f;
        f = d;
        d = tmp;
    }
    void rotD(){
        rotU();
        rotU();
        rotU();
    }
    void rotL(){
        int tmp = a;
        a = e;
        e = f;
        f = b;
        b = tmp;
    }
    void rotR(){
        rotL();
        rotL();
        rotL();
    }
};

int main(){
    while(1){
        int N; cin >> N;
        if(N == 0) break;
        const int PAR = 211;
        vector<vector<int>> G(PAR, vector<int>(PAR, 0));
        vector<vector<int>> val(PAR, vector<int>(PAR, 0));

        for(int _ = 0; _ < N; _++){
            int t, f; cin >> t >> f;
            Dice dice(t, f);

            int r = 103, c = 103;
            while(1){
                int mx = 0;
                // U
                if(dice.d > mx && G[r - 1][c] < G[r][c]) mx = dice.d;
                // D
                if(dice.c > mx && G[r + 1][c] < G[r][c]) mx = dice.c;
                // L
                if(dice.b > mx && G[r][c - 1] < G[r][c]) mx = dice.b;
                // R
                if(dice.e > mx && G[r][c + 1] < G[r][c]) mx = dice.e;

                if(mx <= 3) break;

                // U
                if(dice.d == mx){ dice.rotU(); r--; }
                // D
                if(dice.c == mx){ dice.rotD(); r++; }
                // L
                if(dice.b == mx){ dice.rotL(); c--; }
                // R
                if(dice.e == mx){ dice.rotR(); c++; }
            }
            assert(0 <= r && r < PAR);
            assert(0 <= c && c < PAR);
            G[r][c]++;
            val[r][c] = dice.a;
        }

        vector<int> ans(7, 0);
        for(int i = 0; i < PAR; i++){
            for(int j = 0; j < PAR; j++){
                assert(0 <= val[i][j] && val[i][j] <= 6);
                ans[val[i][j]]++;
            }
        }

        for(int i = 0; i < 6; i++){
            cout << ans[i + 1];
            if(i != 5) cout << " ";
        }
        cout << endl;
    }
}
accuracy: 1
time_ms: 10
memory_kb: 3712
final_rank: 4

code_snippet: #include <bits/stdc++.h>

namespace lib {

    using namespace std;
    template <typename T = int>
        class Dice {
            private:
                array<T, 6> data;
            public:
                int id_;
                Dice(int id_ = 0): id_(id_) {
                    iota(data.begin(), data.end(), 1);
                }
                Dice(const array<T, 6>& data, int id_ = 0): data(data), id_(id_) {}

                void rotate_north() {
                    T temp = data[5];
                    data[5] = data[4];
                    data[4] = data[0];
                    data[0] = data[1];
                    data[1] = temp;
                }

                void rotate_east() {
                    T temp = data[5];
                    data[5] = data[2];
                    data[2] = data[0];
                    data[0] = data[3];
                    data[3] = temp;
                }

                void rotate_south() {
                    T temp = data[5];
                    data[5] = data[1];
                    data[1] = data[0];
                    data[0] = data[4];
                    data[4] = temp;
                }

                void rotate_west() {
                    T temp = data[5];
                    data[5] = data[3];
                    data[3] = data[0];
                    data[0] = data[2];
                    data[2] = temp;
                }

                T top() const {
                    return data[0];
                }

                T front() const {
                    return data[1];
                }

                T right() const {
                    return data[2];
                }

                T left() const {
                    return data[3];
                }

                T back() const {
                    return data[4];
                }

                T bottom() const {
                    return data[5];
                }

                int id() const {
                    return id_;
                }

                static Dice match(T top_value, T front_value) {
                    Dice temp = Dice();
                    for (int i = 0; i < 6; i++) {
                        for (int j = 0; j < 4; j++) {
                            if (temp.top() == top_value && temp.front() == front_value) {
                                return temp;
                            }
                            temp.rotate_east();
                        }
                        if (i & 1) {
                            temp.rotate_east();
                        } else {
                            temp.rotate_west();
                        }
                        temp.rotate_south();
                    } 
                    return temp;
                }
        };

    template <typename T>
        ostream& operator<<(ostream& stream, const Dice<T>& dice) {
            stream << " -- Dice " << dice.id() << " -- " << '\n';
            stream << "top      " << dice.top() << '\n';
            stream << "front      " << dice.front() << '\n';
            stream << "left      " << dice.left() << '\n';
            stream << "right      " << dice.right() << '\n';
            stream << "back      " << dice.back() << '\n';
            stream << "bottom      " << dice.bottom() << '\n';
            return stream;
        }
}
using lib::Dice;

int solve() {
    int n;
    std::cin >> n;
    if (n == 0) return 1;
    const int OFFSET = 150;
    std::vector dices(OFFSET * 2, std::vector(2 * OFFSET, std::vector<Dice<int>>()));

    auto enable_roll = [&](int i, int j, int h) {
        if (h > (int)dices[i][j].size()) return true;
        return false;
    };

    auto roll = [&](auto self, int i, int j, int k) -> void {
        assert((int)dices[i][j].size() > k);
        auto dice = dices[i][j][k];
        for (int val = 6; val > 3; val--) {
            if (dice.left() == val && enable_roll(i, j - 1, k)) {
                dices[i][j].pop_back();
                dice.rotate_west();
                k = dices[i][j - 1].size();
                dices[i][j - 1].push_back(dice);
                self(self, i, j - 1, k);
                return;
            }
            if (dice.front() == val && enable_roll(i - 1, j, k)) {
                dices[i][j].pop_back();
                dice.rotate_south();
                k = dices[i - 1][j].size();
                dices[i - 1][j].push_back(dice);
                self(self, i - 1, j, k);
                return;
            }
            if (dice.back() == val && enable_roll(i + 1, j, k)) {
                dices[i][j].pop_back();
                dice.rotate_north();
                k = dices[i + 1][j].size();
                dices[i + 1][j].push_back(dice);
                self(self, i + 1, j, k);
                return;
            }
            if (dice.right() == val && enable_roll(i, j + 1, k)) {
                dices[i][j].pop_back();
                dice.rotate_east();
                k = dices[i][j + 1].size();
                dices[i][j + 1].push_back(dice);
                self(self, i, j + 1, k);
                return;
            }
        }
    };

    for (int i = 0; i < n; i++) {
        int t, f;
        std::cin >> t >> f;
        Dice<int> dice = Dice<int>::match(t, f);
        dice.id_ = i;
        int h = dices[OFFSET][OFFSET].size();
        dices[OFFSET][OFFSET].push_back(dice);
        roll(roll, OFFSET, OFFSET, h);
    }

    std::vector<int> ans(7);
    for (int i = 0; i < 2 * OFFSET; i++) {
        for (int j = 0; j < 2 * OFFSET; j++) {
            if (dices[i][j].empty()) continue;
            ans[dices[i][j].back().top()]++;
        }
    }

    for (int i = 1; i <= 6; i++) {
        std::cout << ans[i] << (i == 6 ? '\n' : ' ');
    }
    return 0;
}

int main() {
    while (!solve());
}
accuracy: 1
time_ms: 110
memory_kb: 5184
final_rank: 11

code_snippet: #include<bits/stdc++.h>
using namespace std;

struct Dice{
    static constexpr int arr[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 a, b, c, d, e, f;
    
    Dice(int x, int y) : a(x), c(y) {
        //cout << x << " " << y << endl;
        d = 7 - c;
        f = 7 - a;
        e = arr[x][y];
        b = 7 - e;
        //cout << a << b << c << d << e << f << endl;
    }
    void rotU(){
        int tmp = a;
        a = c;
        c = f;
        f = d;
        d = tmp;
    }
    void rotD(){
        rotU();
        rotU();
        rotU();
    }
    void rotL(){
        int tmp = a;
        a = e;
        e = f;
        f = b;
        b = tmp;
    }
    void rotR(){
        rotL();
        rotL();
        rotL();
    }
};

int main(){
    while(1){
        int N; cin >> N;
        if(N == 0) break;
        const int PAR = 211;
        vector<vector<int>> G(PAR, vector<int>(PAR, 0));
        vector<vector<int>> val(PAR, vector<int>(PAR, 0));

        for(int _ = 0; _ < N; _++){
            int t, f; cin >> t >> f;
            Dice dice(t, f);

            int r = 103, c = 103;
            while(1){
                int mx = 0;
                // U
                if(dice.d > mx && G[r - 1][c] < G[r][c]) mx = dice.d;
                // D
                if(dice.c > mx && G[r + 1][c] < G[r][c]) mx = dice.c;
                // L
                if(dice.b > mx && G[r][c - 1] < G[r][c]) mx = dice.b;
                // R
                if(dice.e > mx && G[r][c + 1] < G[r][c]) mx = dice.e;

                if(mx <= 3) break;

                // U
                if(dice.d == mx){ dice.rotU(); r--; }
                // D
                if(dice.c == mx){ dice.rotD(); r++; }
                // L
                if(dice.b == mx){ dice.rotL(); c--; }
                // R
                if(dice.e == mx){ dice.rotR(); c++; }
            }
            assert(0 <= r && r < PAR);
            assert(0 <= c && c < PAR);
            G[r][c]++;
            val[r][c] = dice.a;
        }

        vector<int> ans(7, 0);
        for(int i = 0; i < PAR; i++){
            for(int j = 0; j < PAR; j++){
                assert(0 <= val[i][j] && val[i][j] <= 6);
                ans[val[i][j]]++;
            }
        }

        for(int i = 0; i < 6; i++){
            cout << ans[i + 1];
            if(i != 5) cout << " ";
        }
        cout << endl;
    }
}
accuracy: 1
time_ms: 10
memory_kb: 3740
final_rank: 6

code_snippet: #line 2 "cp-library/src/cp-template.hpp"
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using uint = unsigned int;
using ull  = unsigned long long;
using i32 = int;
using u32 = unsigned int;
using i64 = long long;
using u64 = unsigned long long;
using i128 = __int128_t;
template < class T > bool chmin(T& a, T b) { if(a > b) { a = b; return true; } return false; }
template < class T > bool chmax(T& a, T b) { if(a < b) { a = b; return true; } return false; }
template < class T, class U > T ceil (T x, U y) { return (x > 0 ? (x + y - 1) / y :           x / y); }
template < class T, class U > T floor(T x, U y) { return (x > 0 ?           x / y : (x - y + 1) / y); }
int popcnt(i32 x) { return __builtin_popcount(x); }
int popcnt(u32 x) { return __builtin_popcount(x); }
int popcnt(i64 x) { return __builtin_popcountll(x); }
int popcnt(u64 x) { return __builtin_popcountll(x); }

#line 2 "cp-library/src/utility/rep_itr.hpp"
template < class T > struct itr_rep {
    T i, d;
    constexpr itr_rep(const T i) noexcept : i(i), d(1) {}
    constexpr itr_rep(const T i, const T d) noexcept : i(i), d(d) {}
    void operator++() noexcept { i += d; }
    constexpr int operator*() const noexcept { return i; }
    constexpr bool operator!=(const itr_rep x) const noexcept { return d > 0 ? i < x.i : i > x.i; }
};

template < class T > struct rep {
    const itr_rep< T > s, t;
    constexpr rep(const T t) noexcept : s(0), t(t) {}
    constexpr rep(const T s, const T t) noexcept : s(s), t(t) {}
    constexpr rep(const T s, const T t, const T d) noexcept : s(s, d), t(t, d) {}
    constexpr auto begin() const noexcept { return s; }
    constexpr auto end  () const noexcept { return t; }
};

template < class T > struct revrep {
    const itr_rep < T > s, t;
    constexpr revrep(const T t) noexcept : s(t - 1, -1), t(-1, -1) {}
    constexpr revrep(const T s, const T t) noexcept : s(t - 1, -1), t(s - 1, -1) {}
    constexpr revrep(const T s, const T t, const T d) noexcept : s(t - 1, -d), t(s - 1, -d) {}
    constexpr auto begin() const noexcept { return s; }
    constexpr auto end  () const noexcept { return t; }
};
#line 3 "cp-library/src/utility/io.hpp"

/* 128bit integer */
istream& operator>>(istream& is, i128& x) {
    std::string s; is >> s;
    int pm = (s[0] == '-');
    x = 0;
    for(int i : rep(pm, int(s.size()))) x = x * 10 + (s[i] - '0');
    if(pm) x *= -1;
    return is;
}
ostream& operator<<(ostream& os, const i128& x) {
    if(x == 0) return os << '0';
    i128 y = x;
    if(y < 0) { os << '-'; y *= -1; }
    std::vector<int> ny;
    while(y > 0) { ny.push_back(y % 10); y /= 10; }
    for(int i : revrep(ny.size())) os << ny[i];
    return os;
}

template < class S, class T > istream& operator>>(istream& is,       std::pair< S, T >& x) { is >> x.first        >> x.second; return is; }
template < class S, class T > ostream& operator<<(ostream& os, const std::pair< S, T >& x) { os << x.first << " " << x.second; return os; }

namespace scanner {
    struct sca {
        template < class T > operator T() {
            T s; std::cin >> s; return s;
        }
    };
    struct vec {
        int n;
        vec(int n) : n(n) {}
        template < class T > operator std::vector< T >() {
            std::vector< T > v(n);
            for(T& x : v) std::cin >> x;
            return v;
        }
    };
    struct mat {
        int h, w;
        mat(int h, int w) : h(h), w(w) {}
        template < class T > operator std::vector< std::vector< T > >() {
            std::vector m(h, std::vector< T >(w));
            for(std::vector< T >& v : m) for(T& x : v) std::cin >> x;
            return m;
        }
    };
    struct speedup {
        speedup() {
            std::cin.tie(0);
            std::ios::sync_with_stdio(0);
        }
    } speedup_instance;
}
scanner::sca in() { return scanner::sca(); }
scanner::vec in(int n) { return scanner::vec(n); }
scanner::mat in(int h, int w) { return scanner::mat(h, w); }

namespace printer {
    void precision(int d) { std::cout << std::fixed << std::setprecision(d); }
    void flush() { std::cout.flush(); }
}

template < class T >
ostream& operator<<(ostream& os, const std::vector< T > a) {
    int n = a.size();
    for(int i : rep(n)) { os << a[i]; if(i != n - 1) os << ' '; }
    return os;
}

int print() { std::cout << '\n'; return 0; }
template < class head, class... tail > int print(head&& h, tail&&... t) {
    std::cout << h; if(sizeof...(tail)) std::cout << ' ';
    return print(std::forward<tail>(t)...);
}
template < class T > int print_n(const std::vector< T > a) {
    int n = a.size();
    for(int i : rep(n)) std::cout << a[i] << "\n";
    return 0;
}


#line 2 "cp-library/src/utility/key_val.hpp"

template < class K, class V >
struct key_val {
    K key; V val;
    key_val() {}
    key_val(K key, V val) : key(key), val(val) {}
    template < std::size_t Index >
    std::tuple_element_t< Index, key_val >& get() {
        if constexpr (Index == 0) return key;
        if constexpr (Index == 1) return val;
    }
};

namespace std {

template < class K, class V > struct tuple_size < key_val< K, V > > : integral_constant< size_t, 2 > {};
template < class K, class V > struct tuple_element < 0, key_val< K, V > > { using type = K; };
template < class K, class V > struct tuple_element < 1, key_val< K, V > > { using type = V; };

}
#line 2 "cp-library/src/utility/vec_op.hpp"
template < class T > key_val< int, T > max_of(const vector< T >& a) {
    int i = std::max_element(a.begin(), a.end()) - a.begin();
    return {i, a[i]};
}
template < class T > key_val< int, T > min_of(const vector< T >& a) {
    int i = std::min_element(a.begin(), a.end()) - a.begin();
    return {i, a[i]};
}
template < class S, class T > S sum_of(const vector< T >& a) {
    S sum = 0;
    for(const T x : a) sum += x;
    return sum;
}
template < class S, class T > vector< S > freq_of(const vector< T >& a, T L, T R) {
    vector< S > res(R - L, S(0));
    for(const T x : a) res[x - L] += 1;
    return res;
}
template < class S, class T > struct prefix_sum {
    vector< S > s;
    prefix_sum(const vector< T >& a) : s(a) {
        s.insert(s.begin(), S(0));
        for(int i : rep(a.size())) s[i + 1] += s[i];
    }
    // [L, R)
    S sum(int L, int R) { return s[R] - s[L]; }
};
#line 3 "cp-library/src/utility/heap.hpp"

template < class T > using heap_min = std::priority_queue< T, std::vector< T >, std::greater< T > >;
template < class T > using heap_max = std::priority_queue< T, std::vector< T >, std::less< T > >;

#line 27 "cp-library/src/cp-template.hpp"

#line 1 "cp-library/src/algorithm/bin_search.hpp"
template < class T, class F >
T bin_search(T ok, T ng, F f) {
    while(abs(ng - ok) > 1) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}

template < class T, class F >
T bin_search_real(T ok, T ng, F f, int step = 80) {
    while(step--) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}
#line 2 "cp-library/src/algorithm/argsort.hpp"

template < class T > std::vector< int > argsort(const std::vector< T > &a) {
    std::vector< int > ids((int)a.size());
    std::iota(ids.begin(), ids.end(), 0);
    std::sort(ids.begin(), ids.end(), [&](int i, int j) {
        return a[i] < a[j] || (a[i] == a[j] && i < j);
    });
    return ids;
}
#line 1 "macro.hpp"
namespace macro {

using size_type = int;
template < class container > void  sort(container& a) { std::sort(std:: begin(a), std:: end(a)); }
template < class container > void rsort(container& a) { std::sort(std::rbegin(a), std::rend(a)); }
template < class container > void reverse(container& a) { std::reverse(std::begin(a), std::end(a)); }
template < class container > void unique(container& a) {
    std::sort(std::begin(a), std::end(a));
    a.erase(std::unique(std::begin(a), std::end(a)), std::end(a));
}
template < class container > container  sorted(const container& a) { container b = a;  sort(b); return std::move(b); }
template < class container > container rsorted(const container& a) { container b = a; rsort(b); return std::move(b); }
template < class container, class compare > void sort(container& a, const compare& cmp) { std::sort(std::begin(a), std::end(a), cmp); }
template < class container, class compare > container sorted(const container& a, const compare& cmp) { container b = a; sort(b, cmp); return std::move(b); }
template < class container, class value > size_type lower_bound(const container& a, const value& x) { return std::lower_bound(std::begin(a), std::end(a), x) - std::begin(a); }
template < class container, class value > size_type upper_bound(const container& a, const value& x) { return std::upper_bound(std::begin(a), std::end(a), x) - std::begin(a); }

const std::vector<std::pair<size_type, size_type>> dir4 = { {+1,  0}, {-1,  0}, { 0, +1}, { 0, -1} };
const std::vector<std::pair<size_type, size_type>> dir8 = { {-1, -1}, {-1,  0}, {-1, +1}, { 0, -1}, { 0, +1}, {+1, -1}, {+1,  0}, {+1, +1} };

#ifdef _DEBUG
#define debug(x) std::cout << "[" << __LINE__ << "] " << #x << ": " << x << std::endl
#else
#define debug(x)
#endif

template < class container > void concat(container& a, const container& b) {
    a.insert(std::end(a), std::begin(b), std::end(b));
}
std::vector<size_type> iota(const size_type n) {
    std::vector<size_type> I(n);
    std::iota(std::begin(I), std::end(I), 0);
    return I;
}
template < class container > std::vector<size_type> sort_idx(const container& a) {
    const size_type n = a.size();
    std::vector<size_type> I = iota(n);
    std::sort(std::begin(I), std::end(I), [&](size_type i, size_type j) { return a[i] < a[j] or (a[i] == a[j] and i < j); });
    return I;
}
template < class container, class compare > std::vector<size_type> sort_idx(const container& a, const compare& cmp) {
    const size_type n = a.size();
    std::vector<size_type> I = iota(n);
    std::sort(std::begin(I), std::end(I), [&](size_type i, size_type j) { return cmp(a[i], a[j]) or (a[i] == a[j] and i < j); });
    return std::move(I);
}

struct grid {
    using size_type = int;
    size_type H, W;
    grid(const size_type H, const size_type W) : H(H), W(W) {}
    bool contains(const size_type i, const size_type j) {
        return 0 <= i and i < H and 0 <= j and j < W;
    }
};

} // namespace macro

using namespace macro;
#line 3 "B.cpp"

int main() {

    auto get_right = [&](int top, int front) {
        const static map<int, vector<int>> rs = {
            {1, {2, 3, 5, 4}},
            {2, {3, 1, 4, 6}},
            {3, {5, 1, 2, 6}},
            {4, {1, 5, 6, 2}},
            {5, {1, 3, 6, 4}},
            {6, {5, 3, 2, 4}}
        };
        for(auto& [x, vec] : rs) {
            for(int i : rep(4)) {
                if(vec[i] == top and vec[(i + 1) % 4] == front) {
                    return x;
                }
            }
        }
        assert(0);
    };

    struct state {
        int top, front;
        int height;
    };

    while(true) {
        int n = in(); if(n == 0) break;

        map<pair<int,int>, state> data;
        const int MAX_C = 110;
        for(int x = -MAX_C; x <= +MAX_C; x++)
            for(int y = -MAX_C; y <= +MAX_C; y++)
                data[{x, y}] = state{-1, -1, 0};

        for(int n_ : rep(n)) {
            int top = in(), front = in();
            int x = 0, y = 0;
            while([&] {
                int right = get_right(top, front);
                int height = data[{x, y}].height + 1;
                for(int v = 6; v >= 4; v--) {
                    if(right == v and data[{x + 1, y}].height + 2 <= height) {
                        tie(x, y) = make_pair(x + 1, y);
                        tie(top, front) = make_pair(7 - right, front);
                        return true;
                    }
                    if(7 - right == v and data[{x - 1, y}].height + 2 <= height) {
                        tie(x, y) = make_pair(x - 1, y);
                        tie(top, front) = make_pair(right, front);
                        return true;
                    }
                    if(7 - front == v and data[{x, y + 1}].height + 2 <= height) {
                        tie(x, y) = make_pair(x, y + 1);
                        tie(top, front) = make_pair(front, 7 - top);
                        return true;
                    }
                    if(front == v and data[{x, y - 1}].height + 2 <= height) {
                        tie(x, y) = make_pair(x, y - 1);
                        tie(top, front) = make_pair(7 - front, top);
                        return true;
                    }
                }
                return false;
            }()) {}
            data[{x, y}] = state{top, front, data[{x, y}].height + 1};
        }

        vector<int> cnt(7, 0);
        for(int x = -MAX_C; x <= +MAX_C; x++)
            for(int y = -MAX_C; y <= +MAX_C; y++)
                if(data[{x, y}].height != 0) cnt[data[{x, y}].top]++;
        cnt.erase(cnt.begin());
        print(cnt);
    }
}
accuracy: 1
time_ms: 1700
memory_kb: 6528
final_rank: 16

code_snippet: #include <bits/stdc++.h>
using namespace std;

using ll = long long;
#define rep(i, n) for (ll i = 0; i < (n); i++)

struct dice {
    int top, front;
    bool operator==(const dice &d) { return top == d.top && front == d.front; }
};

bool solve() {
    int N;
    cin >> N;
    if (N == 0) return false;
    ll M = 220;
    vector G(M, vector(M, vector<dice>(M, (dice){0, 0})));
    vector<vector<int>> round = {{2, 3, 5, 4}, {1, 4, 6, 3}, {1, 2, 6, 5},
                                 {1, 5, 6, 2}, {1, 3, 6, 4}, {2, 4, 5, 3}};

    vector<pair<int, int>> dxy = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};

    rep(n, N) {
        int t, f;
        cin >> t >> f;
        int x = 110, y = 110, z = 110;
        G[x][y][z] = (dice){t, f};
        while (true) {
            bool update = false;
            if (z == 0) break;
            if (G[x][y][z - 1] == (dice){0, 0}) {
                update = true;
                G[x][y][z - 1] = G[x][y][z];
                G[x][y][z] = (dice){0, 0};
                z--;
            } else {
                int top = G[x][y][z].top;
                int front = G[x][y][z].front;
                int diff = [&]() {
                    rep(i, 4) if (round[top - 1][i] == G[x][y][z].front) {
                        return i;
                    }
                    cout << "WA" << endl;
                    exit(1);
                }();
                optional<pair<int, int>> nxt_xy = nullopt;
                optional<dice> nxt = nullopt;
                int val = -1;
                rep(i, 4) {
                    // int v = round[top - 1][(i - diff + 4) % 4];
                    int v = round[top - 1][(i + diff) % 4];
                    if (v < 4) continue;
                    if (v < val) continue;
                    auto [dx, dy] = dxy[i];
                    if (G[x + dx][y + dy][z] == (dice){0, 0} &&
                        G[x + dx][y + dy][z - 1] == (dice){0, 0}) {
                        val = v;
                        nxt_xy = {dx, dy};
                        if (i == 0) nxt = (dice){7 - v, top};
                        if (i == 1) nxt = (dice){7 - v, front};
                        if (i == 2) nxt = (dice){7 - v, 7 - top};
                        if (i == 3) nxt = (dice){7 - v, front};
                    }
                }
                if (nxt_xy) {
                    auto [dx, dy] = nxt_xy.value();
                    G[x + dx][y + dy][z - 1] = nxt.value();
                    G[x][y][z] = (dice){0, 0};
                    update = true;
                    x = x + dx;
                    y = y + dy;
                    z = z - 1;
                }
            }
            if (!update) break;
        }

        // vector<int> cnt(7, 0);
        // rep(x, M) rep(y, M) {
        //     for (int z = M - 1; z >= 0; z--) {
        //         if (G[x][y][z] == (dice){0, 0}) continue;
        //         cnt[G[x][y][z].top]++;
        //         break;
        //     }
        // }
        // cout << "debug: ";
        // for (int i = 1; i < 7; i++) {
        //     cout << cnt[i] << (i == 6 ? "\n" : " ");
        // }
    }

    vector<int> cnt(7, 0);
    rep(x, M) rep(y, M) {
        for (int z = M - 1; z >= 0; z--) {
            if (G[x][y][z] == (dice){0, 0}) continue;
            cnt[G[x][y][z].top]++;
            break;
        }
    }
    for (int i = 1; i < 7; i++) {
        cout << cnt[i] << (i == 6 ? "\n" : " ");
    }

    return true;
}

int main() {
    while (solve())
        ;
}
accuracy: 1
time_ms: 5810
memory_kb: 88408
final_rank: 20

code_snippet: #include <bits/stdc++.h>
using namespace std;


//---------------------------- テンプレゾーン --------------------------------//

const long long INF = 1000000010;
const long long INFL = 1000000000000000010;
const double MYPI = 3.14159265358979;
const double epsilon = 1e-10;



typedef long long ll;
typedef __int128_t lll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<ll, ll> pl;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<vvl> vvvl;
typedef vector<double> vd;
typedef vector<vd> vvd;
typedef vector<vvd> vvvd;
typedef vector<bool> vb;
typedef vector<vb> vvb;
typedef vector<vvb> vvvb;
typedef vector<char> vc;
typedef vector<vc> vvc;
typedef vector<vvc> vvvc;
typedef vector<pl> vp;
typedef tuple<ll, ll, ll> tt;
typedef vector<tuple<ll, ll, ll>> vt;
typedef vector<string> vs;

#define overload3(a, b, c, d, ...) d
#define overload4(a, b, c, d, e, ...) e
#define overload5(a, b, c, d, e, f, ...) f
#define overload6(a, b, c, d, e, f, g, ...) g
#define pb push_back
#define eb emplace_back
#define MP make_pair
#define REP_0(n) for(int _=0;_<(n);_++)
#define REP_1(i, n) for(int i=0;i<(n);i++)
#define REP_2(i, l, r) for(int i=(l);i<(r);i++)
#define REP_3(i, l, r, d) for(int i=(l);i<(r);i+=(d))
#define REP(...) overload4(__VA_ARGS__, REP_3, REP_2, REP_1, REP_0)(__VA_ARGS__)
#define REPP(i, n) for(int i=1;i<=(n);i++)
#define RREP_1(i, n) for(int i=(n)-1;i>=0;i--)
#define RREP_2(i, l, r) for(int i=(r)-1;i>=(l);i--)
#define RREP_3(i, l, r, d) for(int i=(r)-1;i>=(l);i-=(d))
#define RREP(...) overload4(__VA_ARGS__, RREP_3, RREP_2, RREP_1)(__VA_ARGS__)
#define RREPP(i, n) for(int i=(n);i>0;i--)
#define EACH1(e, a) for(auto &e : a)
#define EACH2(x, y, a) for(auto &[x, y] : a)
#define EACH3(x, y, z, a) for(auto &[x, y, z] : a)
#define EACH(...) overload4(__VA_ARGS__, EACH3, EACH2, EACH1)(__VA_ARGS__)
#define ALL1(x) begin(x), end(x)
#define ALL2(x, a) begin(x), begin(x) + a
#define ALL3(x, a, b) begin(x) + a, begin(x) + b
#define ALL(...) overload3(__VA_ARGS__, ALL3, ALL2, ALL1)(__VA_ARGS__)
#define RALL1(i) (i).rbegin(), (i).rend()
#define RALL2(i, a) (i).rend() - a, (i).rend()
#define RALL3(i, a, b) (i).rend() - b, (i).rend() - a
#define RALL(...) overload3(__VA_ARGS__, RALL3, RALL2, RALL1)(__VA_ARGS__)
#define sz(x) (long long)x.size()
#define LB(a, x) (lower_bound(a.begin(), a.end(), x) - a.begin())
#define UB(a, x) (upper_bound(a.begin(), a.end(), x) - a.begin())
#define FLG(x, i) (((x)>>(i)) & 1)
#define CNTBIT(x) __builtin_popcountll(x)
#define TOPBIT(t) (t == 0 ? -1 : 63 - __builtin_clzll(t))
#define BTMBIT(t) (t == 0 ? 64 : __builtin_ctzll(t))
#define IN(x, a, b) ((a) <= (x) && (x) < (b))
#define INT(...) int __VA_ARGS__; input(__VA_ARGS__)
#define STR(...) string __VA_ARGS__; input(__VA_ARGS__)
#define CHAR(...) char __VA_ARGS__; input(__VA_ARGS__)
#define DBL(...) double __VA_ARGS__; input(__VA_ARGS__)
#define LD(...) long double __VA_ARGS__; input(__VA_ARGS__)
#define VL1(a, n) vector<long long> a(n); for(int I=0;I<(n);I++)cin >> a[I]
#define VL2(a, b, n) vector<long long> a(n), b(n); for(int I=0;I<(n);I++)cin >> a[I] >> b[I]
#define VL3(a, b, c, n) vector<long long> a(n), b(n), c(n); for(int I=0;I<(n);I++)cin >> a[I] >> b[I] >> c[I]
#define VL4(a, b, c, d, n) vector<long long> a(n), b(n), c(n), d(n); for(int I=0;I<(n);I++)cin >> a[I] >> b[I] >> c[I] >> d[I]
#define VL5(a, b, c, d, e, n) vector<long long> a(n), b(n), c(n), d(n), e(n); for(int I=0;I<(n);I++)cin >> a[I] >> b[I] >> c[I] >> d[I] >> e[I]
#define VL(...) overload6(__VA_ARGS__, VL5, VL4, VL3, VL2, VL1)(__VA_ARGS__)
#define VD1(a, n) vector<double> a(n); for(int I=0;I<(n);I++)cin >> a[I]
#define VD2(a, b, n) vector<double> a(n), b(n); for(int I=0;I<(n);I++)cin >> a[I] >> b[I]
#define VD3(a, b, c, n) vector<double> a(n), b(n), c(n); for(int I=0;I<(n);I++)cin >> a[I] >> b[I] >> c[I]
#define VD4(a, b, c, d, n) vector<double> a(n), b(n), c(n), d(n); for(int I=0;I<(n);I++)cin >> a[I] >> b[I] >> c[I] >> d[I]
#define VD5(a, b, c, d, e, n) vector<double> a(n), b(n), c(n), d(n), e(n); for(int I=0;I<(n);I++)cin >> a[I] >> b[I] >> c[I] >> d[I] >> e[I]
#define VD(...) overload6(__VA_ARGS__, VD5, VD4, VD3, VD2, VD1)(__VA_ARGS__)
#define VVL(a, n, m) vector<vector<long long> > a(n, vector<long long>(m)); for(int I=0;I<(n);I++)for(int J=0;J<(m);J++)cin >> a[I][J]
#define VVC(s, n, m) vector<vector<char> > s(n, vector<char>(m)); for(int I=0;I<(n);I++)for(int J=0;J<(m);J++)cin >> s[I][J]
#define VS(s, n) vector<string> s(n); for(int I=0;I<(n);I++)cin >> s[I];

template <typename T1, typename T2>
ostream &operator<<(ostream &os, const pair<T1, T2> &a){
  return os << a.first << " " << a.second;
}
template <typename T1, typename T2, typename T3>
ostream &operator<<(ostream &os, const tuple<T1, T2, T3> &a){
  return os << get<0>(a) << " " << get<1>(a) << " " << get<2>(a);
}

struct IoSetup{
  IoSetup() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout << fixed << setprecision(15);
  }
} iosetup;

#ifdef LOCAL
#  include <debug_print.hpp>
#  define debug(...) debug_print::multi_print(#__VA_ARGS__, __VA_ARGS__)
#else
#  define debug(...) (static_cast<void>(0))
#endif

template <typename T>
using minheap = priority_queue<T, vector<T>, greater<T>>;
 
template <typename T>
using maxheap = priority_queue<T>;

template<class... T>
void input(T&... a){
  (cin >> ... >> a);
}

template <typename... T>
constexpr auto min(T... a){
  return min(initializer_list<common_type_t<T...>>{a...});
}
template <typename... T>
constexpr auto max(T... a){
  return max(initializer_list<common_type_t<T...>>{a...});
}

template <typename T1, typename T2>
bool chmax(T1 &x, const T2 &y){
  return x < y ? x = y, true : false;
}
template <typename T1, typename T2>
bool chmin(T1 &x, const T2 &y){
  return x > y ? x = y, true : false;
}

void OUT(){cout << "\n";}

template <typename T, typename... Ts>
void OUT(const T &a, const Ts&... b){
  cout << a;
  (cout << ... << (cout << " ", b));
  cout << "\n";
}

template <typename T>
void OUT(const vector<T> &res){
  for(int i=0;i<(int)res.size();i++){
    cout << res[i] << " ";
  }
  cout << "\n";
}

template <typename T>
void OUT_(const T &a){
  cout << a << " ";
}

template <typename T>
void OUTN(const vector<T> &res, long long margin = 0){
  for(int i=0;i<(int)res.size();i++){
    cout << res[i] + (T)margin << "\n";
  }
}

template <typename T>
void OUTN_(const vector<T> &res, long long margin = 0){
  for(int i=0;i<(int)res.size();i++){
    cout << res[i] + (T)margin << " ";
  }
  cout << "\n";
}

template <typename T>
void OUTNN(const vector<vector<T>> &res, long long margin = 0){
  for(int i=0;i<(int)res.size();i++){
    for(int j=0;j<(int)res[i].size();j++){
      cout << res[i][j] + (T)margin << " ";
    }
    cout << "\n";
  }
}

void YES(const bool &res = true, bool Capital = false){
  if(Capital) cout << (res ? "YES" : "NO") << "\n";
  else cout << (res ? "Yes" : "No") << "\n";
}

void FIRST(const bool &res = true, bool Capital = false){
  if(Capital) cout << (res ? "FIRST" : "SECOND") << "\n";
  else cout << (res ? "First" : "Second") << "\n";
}

template <typename T>
void DEC(vector<T> &a, long long dif = 1){
  for(auto &x : a)x -= (T)dif;
}
template <typename T>
void DEC(vector<T> &a, vector<T> &b, long long dif = 1){
  for(auto &x : a)x -= (T)dif;
  for(auto &x : b)x -= (T)dif;
}
template <typename T>
void DEC(vector<vector<T>> &a, long long dif = 1){
  for(auto &v : a)for(auto &x : v)x -= (T)dif;
}

template <typename T>
void INC(vector<T> &a, long long dif = 1){
  for(auto &x : a)x += (T)dif;
}
template <typename T>
void INC(vector<T> &a, vector<T> &b, long long dif = 1){
  for(auto &x : a)x += (T)dif;
  for(auto &x : b)x += (T)dif;
}
template <typename T>
void INC(vector<vector<T>> &a, long long dif = 1){
  for(auto &v : a)for(auto &x : v)x += (T)dif;
}

template <typename T>
T SUM(const vector<T> &a){
  return accumulate(a.begin(), a.end(), (T)0);
}
template <typename T>
T SUM(const vector<vector<T>> &a){
  T ret = 0;
  for(int i=0;i<(int)a.size();i++)ret += accumulate(a[i].begin(), a[i].end(), (T)0);
  return ret;
}

template <typename T>
T MAX(const vector<T> &a){
  return *max_element(a.begin(), a.end());
}
template <typename T>
T MAX(const vector<vector<T>> &a){
  T ret = -INFL;
  for(int i=0;i<(int)a.size();i++)for(int j=0;j<(int)a[i].size();j++)if(ret < a[i][j])ret = a[i][j];
  return ret;
}

template <typename T>
int ARGMAX(const vector<T> &a){
  int ret = 0;
  for(int i=1;i<(int)a.size();i++)if(a[ret] < a[i])ret = i;
  return ret;
}
template <typename T>
pair<int, int> ARGMAX(const vector<vector<T>> &a){
  pair<int, int> ret = {0, 0};
  for(int i=0;i<(int)a.size();i++)for(int j=0;j<(int)a[i].size();j++)if(a[ret.first][ret.second] < a[i][j])ret = {i, j};
  return ret;
}

template <typename T>
T MIN(const vector<T> &a){
  return *min_element(a.begin(), a.end());
}
template <typename T>
T MIN(const vector<vector<T>> &a){
  T ret = INFL;
  for(int i=0;i<(int)a.size();i++)for(int j=0;j<(int)a[i].size();j++)if(ret > a[i][j])ret = a[i][j];
  return ret;
}

template <typename T>
int ARGMIN(const vector<T> &a){
  int ret = 0;
  for(int i=1;i<(int)a.size();i++)if(a[ret] > a[i])ret = i;
  return ret;
}
template <typename T>
pair<int, int> ARGMIN(const vector<vector<T>> &a){
  pair<int, int> ret = {0, 0};
  for(int i=0;i<(int)a.size();i++)for(int j=0;j<(int)a[i].size();j++)if(a[ret.first][ret.second] > a[i][j])ret = {i, j};
  return ret;
}

template <typename T>
int SIGN(const T &a){
  if(abs(a) < epsilon)return 0;
  return a > 0 ? 1 : -1;
}

template <typename T>
vector<T> UNIQ(vector<T> a){
  sort(a.begin(), a.end());
  a.erase(unique(a.begin(), a.end()), a.end());
  return a;
}

template <typename T>
vector<T> sorted(vector<T> a, bool Descending = false){
  sort(a.begin(), a.end());
  if(Descending)reverse(a.begin(), a.end());
  return a;
}

template <typename T>
vector<T> cumsum(const vector<T> &a){
  int n = (int)a.size();
  vector<T> ret(n+1, (T)0);
  for(int i=0;i<n;i++)ret[i+1] = ret[i] + a[i];
  return ret;
}
template <typename T>
vector<vector<T>> cumsum(const vector<vector<T>> &a){
  int n = (int)a.size(), m = (int)a[0].size();
  vector<vector<T>> ret(n+1, vector<T>(m+1, (T)0));
  for(int i=0;i<n;i++)for(int j=0;j<m;j++)ret[i+1][j+1] = ret[i+1][j] + a[i][j];
  for(int i=0;i<n;i++)for(int j=0;j<m;j++)ret[i+1][j+1] += ret[i][j+1];
  return ret;
}
template <typename T>
vector<vector<vector<T>>> cumsum(const vector<vector<vector<T>>> &a){
  int n = (int)a.size(), m = (int)a[0].size(), l = (int)a[0][0].size();
  vector<vector<vector<T>>> ret(n+1, vector<vector<T>>(m+1, vector<T>(l+1, (T)0)));
  for(int i=0;i<n;i++)for(int j=0;j<m;j++)for(int k=0;k<l;k++)ret[i+1][j+1][k+1] = ret[i+1][j+1][k] + a[i][j][k];
  for(int i=0;i<n;i++)for(int j=0;j<m;j++)for(int k=0;k<l;k++)ret[i+1][j+1][k+1] += ret[i][j+1][k+1];
  for(int i=0;i<n;i++)for(int j=0;j<m;j++)for(int k=0;k<l;k++)ret[i+1][j+1][k+1] += ret[i+1][j][k+1];
  return ret;
}
template <typename T>
void cumsum_inplace(vector<T> &a){
  int n = (int)a.size();
  for(int i=0;i<n-1;i++)a[i+1] += a[i];
}
template <typename T>
void cumsum_inplace(vector<vector<T>> &a){
  int n = (int)a.size(), m = (int)a[0].size();
  for(int i=0;i<n-1;i++)for(int j=0;j<m;j++)a[i+1][j] += a[i][j];
  for(int i=0;i<n;i++)for(int j=0;j<m-1;j++)a[i][j+1] += a[i][j];
}
template <typename T>
void cumsum_inplace(vector<vector<vector<T>>> &a){
  int n = (int)a.size(), m = (int)a[0].size(), l = (int)a[0][0].size();
  for(int i=0;i<n-1;i++)for(int j=0;j<m;j++)for(int k=0;k<l;k++)a[i+1][j][k] += a[i][j][k];
  for(int i=0;i<n;i++)for(int j=0;j<m-1;j++)for(int k=0;k<l;k++)a[i][j+1][k] += a[i][j][k];
  for(int i=0;i<n;i++)for(int j=0;j<m;j++)for(int k=0;k<l-1;k++)a[i][j][k+1] += a[i][j][k];
}

template< typename T = long long >
struct Edge {
  long long from, to;
  T cost;
  long long idx;
  Edge() = default;
  Edge(long long from, long long to, T cost = 1, long long idx = -1) : from(from), to(to), cost(cost), idx(idx) {}
  operator int() const { return to; }
};

template< typename T = long long >
struct Graph {
  vector< vector< Edge< T > > > g, ginv;
  vector<int> indeg, outdeg;
  long long es;
  Graph() = default;
  explicit Graph(long long n) : g(n), ginv(n), indeg(n, 0), outdeg(n, 0), es(0) {}
  size_t size() const {
    return g.size();
  }
  void add_directed_edge(long long from, long long to, T cost = 1) {
    indeg[to]++, outdeg[from]++;
    //ginv[to].emplace_back(to, from, cost, es);
    g[from].emplace_back(from, to, cost, es++);
  }
  void add_edge(long long from, long long to, T cost = 1) {
    indeg[from]++, outdeg[from]++, indeg[to]++, outdeg[to]++;
    g[from].emplace_back(from, to, cost, es);
    g[to].emplace_back(to, from, cost, es++);
  }
  inline vector< Edge< T > > &operator[](const int &k) {
    return g[k];
  }
  inline const vector< Edge< T > > &operator[](const int &k) const {
    return g[k];
  }
};

template< typename T = long long >
using Edges = vector< Edge< T > >;

template< typename T >
struct Enumeration {
private:
  static vector< T > _fact, _finv, _inv;
  inline static void expand(size_t sz) {
    if(_fact.size() < sz + 1) {
      int pre_sz = max(1, (int) _fact.size());
      _fact.resize(sz + 1, T(1));
      _finv.resize(sz + 1, T(1));
      _inv.resize(sz + 1, T(1));
      for(int i = pre_sz; i <= (int) sz; i++) {
        _fact[i] = _fact[i - 1] * T(i);
      }
      _finv[sz] = T(1) / _fact[sz];
      for(int i = (int) sz - 1; i >= pre_sz; i--) {
        _finv[i] = _finv[i + 1] * T(i + 1);
      }
      for(int i = pre_sz; i <= (int) sz; i++) {
        _inv[i] = _finv[i] * _fact[i - 1];
      }
    }
  }
public:
  explicit Enumeration(size_t sz = 0) { expand(sz); }
  static inline T fact(int k) {
    expand(k);
    return _fact[k];
  }
  static inline T finv(int k) {
    expand(k);
    return _finv[k];
  }
  static inline T inv(int k) {
    expand(k);
    return _inv[k];
  }
  static T P(int n, int r) {
    if(r < 0 || n < r) return 0;
    return fact(n) * finv(n - r);
  }
  static T C(int p, int q) {
    if(q < 0 || p < q) return 0;
    return fact(p) * finv(q) * finv(p - q);
  }
};

template< typename T >
vector< T > Enumeration< T >::_fact = vector< T >();
template< typename T >
vector< T > Enumeration< T >::_finv = vector< T >();
template< typename T >
vector< T > Enumeration< T >::_inv = vector< T >();

template <typename T>
T norm1(const pair<T, T> &a, const pair<T, T> &b = {(T)0, (T)0}){
  return abs(a.first - b.first) + abs(a.second - b.second);
}
template <typename T>
T norm22(const pair<T, T> &a, const pair<T, T> &b = {(T)0, (T)0}){
  return (a.first - b.first) * (a.first - b.first) + (a.second - b.second) * (a.second - b.second);
}
template <typename T>
double norm2(const pair<T, T> &a, const pair<T, T> &b = {(T)0, (T)0}){
  return sqrt(norm22(a, b));
}

long long powll(long long a, long long n){
  assert(n >= 0);
  if(n == 0)return 1;
  long long ret = 1;
  while(n){
    if(n & 1)ret *= a;
    a *= a;
    n >>= 1;
  }
  return ret;
}

vector<long long> str_to_vl(const string &s){
  vector<long long> ret(s.size());
  if(s.size() == 0)return ret;
  if(0 <= s[0]-'A' && s[0]-'A' < 26) for(int i=0;i<(int)s.size();i++) ret[i] = s[i] - 'A';
  else if(0 <= s[0]-'a' && s[0]-'a' < 26) for(int i=0;i<(int)s.size();i++) ret[i] = s[i] - 'a';
  else if(0 <= s[0]-'0' && s[0]-'0' < 10) for(int i=0;i<(int)s.size();i++) ret[i] = s[i] - '0';
  else assert(0);
  return ret;
}

// 0-indexed
long long TOPDIGIT(long long x){
  assert(x >= 0);
  long long ret = 0;
  while(x >= 10){x /= 10; ret++;}
  return ret;
}

template <typename T>
vector<pair<T, int>> sorti(const vector<T> &a){
  vector<pair<T, int>> ret(a.size());
  for(int i=0;i<(int)a.size();i++){
    ret[i] = {a[i], i};
  }
  sort(ret.begin(), ret.end());
  return ret;
}
template <typename T1, typename T2>
vector<tuple<T1, T2, int>> sorti(const vector<T1> &a, const vector<T2> &b){
  assert(a.size() == b.size());
  vector<tuple<T1, T2, int>> ret(a.size());
  for(int i=0;i<(int)a.size();i++){
    ret[i] = {a[i], b[i], i};
  }
  sort(ret.begin(), ret.end());
  return ret;
}
template <typename T1, typename T2, typename T3>
vector<tuple<T1, T2, T3, int>> sorti(const vector<T1> &a, const vector<T2> &b, const vector<T3> &c){
  assert(a.size() == b.size() && a.size() == c.size());
  vector<tuple<T1, T2, T3, int>> ret(a.size());
  for(int i=0;i<(int)a.size();i++){
    ret[i] = {a[i], b[i], c[i], i};
  }
  sort(ret.begin(), ret.end());
  return ret;
}

// 高々小数第 k 位までの実数を 10^k 倍して整数化
ll decimal_to_ll(const string &s, int k){
  int n = s.size();
  for(int i=0;i<n;i++){
    if(s[i] == '.'){
      ll ret = stoll(s.substr(0, i) + s.substr(i + 1));
      for(int j=0;j<k-(n-1-i);j++)ret *= 10;
      return ret;
    }
  }
  ll ret = stoll(s);
  for(int i=0;i<k;i++)ret *= 10;
  return ret;
}

long long max(const int &a, const long long &b){return max((long long)a, b);}
long long min(const int &a, const long long &b){return min((long long)a, b);}

const vector<long long> dy = {1, 0, -1, 0, 1, -1, -1, 1};
const vector<long long> dx = {0, 1, 0, -1, 1, 1, -1, -1};

random_device seed_gen;
mt19937_64 rnd;

// [low, high] の範囲の値を持つ長さ len のランダムベクトルを生成
vector<long long> random_vl(int len, long long low, long long high){
  uniform_int_distribution<long long> dist(low, high);
  vector<long long> ret(len);
  for(int i=0;i<len;i++)ret[i] = dist(rnd);
  return ret;
};

vector<long long> random_permutation(int len){
  uniform_int_distribution<int> dist(1, len);
  vector<long long> ret(len);
  set<int> se;
  for(int i=0;i<len;i++){
    int tmp = dist(rnd);
    while(se.count(tmp))tmp = dist(rnd);
    ret[i] = tmp;
    se.insert(ret[i]);
  }
  return ret;
};

//--------------------------- テンプレゾーン終 -------------------------------//

//----------------------------- コピペゾーン ---------------------------------//



//---------------------------- コピペゾーン終 --------------------------------//

#define int long long

void solve(){
	vvl ans;
  map<pl, ll> right, left;
  right[{1, 2}] = 3, right[{1, 3}] = 5;
  right[{6, 2}] = 4, right[{6, 3}] = 2;
  while(sz(right) < 24){
    auto nxt = right;
    EACH(p, z, right){
      auto [x, y] = p;
      nxt[{y, x}] = 7 - z;
      nxt[{y, z}] = x;
    }
    swap(nxt, right);
  }
  EACH(p, z, right){
    left[{p}] = 7 - z;
  }
  while(1){
    INT(n);
    if(n == 0)break;
    vvl height(201, vl(201, 0));
    vvl num = height;
    REP(n){
      INT(t, f);
      ll y = 100, x = 100, h = height[y][x];
      while(1){
        bool fin = true;
        RREP(i, 4, 7){
          if(t == 7 - i)continue;
          if(f == i && height[y+1][x] < h){
            h = height[y+1][x];
            y = y + 1;
            ll tmp = t;
            t = right[{t, right[{t, f}]}];
            f = tmp;
            fin = false;
            break;
          }
          if(f == 7 - i && height[y-1][x] < h){
            h = height[y-1][x];
            y = y - 1;
            ll tmp = t;
            t = f;
            f = 7 - tmp;
            fin = false;
            break;
          }
          if(right[{t, f}] == i && height[y][x+1] < h){
            h = height[y][x+1];
            x++;
            t = left[{t, f}];
            fin = false;
            break;
          }
          if(left[{t, f}] == i && height[y][x-1] < h){
            h = height[y][x-1];
            x--;
            t = right[{t, f}];
            fin = false;
            break;
          }
        }
        if(fin)break;
      }
      height[y][x] = h + 1;
      num[y][x] = t;
    }
    vl res(6, 0);
    REP(i, 201)REP(j, 201){
      if(num[i][j] == 0)continue;
      res[num[i][j]-1]++;
    }
    ans.pb(res);
  }
  REP(i, sz(ans)){
    REP(j, sz(ans[i]))cout << ans[i][j] << (j == sz(ans[i]) - 1 ? "\n" : " ");
  }
}

int solve_test(int n, vl a){

  return 0;
}

int solve_naive(int n, vl a){

  return 0;
}

void random_test(){
  rnd.seed(seed_gen());

  uniform_int_distribution<int> dist_n(4, 10), dist_m(4, 10), dist_a(1, 20), dist_b(1, 20);  

  for(int test = 1; test <= 100; test++){
    int n = dist_n(rnd), m = dist_m(rnd);
    vl a = random_vl(n, 3, 20);
    auto Output = solve_test(n, a), Answer = solve_naive(n, a);
    if(Output != Answer){
      cout << "Wrong Answer on Test #" << test << '\n';
      debug(n);
      debug(a);
      debug(Answer);
      debug(Output);
      break;
    }
  }
}

signed main(){
  int T = 1;
  // cin >> T;

  while(T--) solve();

  // random_test();

  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 4036
final_rank: 8

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vll = vector<ll>;
using vvll = vector<vll>;
#define all(A) A.begin(),A.end()
#define rep(i, n) for (ll i = 0; i < (ll) (n); i++)
template<class T>
bool chmax(T& p, T q, bool C = 1) {
    if (C == 0 && p == q) {
        return 1;
    }
    if (p < q) {
        p = q;
        return 1;
    }
    else {
        return 0;
    }
}


vvll D = {
    {1,2,4,3},
    {0,3,5,2},
    {0,1,5,4},
    {0,4,5,1},
    {0,2,5,3},
    {1,3,4,2}
};

void rot(vll& d, ll& F) {
    while (d[0] != F) {
        rotate(d.begin(), d.begin() + 1, d.end());
    }
    return;
}

vll dx = { 0,1,0,-1 };
vll dy = { 1,0,-1,0 };

int main() {

    cin.tie(nullptr);
    ios::sync_with_stdio(false);

    while (1) {
        vector<vector<pair<ll, ll>>> H(220, vector<pair<ll, ll>>(220, { 0,-1 }));
        ll N;
        cin >> N;
        if (N == 0)return 0;
        rep(i, N) {
            ll T, F;
            cin >> T >> F;
            T--; F--;
            ll y = 110, x = 110;
            vll d = D[T];
            rot(d, F);
            while (1) {
                ll OK = -1, M = -1;
                rep(t, 4) {
                    if (H[y][x].first > H[y + dy[t]][x + dx[t]].first && d[t] > 2) {
                        if (chmax(M, d[t]))OK = t;
                    }
                }
                if (OK == -1)break;

                y += dy[OK];
                x += dx[OK];
                if (OK == 0) {
                    ll NT = 5 - F;
                    F = T;
                    T = NT;
                    d = D[NT];
                    rot(d, F);
                }
                else if (OK == 1) {
                    ll NT = d[3];
                    d = D[d[3]];
                    T = NT;
                    rot(d, F);
                }
                else if (OK == 2) {
                    d = D[F];
                    ll NT = F;
                    F = 5 - T;
                    T = NT;
                    rot(d, F);
                }
                else {
                    T = d[1];
                    d = D[d[1]];
                    
                    rot(d, F);
                }

            }
            H[y][x].first++;
            H[y][x].second = T;
        }
        vll an(6, 0);
        rep(i, 220)rep(j, 220)if (H[i][j].second >= 0) {
            an[H[i][j].second]++;
        }
        rep(i, 6)cout << an[i] << " \n"[i == 5];
    }

}
accuracy: 1
time_ms: 30
memory_kb: 3812
final_rank: 9

code_snippet: #include<bits/stdc++.h>
using namespace std;

struct myrand {
	random_device rnd;
	mt19937 mt;
	myrand() : rnd{}, mt{ rnd() } {}
	// l <= i and i < r
	int get(int l, int r) {
		return mt() % r + l;
	}
};

struct Dice {
	int top, bottom, north, south, east, west;

	void init(){
		top = 1;
		bottom = 6;
		east = 5;
		west = 2;
		south = 3;
		north = 4;
	}

	Dice() {
		init();
	}

	Dice(int t,int e) {
		init();

		myrand rnd;

		while(t != top or e != east) {
			if (rnd.get(0, 2) == 0) {
				rotate_north();
			} else {
				rotate_east();
			}
		}
	}

	void rotate_north() {
		int tmp = bottom;
		bottom = north;
		north = top;
		top = south;
		south = tmp;
	}

	void rotate_east() {
		int tmp = bottom;
		bottom = east;
		east = top;
		top = west;
		west = tmp;
	}

	void rotate_west() {
		int tmp = bottom;
		bottom = west;
		west = top;
		top = east;
		east = tmp;
	}

	void rotate_south() {
		int tmp = bottom;
		bottom = south;
		south = top;
		top = north;
		north = tmp;
	}
};


vector<pair<int, char>> aspects(Dice d) {
	vector<pair<int,char>> a = {
		make_pair(d.north, 'N'),
		make_pair(d.south, 'S'),
		make_pair(d.west, 'W'),
		make_pair(d.east, 'E')
	};

	sort(a.rbegin(), a.rend());

	return a;
}


pair<int,int> direction_to_dxdy(char dir){
	switch (dir){
		case 'N':
			return make_pair(0, -1);
		case 'S':
			return make_pair(0, 1);
		case 'W':
			return make_pair(-1, 0);
		case 'E':
			return make_pair(1, 0);
	}
	int inf = 1<<30;
	return make_pair(inf, inf);
}


bool solve() {
	int n;
	cin>>n;

	if (n == 0) {
		return false;
	}

	map<pair<int,int>, vector<Dice>> xy_to_dices;

	for(int i=0;i<n;i++) {
		int t, f;
		cin >> t >> f;

		Dice d(t,f);

		assert(t == d.top and f == d.east);

		int x = 0, y = 0;
		xy_to_dices[make_pair(x,y)].push_back(d);

		while(true) {
			bool rotated = false;

			// 大きい順に側面を見る
			vector<pair<int, char>> as = aspects(d);
			for(auto [v, dir]:as){
				if (v < 4) {
					break;
				}

				auto [dx, dy] = direction_to_dxdy(dir);
				int nx = x + dx;
				int ny = y + dy;

				int size = xy_to_dices[make_pair(x,y)].size();
				int to_size = xy_to_dices[make_pair(nx,ny)].size();

				// 転がれる場合
				if (size - to_size >= 2) {
					xy_to_dices[make_pair(x,y)].pop_back();
					switch(dir){
						case 'N':
							d.rotate_north();
							break;
						case 'E':
							d.rotate_east();
							break;
						case 'W':
							d.rotate_west();
							break;
						case 'S':
							d.rotate_south();
							break;
						default:
							assert(false);
							break;
					}
					xy_to_dices[make_pair(nx,ny)].push_back(d);
					x = nx;
					y = ny;
					rotated = true;
					break;
				}
			}

			if (not rotated) {
				break;
			}
		}

	}

	vector<int> ans(6, 0);

	for(auto [p, dices]: xy_to_dices) {
		if (dices.size() == 0) {
			continue;
		}

		// 最も上に積み上がっているサイコロの上面を見る
		ans[dices.back().top - 1]++;
	}

	for(int i=0;i<6;i++){
		if (i) {
			cout << " ";
		}
		cout << ans[i];
	}
	cout << "\n";

	return true;
}


int main() {
	while(solve()) {}
}
accuracy: 1
time_ms: 10
memory_kb: 3468
final_rank: 1

code_snippet: #include <iostream>
#include <vector>
using namespace std;

struct Dice {
	int a[6];
};

// サイコロ・方向
int dx[4] = { 0, 0, -1, 1 };
int dy[4] = { -1, 1, 0, 0 };
int Important[4] = { 3, 2, 4, 1 };
int Transform[4][6] = {
	{ 2, 1, 5, 0, 4, 3 },
	{ 3, 1, 0, 5, 4, 2 },
	{ 1, 5, 2, 3, 0, 4 },
	{ 4, 0, 2, 3, 5, 1 }
};

// その他の変数
const int OFFSET = 150;
int N, A[1009], B[1009];
int cnt[309][309];
vector<int> Saikoro[309][309];

Dice Initial(int A0, int A1) {
	Dice E;
	E.a[0] = A0;
	E.a[1] = A1;

	// 最初が 1 の場合
	if (A0 == 1 && A1 == 2) E.a[2] = 3;
	if (A0 == 1 && A1 == 3) E.a[2] = 5;
	if (A0 == 1 && A1 == 5) E.a[2] = 4;
	if (A0 == 1 && A1 == 4) E.a[2] = 2;

	// 最初が 2 の場合
	if (A0 == 2 && A1 == 3) E.a[2] = 1;
	if (A0 == 2 && A1 == 1) E.a[2] = 4;
	if (A0 == 2 && A1 == 4) E.a[2] = 6;
	if (A0 == 2 && A1 == 6) E.a[2] = 3;

	// 最初が 3 の場合
	if (A0 == 3 && A1 == 1) E.a[2] = 2;
	if (A0 == 3 && A1 == 2) E.a[2] = 6;
	if (A0 == 3 && A1 == 6) E.a[2] = 5;
	if (A0 == 3 && A1 == 5) E.a[2] = 1;

	// 最初が 4 の場合
	if (A0 == 4 && A1 == 5) E.a[2] = 6;
	if (A0 == 4 && A1 == 6) E.a[2] = 2;
	if (A0 == 4 && A1 == 2) E.a[2] = 1;
	if (A0 == 4 && A1 == 1) E.a[2] = 5;

	// 最初が 5 の場合
	if (A0 == 5 && A1 == 6) E.a[2] = 4;
	if (A0 == 5 && A1 == 4) E.a[2] = 1;
	if (A0 == 5 && A1 == 1) E.a[2] = 3;
	if (A0 == 5 && A1 == 3) E.a[2] = 6;

	// 最初が 6 の場合
	if (A0 == 6 && A1 == 4) E.a[2] = 5;
	if (A0 == 6 && A1 == 5) E.a[2] = 3;
	if (A0 == 6 && A1 == 3) E.a[2] = 2;
	if (A0 == 6 && A1 == 2) E.a[2] = 4;

	// その他
	E.a[3] = 7 - E.a[2];
	E.a[4] = 7 - E.a[1];
	E.a[5] = 7 - E.a[0];
	return E;
}

Dice Move(Dice E, int dir) {
	Dice F;
	for (int i = 0; i < 6; i++) F.a[i] = E.a[Transform[dir][i]];
	return F;
}

void solve() {
	// 初期化
	for (int i = 0; i <= 300; i++) {
		for (int j = 0; j <= 300; j++) {
			cnt[i][j] = 0; Saikoro[i][j].clear();
		}
	}

	// シミュレーション
	for (int i = 1; i <= N; i++) {
		Dice G = Initial(A[i], B[i]);
		int cx = OFFSET, cy = OFFSET;

		// 転がりのシミュレーション
		while (true) {
			int maxn = -1;
			int max_id = -1;
			for (int dir = 0; dir < 4; dir++) {
				if (G.a[Important[dir]] <= 3) continue;
				int sx = cx + dx[dir];
				int sy = cy + dy[dir];
				if (cnt[sx][sy] >= cnt[cx][cy]) continue;
				if (maxn < G.a[Important[dir]]) {
					maxn = G.a[Important[dir]];
					max_id = dir;
				}
			}
			if (max_id == -1) break;

			// サイコロを転がす
			cx += dx[max_id];
			cy += dy[max_id];
			G = Move(G, max_id);
		}

		// サイコロを追加
		Saikoro[cx][cy].push_back(G.a[0]);
		cnt[cx][cy] += 1;
	}

	// 答えを計算
	vector<int> Answer(6, 0);
	for (int i = 0; i <= 300; i++) {
		for (int j = 0; j <= 300; j++) {
			if (Saikoro[i][j].size() == 0) continue;
			int val = Saikoro[i][j][Saikoro[i][j].size() - 1];
			Answer[val - 1] += 1;
		}
	}

	// 答えを出力
	cout << Answer[0] << " " << Answer[1] << " " << Answer[2] << " " << Answer[3] << " " << Answer[4] << " " << Answer[5] << endl;
}

int main() {
	while (true) {
		// 入力
		cin >> N; if (N == 0) break;
		for (int i = 1; i <= N; i++) cin >> A[i] >> B[i];

		// 問題を解く
		solve();
	}
	return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 5956
final_rank: 10

code_snippet: #include <bits/stdc++.h>

#define rep(x, y) for (int x = 0; x < y; x++)
#define rrep(x, y) for (int x = y - 1; x >= 0; x--)
#define orep(x, y) for (int x = 1; x <= y; x++)
#define ll long long
template <class T>
bool chmax(T &a, const T &b) {
  return a < b ? (a = b, 1) : 0;
}
template <class T>
bool chmin(T &a, const T &b) {
  return b < a ? (a = b, 1) : 0;
}
using namespace std;
using P = pair<int, int>;

const vector<P> DIRS = {{1, 0}, {0, -1}, {-1, 0}, {0, 1}};

struct Dice {
  int top_n = -1, front_n = -1;

  vector<int> get_sides() {
    if (top_n == 6) {
      return vector<int>{2, 3, 5, 4};
    }
    if (top_n == 5) {
      return vector<int>{3, 1, 4, 6};
    }
    if (top_n == 4) {
      return vector<int>{1, 2, 6, 5};
    }
    if (top_n == 3) {
      return vector<int>{2, 1, 5, 6};
    }
    if (top_n == 2) {
      return vector<int>{1, 3, 6, 4};
    }
    if (top_n == 1) {
      return vector<int>{3, 2, 4, 5};
    }
    exit(1);
  }

  int get_bottom() { return 7 - top_n; }

  vector<P> get_dirs() {
    vector<int> sides = get_sides();

    vector<int> idx_list;
    for (int i = 6; i >= 4; i--) {
      rep(si, 4) {
        if (sides[si] == i) idx_list.push_back(si);
      }
    }

    int rotate_cnt = -1;
    rep(i, 4) {
      if (sides[i] == front_n) {
        rotate_cnt = i;
      }
    }

    return vector<P>{DIRS[(idx_list[0] - rotate_cnt + 4) % 4],
                     DIRS[(idx_list[1] - rotate_cnt + 4) % 4]};
  }

  Dice rotate(P dir) {
    vector<int> sides = get_sides();
    int rotate_cnt = -1;
    rep(i, 4) {
      if (sides[i] == front_n) {
        rotate_cnt = i;
      }
    }

    int dir_no = -1;
    rep(i, 4) {
      if (DIRS[i].first == dir.first && DIRS[i].second == dir.second) {
        dir_no = i;
      }
    }

    int under_n = sides[(dir_no + rotate_cnt) % 4];
    if (dir_no == 0) {
      return Dice{7 - under_n, top_n};
    }
    if (dir_no == 2) {
      return Dice{7 - under_n, get_bottom()};
    }
    if (dir_no % 2) {
      return Dice{7 - under_n, front_n};
    }
    exit(1);
  }
};
struct Floor {
  vector<vector<Dice>> floor;
  Floor() {
    vector<vector<Dice>> new_floor(100, vector<Dice>(100));
    swap(new_floor, floor);
  }

  Dice &get(int h, int w) { return floor[h + 50][w + 50]; }
};

struct Field {
  int highest = 0;

  vector<Floor> field;
  Field() {
    vector<Floor> new_field(100);
    swap(field, new_field);
  }

  void fall(Dice a) {
    int now = highest - 1;
    Dice dice = a;
    int h = 0;
    int w = 0;
    while (1) {
      if (now < 0) break;
      bool has_move = false;
      auto dirs = a.get_dirs();
      for (auto d : dirs) {
        int new_h = h + d.first;
        int new_w = w + d.second;
        if (field[now].get(new_h, new_w).top_n == -1) {
          has_move = true;
          a = a.rotate(d);
          h = new_h;
          w = new_w;
          break;
        }
      }
      if (has_move) {
        now--;
        while (now >= 0 && field[now].get(h, w).top_n == -1) {
          now--;
        }
      } else {
        break;
      }
    }
    if (h == 0 && w == 0) {
      field[highest].get(h, w) = a;
      highest++;
    } else {
      field[now + 1].get(h, w) = a;
    }
  }

  void output() {
    vector<vector<bool>> used(100, vector<bool>(100, false));
    vector<int> ans(7);
    rrep(layer, 100) {
      rep(hi, 100) rep(wi, 100) {
        if (used[hi][wi]) continue;
        if (field[layer].floor[hi][wi].top_n == -1) continue;
        used[hi][wi] = true;
        ans[field[layer].floor[hi][wi].top_n]++;
      }
    }
    rep(i, 7) {
      if (i == 0) continue;
      if (i == 6) {
        cout << ans[i] << endl;
      } else {
        cout << ans[i] << " ";
      }
    }
  }
};

bool func() {
  int n;
  cin >> n;
  if (n == 0) return false;

  Field field;
  rep(i, n) {
    int top, front;
    cin >> top >> front;
    field.fall(Dice{top, front});
  }
  field.output();
  return true;
}

int main() {
  while (func()) {
    ;
  }
}
accuracy: 1
time_ms: 280
memory_kb: 11576
final_rank: 15

code_snippet: // #define _GLIBCXX_DEBUG
#include <bits/stdc++.h>
//#include <atcoder/all>
using namespace std;
//using namespace atcoder;

#define int long long
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define rep(i, n) for (int i = 0; i < n; ++i)
#define REP(i, n) for (int i = 0; i < n; ++i)
#define range(i,a,b) ((a)<=(i) && (i)<(b))
#define debug(x) cout << #x << " = " << (x) << endl;
#define fs first
#define sc second
#define pb push_back
#define eb emplace_back
#define SP << " " <<

typedef long long ll;
typedef pair<int, int> P;
typedef tuple<int, int, int> T;
typedef vector<int> vec;
typedef vector<P> pvec;
typedef vector<vector<int>> vvec;
typedef vector<vector<P>> pvvec;
typedef priority_queue<int> PQI;
typedef priority_queue<P> PQP;
typedef priority_queue<int,vector<int>,greater<int>> PQIG;
typedef priority_queue<P,vector<P>,greater<P>> PQPG;

const vector<int> DX = {0, -1, 0, 1, 1, 1, -1, -1};
const vector<int> DY = {1, 0, -1, 0, 1, -1, 1, -1};
constexpr int MOD = (1000000007);
// const int MOD = (998244353);
// const int INF = (1 << 30); // 1073741824
const ll INF = (1LL << 60); // 1152921504606846976
const double PI = (3.141592653589794);
const double EPS = (0.0000000001); // 10^(-10)

template<class T> inline bool chmin(T& a, T b) {if (a > b) {a = b; return 1;} return 0;}
template<class T> inline bool chmax(T& a, T b) {if (a < b) {a = b; return 1;} return 0;}
template<class T> inline T ceil(T a, T b) {return T((a + b - 1) / b);}
template<class T> inline T round(T a, T b) {return T(a / b);}
template< typename T1, typename T2 > istream &operator>>(istream &is, pair< T1, T2 > &p) { is >> p.first >> p.second; return is; }
template <class T> inline void out(T &a) { bool flag=true; for(auto&x:a){if(flag) {flag=false;} else{ cout << ' '; } cout<<x; } cout << endl; }



//----------------------------------------------------------------
int nmax=200000; // 2*(10^5)
vvec G(nmax);

struct sai{
  vvec rr={{0,3,5,2,4,0},
          {4,0,1,6,0,3},
          {2,6,0,0,1,5},
          {5,1,0,0,6,2},
          {3,0,6,1,0,4},
          {0,4,2,5,3,0}};
  int tf(int t,int f){
    return rr[t-1][f-1];
  };
  vec four(int t,int f){
    int r=tf(t,f);
    return vector<int>{f,r,7-f,7-r}; // 手前、右、奥、左 // x, y, -x, -y
  }
};

const vector<int> dx = {1, 0, -1, 0, 1, 1, -1, -1};
const vector<int> dy = {0, 1, 0, -1, 1, -1, 1, -1};

int h[300][300];
int me[300][300];

void solve4ts()
{
  
  
  int n;
  cin>>n;
  if(n==0) exit(0);
  sai saikoro;
  
  int geta=150;
  rep(i,300) rep(j,300){
    h[i][j]=0;
    me[i][j]=0;
  }
  rep(_,n){
    
    int x=geta; int y=geta;
    int t,f; cin>>t>>f;
    while(true){
      bool koro=false;
      vec four = saikoro.four(t,f);
      for(int c=6;c>=4;c--){
        rep(dir,4){
          if(c==four[dir]){
            int nx=x+dx[dir];
            int ny=y+dy[dir];
            if(h[nx][ny]<h[x][y]){
              int nt,nf;
              int r=saikoro.tf(t,f);
              if(dir==0) nt=7-f,nf=t;
              if(dir==1) nt=7-r,nf=f;
              if(dir==2) nt=f,nf=7-t;
              if(dir==3) nt=r,nf=f;
              t=nt; f=nf; x=nx; y=ny;
              koro=true;
              break;
            }
          }
        }
        if(koro) break;
      }
      if(!koro) break;
    }
    h[x][y]++;
    me[x][y]=t;
  }
  vec count(10);
  rep(i,300) rep(j,300) count[me[i][j]]++;
  for(int i=1;i<=6;i++){
    if(i==6) cout<<count[i];
    else cout<<count[i]<<" ";
  }
  cout<<endl;
}
//-----------------------------------------------------------------

signed main(){ ios::sync_with_stdio(false); cin.tie(0); cout << fixed << setprecision(15);
  int repeat = INF;
  // cin >> repeat;
  while(repeat--) solve4ts();
}

/*

g++ -std=c++1z code.cpp

./a.out

python3 expander.py code.cpp

*/
accuracy: 1
time_ms: 20
memory_kb: 9080
final_rank: 14

code_snippet: #include <bits/stdc++.h>
#ifdef MY_DEBUG
  #include "dprint.cpp"
  # define dprint(a, ...);\
      do {\
          printf("line : %d, func : %s\n",\
                __LINE__, __func__);\
          dprint(#a,a,##__VA_ARGS__ );\
      } while (0)
#else
  #define dprint(a,...) 
#endif
using namespace std;
vector<vector<vector<int>>>room;
int n;
vector<int> get_room(int x,int y){
  return room[x+n][y+n];
}

void set_room(int x,int y,int top){
  room[x+n][y+n][0]++;
  room[x+n][y+n][1]=top;
}

int get_right_side(int top,int front){
  top--;
  front--;
  int right_side[6][6]={
    {0,3,5,2,4,0},
    {4,0,1,6,0,3},
    {2,6,0,0,1,5},
    {5,1,0,0,6,2},
    {3,0,6,1,0,4},
    {0,4,2,5,3,0}
  };

  return right_side[top][front];

}

void solve(vector<vector<int>> vec){

for (auto v :vec){
  int now_x=0;
  int now_y=0;
  int  now_z=get_room(now_x,now_x)[0];
  int now_top=v[0];
  int now_front=v[1];

  while (true){
    int rotate=-1;
    int rotate_num=-1;

    //front
    int dice=now_front;
    if(dice>=4&& rotate_num<dice){
      //目の大きさ的に回転する可能性あり
      if(get_room(now_x,now_y+1)[0]<now_z){
        //高低差あり
        rotate_num=dice;
        rotate=0;//front
      }
    }

    //back 7-front
     dice=7-now_front;
    if(dice>=4&& rotate_num<dice){
      //目の大きさ的に回転する可能性あり
      if(get_room(now_x,now_y-1)[0]<now_z){
        //高低差あり

        rotate_num=dice;
        rotate=1;//-front
      }
    }

    //right get_right_side(top,front)
    dice=get_right_side(now_top,now_front);
    if(dice>=4&& rotate_num<dice){
      //目の大きさ的に回転する可能性あり
      if(get_room(now_x+1,now_y)[0]<now_z){
        //高低差あり
        rotate_num=dice;
        rotate=2;//right
      }
    }
    //left 7-get_right_side(top,side)
    dice=7-get_right_side(now_top,now_front);
    if(dice>=4&& rotate_num<dice){
      //目の大きさ的に回転する可能性あり
      if(get_room(now_x-1,now_y)[0]<now_z){
        //高低差あり
        rotate_num=dice;
        rotate=3;//-right
      }
    }

    if(rotate_num==-1){
      //確定(転がることができない)
      set_room(now_x,now_y,now_top);
      break;
    }
    int t_front=now_front;
    int t_back=7-now_front;
    int t_right=get_right_side(now_top,now_front);
    int t_left=7-get_right_side(now_top,now_front);
    int t_top=now_top;
    int t_bottom=7-now_top;

    switch (rotate){
      case 0:
       now_front=t_top;
       now_top=t_back;
      
       now_y++;
       now_z=get_room(now_x,now_y)[0];
      break;
      
      case 1:
        now_front=t_bottom;
        now_top=t_front;

        now_y--;
        now_z=get_room(now_x,now_y)[0];
        break; 
      case 2:
        now_top=t_left;

        now_x++;
        now_z=get_room(now_x,now_y)[0];
        break;

      case 3:
        now_top=t_right; 

        now_x--;
        now_z=get_room(now_x,now_y)[0];
        break;
      }
  }
  
  

}



}

int main() {
  while (true){
  cin >>n;
  if(n==0)break;

  vector<vector<int>> vec(n, vector<int>(2));
  for (int i = 0; i < n; i++){
    for(int j=0;j<2;j++){
      cin >> vec[i][j];
    }
  }
  room=vector<vector<vector<int>>>(2*n+1,vector<vector<int>>(2*n+1,vector<int>(2,0)));
  solve(vec);
  vector<int>ans(7,0);
  for (int i = 0; i < 2*n+1; i++){
    for (int j = 0; j < 2*n+1; j++){
      ans[room[i][j][1]]++;
    }
    
  }
  for (int i = 1; i <= 6; i++)
  {
    cout <<ans[i] ; 
    if(i!=6)cout << " ";
  }
  cout   << endl;
  
  }
  
return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 7464
final_rank: 13

code_snippet: #include<bits/stdc++.h>
using namespace std;
using ll=long long;

vector<int> make_dice(int t,int f){
    vector<int> dice(6);
    dice[0]=f,dice[2]=7-f;
    dice[4]=t,dice[5]=7-t;
    if(f==1&&t==2) dice[1]=3;
    if(f==1&&t==3) dice[1]=5;
    if(f==1&&t==4) dice[1]=2;
    if(f==1&&t==5) dice[1]=4;
    if(f==2&&t==1) dice[1]=4;
    if(f==2&&t==3) dice[1]=1;
    if(f==2&&t==4) dice[1]=6;
    if(f==2&&t==6) dice[1]=3;
    if(f==3&&t==1) dice[1]=2;
    if(f==3&&t==2) dice[1]=6;
    if(f==3&&t==5) dice[1]=1;
    if(f==3&&t==6) dice[1]=5;
    if(f==4&&t==1) dice[1]=5;
    if(f==4&&t==2) dice[1]=1;
    if(f==4&&t==5) dice[1]=6;
    if(f==4&&t==6) dice[1]=2;
    if(f==5&&t==1) dice[1]=3;
    if(f==5&&t==3) dice[1]=6;
    if(f==5&&t==4) dice[1]=1;
    if(f==5&&t==6) dice[1]=4;
    if(f==6&&t==2) dice[1]=4;
    if(f==6&&t==3) dice[1]=2;
    if(f==6&&t==4) dice[1]=5;
    if(f==6&&t==5) dice[1]=3;
    dice[3]=7-dice[1];
    return dice;
}

vector<int> rotate(vector<int> dice,int d){
    if(d==0){
        return {dice[4],dice[1],dice[5],dice[3],dice[2],dice[0]};
    }
    if(d==1){
        return {dice[0],dice[4],dice[2],dice[5],dice[3],dice[1]};
    }
    if(d==2){
        return {dice[5],dice[1],dice[4],dice[3],dice[0],dice[2]};
    }
    if(d==3){
        return {dice[0],dice[5],dice[2],dice[4],dice[1],dice[3]};
    }
    return {};
}

void solve(){
    while(1){
        map<pair<int,int>,int> num,height;
        vector<int> dx={0,-1,0,1},dy={-1,0,1,0};
        int n;
        cin>>n;
        if(n==0){
            break;
        }
        vector<int> t(n),f(n);
        for(int i=0;i<n;i++){
            cin>>t[i]>>f[i];
        }
        for(int i=0;i<n;i++){
            vector<int> dice=make_dice(t[i],f[i]);
            int x=0,y=0,h=height[{x,y}]+1;
            while(1){
                vector<pair<int,int>> possible_move;
                for(int d=0;d<4;d++){
                    if(dice[d]>=4&&h>height[{x+dx[d],y+dy[d]}]+1){
                        possible_move.push_back({dice[d],d});
                    }
                }
                if(possible_move.size()==0){
                    num[{x,y}]=dice[4];
                    height[{x,y}]=h;
                    break;
                }
                sort(possible_move.begin(),possible_move.end(),greater<pair<int,int>>());
                int rd=possible_move[0].second;
                x+=dx[rd],y+=dy[rd];
                h=height[{x,y}]+1;
                dice=rotate(dice,rd);
            }
        }
        vector<int> ans(7,0);
        for(int x=-200;x<=200;x++){
            for(int y=-200;y<=200;y++){
                ans[num[{x,y}]]++;
            }
        }
        for(int i=1;i<=5;i++){
            cout<<ans[i]<<" ";
        }
        cout<<ans[6]<<endl;
    }
    return;
}

int main(){
    solve();
    return 0;
}
accuracy: 1
time_ms: 3150
memory_kb: 13232
final_rank: 17

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
#include <deque>
#include <queue>
#include <string>
#include <iomanip>
#include <set>
#include <unordered_set>
#include <map>
#include <unordered_map>
#include <utility>
#include <stack>
#include <random>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include <assert.h>
#if __has_include(<atcoder/all>)
#include <atcoder/all>
using namespace atcoder;
#endif
using namespace std;
using ll=long long;
#define read(x) cin>>(x);
#define readll(x) ll (x);cin>>(x);
#define readS(x) string (x);cin>>(x);
#define readvll(x,N) vector<ll> (x)((N));for(int i=0;i<(N);i++){cin>>(x)[i];}
#define rep(i,N) for(ll (i)=0;(i)<(N);(i)++)
#define rep2d(i,j,H,W) for(ll (i)=0;(i)<(H);(i)++)for(ll (j)=0;(j)<(W);j++)
#define is_in(x,y) (0<=(x) && (x)<H && 0<=(y) && (y)<W)
#define yn {cout<<"Yes"<<endl;}else{cout<<"No"<<endl;}
inline ll powll(ll x,ll n){ll r=1;while(n>0){if(n&1){r*=x;};x*=x;n>>=1;};return r;}

const ll M=200;

struct Dice{
  ll top,front,bottom,back,left,right;
  Dice(){
    top=1;
    front=3;
    bottom=6;
    back=4;
    left=2;
    right=5;
  }
};

void debug(Dice x){
  cerr<<x.top<<" "<<x.front<<" "<<x.bottom<<" "<<x.back<<" "<<x.left<<" "<<x.right<<endl;
}

Dice roll_right(Dice x){
  Dice res;
  res.top=x.left;
  res.front=x.front;
  res.bottom=x.right;
  res.back=x.back;
  res.left=x.bottom;
  res.right=x.top;
  return res;
}

Dice roll_left(Dice x){
  Dice res;
  res.top=x.right;
  res.front=x.front;
  res.bottom=x.left;
  res.back=x.back;
  res.left=x.top;
  res.right=x.bottom;
  return res;
}

Dice roll_front(Dice x){
  Dice res;
  res.top=x.back;
  res.front=x.top;
  res.bottom=x.front;
  res.back=x.bottom;
  res.left=x.left;
  res.right=x.right;
  return res;
}

Dice roll_back(Dice x){
  Dice res;
  res.top=x.front;
  res.front=x.bottom;
  res.bottom=x.back;
  res.back=x.top;
  res.left=x.left;
  res.right=x.right;
  return res;
}

Dice spin_right(Dice x){
  Dice res;
  res.top=x.top;
  res.front=x.right;
  res.bottom=x.bottom;
  res.back=x.left;
  res.left=x.front;
  res.right=x.back;
  return res;
}

Dice spin_left(Dice x){
  Dice res;
  res.top=x.top;
  res.front=x.left;
  res.bottom=x.bottom;
  res.back=x.right;
  res.left=x.back;
  res.right=x.front;
  return res;
}

Dice getDice(ll t,ll f){
  Dice res;
  if(t==1){
    if(f==2){
      res=spin_left(res);
      return res;
    }else if(f==3){
      return res;
    }else if(f==4){
      res=spin_left(res);
      res=spin_left(res);
      return res;
    }else if(f==5){
      res=spin_right(res);
      return res;
    }else{
      exit(1);
    }
  }else if(t==2){
    res=roll_right(res);
    if(f==1){
      res=spin_right(res);
      return res;
    }else if(f==3){
      return res;
    }else if(f==4){
      res=spin_right(res);
      res=spin_right(res);
      return res;
    }else if(f==6){
      res=spin_left(res);
      return res;
    }else{
      exit(1);
    }
  }else if(t==3){
    res=roll_back(res);
    if(f==1){
      res=spin_left(res);
      res=spin_left(res);
      return res;
    }else if(f==2){
      res=spin_left(res);
      return res;
    }else if(f==5){
      res=spin_right(res);
      return res;
    }else if(f==6){
      return res;
    }else{
      exit(1);
    }
  }else if(t==4){
    res=roll_front(res);
    if(f==1){
      return res;
    }else if(f==2){
      res=spin_left(res);
      return res;
    }else if(f==5){
      res=spin_right(res);
      return res;
    }else if(f==6){
      res=spin_left(res);
      res=spin_left(res);
      return res;
    }else{
      exit(1);
    }
  }else if(t==5){
    res=roll_left(res);
    if(f==1){
      res=spin_left(res);
      return res;
    }else if(f==3){
      return res;
    }else if(f==4){
      res=spin_left(res);
      res=spin_left(res);
      return res;
    }else if(f==6){
      res=spin_right(res);
      return res;
    }else{
      exit(1);
    }
  }else{
    res=roll_left(res);
    res=roll_left(res);
    if(f==2){
      res=spin_right(res);
      return res;
    }else if(f==3){
      return res;
    }else if(f==4){
      res=spin_left(res);
      res=spin_left(res);
      return res;
    }else if(f==5){
      res=spin_left(res);
      return res;
    }else{
      exit(1);
    }
  }
  //exit(1);
}


void solve(ll n){
  ll t,f;
  vector<vector<pair<ll,ll>>> d(2*M+1,vector<pair<ll,ll>>(2*M+1,make_pair(0,0)));// 高さ、数
  vector<ll> ans(7);
  for(ll i=0;i<n;i++){
    cin>>t>>f;
    //cerr<<endl<<t<<" "<<f<<endl;
    Dice di=getDice(t,f);
    //debug(di);
    ll x=M,y=M;
    ll dx,dy;
    while(1){
      vector<pair<ll,pair<ll,ll>>> tmp;
      if(d[x][y].first>d[x+1][y].first && di.right>=4){
        tmp.push_back(make_pair(di.right,make_pair(1,0)));
      }
      if(d[x][y].first>d[x][y+1].first && di.back>=4){
        tmp.push_back(make_pair(di.back,make_pair(0,1)));
      }
      if(d[x][y].first>d[x-1][y].first && di.left>=4){
        tmp.push_back(make_pair(di.left,make_pair(-1,0)));
      }
      if(d[x][y].first>d[x][y-1].first && di.front>=4){
        tmp.push_back(make_pair(di.front,make_pair(0,-1)));
      }
      sort(tmp.rbegin(),tmp.rend());
      if(tmp.empty()){
        ans[d[x][y].second]--;
        ans[di.top]++;
        d[x][y].first++;
        d[x][y].second=di.top;
        break;
      }
      dx=tmp[0].second.first;
      dy=tmp[0].second.second;
      //cerr<<dx<<" "<<dy<<endl;
      if(dx==1 && dy==0){
        di=roll_right(di);
      }else if(dx==0 && dy==1){
        di=roll_back(di);
      }else if(dx==-1 && dy==0){
        di=roll_left(di);
      }else if(dx==0 && dy==-1){
        di=roll_front(di);
      }else{
        exit(1);
      }
      x+=dx;
      y+=dy;
    }
  }
  cout<<ans[1]<<" "<<ans[2]<<" "<<ans[3]<<" "<<ans[4]<<" "<<ans[5]<<" "<<ans[6]<<endl;
}

int main(){
  ll n;
  while(1){
    cin>>n;
    if(n==0){
      break;
    }
    solve(n);
  }
}
accuracy: 1
time_ms: 90
memory_kb: 5616
final_rank: 12

code_snippet: #pragma GCC target("avx,avx2")
//#pragma GCC optimize("Ofast")
//#undef LOCAL

#include <unistd.h>
#include <algorithm>
#include <array>
#include <cassert>
#include <cctype>
#include <cstring>
#include <sstream>
#include <string>
#include <type_traits>
#include <vector>

namespace yosupo {

namespace internal {

int ceil_pow2(int n) {
    int x = 0;
    while ((1U << x) < (unsigned int)(n)) x++;
    return x;
}

}  // namespace internal

int bsf(unsigned int n) {
    return __builtin_ctz(n);
}
int bsf(unsigned long n) {
    return __builtin_ctzl(n);
}
int bsf(unsigned long long n) {
    return __builtin_ctzll(n);
}
int bsf(unsigned __int128 n) {
    unsigned long long low = (unsigned long long)(n);
    unsigned long long high = (unsigned long long)(n >> 64);
    return low ? __builtin_ctzll(low) : 64 + __builtin_ctzll(high);
}

int bsr(unsigned int n) {
    return 8 * (int)sizeof(unsigned int) - 1 - __builtin_clz(n);
}
int bsr(unsigned long n) {
    return 8 * (int)sizeof(unsigned long) - 1 - __builtin_clzl(n);
}
int bsr(unsigned long long n) {
    return 8 * (int)sizeof(unsigned long long) - 1 - __builtin_clzll(n);
}
int bsr(unsigned __int128 n) {
    unsigned long long low = (unsigned long long)(n);
    unsigned long long high = (unsigned long long)(n >> 64);
    return high ? 127 - __builtin_clzll(high) : 63 - __builtin_ctzll(low);
}

int popcnt(unsigned int n) {
    return __builtin_popcount(n);
}
int popcnt(unsigned long n) {
    return __builtin_popcountl(n);
}
int popcnt(unsigned long long n) {
    return __builtin_popcountll(n);
}

}  // namespace yosupo

#include <cassert>
#include <numeric>
#include <type_traits>

namespace yosupo {

namespace internal {

template <class T> using is_signed_int128 =
    typename std::conditional<std::is_same<T, __int128_t>::value || std::is_same<T, __int128>::value,
                              std::true_type, std::false_type>::type;

template <class T> using is_unsigned_int128 =
    typename std::conditional<std::is_same<T, __uint128_t>::value ||
                                  std::is_same<T, unsigned __int128>::value,
                              std::true_type, std::false_type>::type;

template <class T> using make_unsigned_int128 =
    typename std::conditional<std::is_same<T, __int128_t>::value, __uint128_t, unsigned __int128>;

template <class T> using is_integral =
    typename std::conditional<std::is_integral<T>::value || internal::is_signed_int128<T>::value ||
                                  internal::is_unsigned_int128<T>::value,
                              std::true_type, std::false_type>::type;

template <class T> using is_signed_int =
    typename std::conditional<(is_integral<T>::value && std::is_signed<T>::value) ||
                                  is_signed_int128<T>::value,
                              std::true_type, std::false_type>::type;

template <class T> using is_unsigned_int =
    typename std::conditional<(is_integral<T>::value && std::is_unsigned<T>::value) ||
                                  is_unsigned_int128<T>::value,
                              std::true_type, std::false_type>::type;

template <class T> using to_unsigned =
    typename std::conditional<is_signed_int128<T>::value, make_unsigned_int128<T>,
                              typename std::conditional<std::is_signed<T>::value, std::make_unsigned<T>,
                                                        std::common_type<T>>::type>::type;

template <class T> using is_integral_t = std::enable_if_t<is_integral<T>::value>;

template <class T> using is_signed_int_t = std::enable_if_t<is_signed_int<T>::value>;

template <class T> using is_unsigned_int_t = std::enable_if_t<is_unsigned_int<T>::value>;

template <class T> using to_unsigned_t = typename to_unsigned<T>::type;

}  // namespace internal

}  // namespace yosupo

namespace yosupo {

struct Scanner {
public:
    Scanner(const Scanner&) = delete;
    Scanner& operator=(const Scanner&) = delete;

    Scanner(FILE* fp) : fd(fileno(fp)) {}

    void read() {}
    template <class H, class... T> void read(H& h, T&... t) {
        bool f = read_single(h);
        assert(f);
        read(t...);
    }

    int read_unsafe() { return 0; }
    template <class H, class... T> int read_unsafe(H& h, T&... t) {
        bool f = read_single(h);
        if (!f) return 0;
        return 1 + read_unsafe(t...);
    }

    int close() { return ::close(fd); }

private:
    static constexpr size_t SIZE = 1 << 15;

    int fd = -1;
    std::array<char, SIZE> line;
    size_t st = 0, ed = 0;
    bool eof = false;

    bool read_single(std::string& ref) {
        if (!skip_space()) return false;
        ref = "";
        while (true) {
            char c = top();
            if (c <= ' ') break;
            ref += c;
            st++;
        }
        return true;
    }
    bool read_single(double& ref) {
        std::string s;
        if (!read_single(s)) return false;
        ref = std::stod(s);
        return true;
    }

    template <class T, std::enable_if_t<std::is_same<T, char>::value>* = nullptr>
    bool read_single(T& ref) {
        if (!skip_space(50)) return false;
        ref = top();
        st++;
        return true;
    }

    template <class T, internal::is_signed_int_t<T>* = nullptr,
              std::enable_if_t<!std::is_same<T, char>::value>* = nullptr>
    bool read_single(T& sref) {
        using U = internal::to_unsigned_t<T>;
        if (!skip_space(50)) return false;
        bool neg = false;
        if (line[st] == '-') {
            neg = true;
            st++;
        }
        U ref = 0;
        do {
            ref = 10 * ref + (line[st++] & 0x0f);
        } while (line[st] >= '0');
        sref = neg ? -ref : ref;
        return true;
    }
    template <class U, internal::is_unsigned_int_t<U>* = nullptr,
              std::enable_if_t<!std::is_same<U, char>::value>* = nullptr>
    bool read_single(U& ref) {
        if (!skip_space(50)) return false;
        ref = 0;
        do {
            ref = 10 * ref + (line[st++] & 0x0f);
        } while (line[st] >= '0');
        return true;
    }

    bool reread() {
        if (ed - st >= 50) return true;
        if (st > SIZE / 2) {
            std::memmove(line.data(), line.data() + st, ed - st);
            ed -= st;
            st = 0;
        }
        if (eof) return false;
        auto u = ::read(fd, line.data() + ed, SIZE - ed);
        if (u == 0) {
            eof = true;
            line[ed] = '\0';
            u = 1;
        }
        ed += u;
        return true;
    }

    char top() {
        if (st == ed) {
            bool f = reread();
            assert(f);
        }
        return line[st];
    }

    bool skip_space(unsigned int token_len = 0) {
        while (true) {
            while (st != ed && line[st] <= ' ') st++;
            if (ed - st > token_len) return true;
            for (auto i = st; i < ed; i++) {
                if (line[i] <= ' ') return true;
            }
            if (!reread()) return false;
        }
    }
};

struct Printer {
public:
    template <char sep = ' ', bool F = false> void write() {}
    template <char sep = ' ', bool F = false, class H, class... T> void write(const H& h, const T&... t) {
        if (F) write_single(sep);
        write_single(h);
        write<true>(t...);
    }
    template <char sep = ' ', class... T> void writeln(const T&... t) {
        write<sep>(t...);
        write_single('\n');
    }

    Printer(FILE* _fp) : fd(fileno(_fp)) {}
    ~Printer() { flush(); }

    int close() {
        flush();
        return ::close(fd);
    }

    void flush() {
        if (pos) {
            auto res = ::write(fd, line.data(), pos);
            assert(res != -1);
            pos = 0;
        }
    }

private:
    static std::array<std::array<char, 2>, 100> small;
    static std::array<unsigned long long, 20> tens;

    static constexpr size_t SIZE = 1 << 15;
    int fd;
    std::array<char, SIZE> line;
    size_t pos = 0;
    std::stringstream ss;

    template <class T, std::enable_if_t<std::is_same<char, T>::value>* = nullptr>
    void write_single(const T& val) {
        if (pos == SIZE) flush();
        line[pos++] = val;
    }

    template <class T, internal::is_signed_int_t<T>* = nullptr,
              std::enable_if_t<!std::is_same<char, T>::value>* = nullptr>
    void write_single(const T& val) {
        using U = internal::to_unsigned_t<T>;
        if (val == 0) {
            write_single('0');
            return;
        }
        if (pos > SIZE - 50) flush();
        U uval = val;
        if (val < 0) {
            write_single('-');
            uval = -uval;
        }
        write_unsigned(uval);
    }

    template <class U, internal::is_unsigned_int_t<U>* = nullptr> void write_single(U uval) {
        if (uval == 0) {
            write_single('0');
            return;
        }
        if (pos > SIZE - 50) flush();

        write_unsigned(uval);
    }

    template <class U, internal::is_unsigned_int_t<U>* = nullptr> static int calc_len(U x) {
        int i = (bsr(x) * 3 + 3) / 10;
        if (x < tens[i])
            return i;
        else
            return i + 1;
    }

    template <class U, internal::is_unsigned_int_t<U>* = nullptr,
              std::enable_if_t<8 >= sizeof(U)>* = nullptr>
    void write_unsigned(U uval) {
        size_t len = calc_len(uval);
        pos += len;

        char* ptr = line.data() + pos;
        while (uval >= 100) {
            ptr -= 2;
            memcpy(ptr, small[uval % 100].data(), 2);
            uval /= 100;
        }
        if (uval >= 10) {
            memcpy(ptr - 2, small[uval].data(), 2);
        } else {
            *(ptr - 1) = char('0' + uval);
        }
    }

    template <class U, std::enable_if_t<internal::is_unsigned_int128<U>::value>* = nullptr>
    void write_unsigned(U uval) {
        static std::array<char, 50> buf;
        size_t len = 0;
        while (uval > 0) {
            buf[len++] = char((uval % 10) + '0');
            uval /= 10;
        }
        std::reverse(buf.begin(), buf.begin() + len);
        memcpy(line.data() + pos, buf.data(), len);
        pos += len;
    }

    void write_single(const std::string& s) {
        for (char c : s) write_single(c);
    }
    void write_single(const char* s) {
        size_t len = strlen(s);
        for (size_t i = 0; i < len; i++) write_single(s[i]);
    }
    template <class T> void write_single(const std::vector<T>& val) {
        auto n = val.size();
        for (size_t i = 0; i < n; i++) {
            if (i) write_single(' ');
            write_single(val[i]);
        }
    }
};

std::array<std::array<char, 2>, 100> Printer::small = [] {
    std::array<std::array<char, 2>, 100> table;
    for (int i = 0; i <= 99; i++) {
        table[i][1] = char('0' + (i % 10));
        table[i][0] = char('0' + (i / 10 % 10));
    }
    return table;
}();
std::array<unsigned long long, 20> Printer::tens = [] {
    std::array<unsigned long long, 20> table;
    for (int i = 0; i < 20; i++) {
        table[i] = 1;
        for (int j = 0; j < i; j++) {
            table[i] *= 10;
        }
    }
    return table;
}();

}  // namespace yosupo
using namespace yosupo;

#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <complex>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>

using namespace std;

using uint = unsigned int;
using ll = long long;
using ull = unsigned long long;
constexpr ll TEN(int n) {
    return (n == 0) ? 1 : 10 * TEN(n - 1);
}
template <class T> using V = vector<T>;
template <class T> using VV = V<V<T>>;

#ifdef LOCAL

ostream& operator<<(ostream& os, __int128_t x) {
    if (x < 0) {
        os << "-";
        x *= -1;
    }
    if (x == 0) {
        return os << "0";
    }
    string s;
    while (x) {
        s += char(x % 10 + '0');
        x /= 10;
    }
    reverse(s.begin(), s.end());
    return os << s;
}
ostream& operator<<(ostream& os, __uint128_t x) {
    if (x == 0) {
        return os << "0";
    }
    string s;
    while (x) {
        s += char(x % 10 + '0');
        x /= 10;
    }
    reverse(s.begin(), s.end());
    return os << s;
}

template <class T, class U> ostream& operator<<(ostream& os, const pair<T, U>& p);
template <class T> ostream& operator<<(ostream& os, const V<T>& v);
template <class T> ostream& operator<<(ostream& os, const deque<T>& v);
template <class T, size_t N> ostream& operator<<(ostream& os, const array<T, N>& a);
template <class T> ostream& operator<<(ostream& os, const set<T>& s);
template <class T, class U> ostream& operator<<(ostream& os, const map<T, U>& m);

template <class T, class U> ostream& operator<<(ostream& os, const pair<T, U>& p) {
    return os << "P(" << p.first << "," << p.second << ")";
}

template <class T> ostream& operator<<(ostream& os, const V<T>& v) {
    os << "[";
    bool f = false;
    for (auto d : v) {
        if (f) os << ",";
        f = true;
        os << d;
    }
    return os << "]";
}

template <class T> ostream& operator<<(ostream& os, const deque<T>& v) {
    os << "[";
    bool f = false;
    for (auto d : v) {
        if (f) os << ",";
        f = true;
        os << d;
    }
    return os << "]";
}
template <class T, size_t N> ostream& operator<<(ostream& os, const array<T, N>& a) {
    os << "[";
    bool f = false;
    for (auto d : a) {
        if (f) os << ",";
        f = true;
        os << d;
    }
    return os << "]";
}

template <class T> ostream& operator<<(ostream& os, const set<T>& s) {
    os << "{";
    bool f = false;
    for (auto d : s) {
        if (f) os << ",";
        f = true;
        os << d;
    }
    return os << "}";
}

template <class T, class U> ostream& operator<<(ostream& os, const map<T, U>& s) {
    os << "{";
    bool f = false;
    for (auto p : s) {
        if (f) os << ",";
        f = true;
        os << p.first << ": " << p.second;
    }
    return os << "}";
}

struct PrettyOS {
    ostream& os;
    bool first;

    template <class T> auto operator<<(T&& x) {
        if (!first) os << ",";
        first = false;
        os << x;
        return *this;
    }
};
template <class... T> void dbg0(T&&... t) {
    (PrettyOS{cerr, true} << ... << t);
}
#define dbg(...)                                           \
    do {                                                   \
        cerr << __LINE__ << ": " << #__VA_ARGS__ << " = "; \
        dbg0(__VA_ARGS__);                                 \
        cerr << endl;                                      \
    } while (false);
#else
#define dbg(...)
#endif

Scanner sc = Scanner(stdin);
Printer pr = Printer(stdout);

/**
 * サイコロ。6面あって、各面には数字が書かれている。
 * 転がすことができる。
 * 0: up, 1: front, 2: right, 3: left, 4: back, 5: down
 */
struct Dice {
    // 0: up, 1: front, 2: right, 3: left, 4: back, 5: down
    // 0: U,  1: F    , 2: R,     3: L,    4: B,    5: D
    array<int, 6> num;
    Dice() { num = array<int, 6>{1, 2, 3, 4, 5, 6}; }
    Dice(const array<int, 6>& num) : num(num) {}
    // dice を up から見て、 North、East、West、South を考える
    //   N
    // W d E
    //   S
    void rollN() { roll_y_left_hand(); }
    void rollE() { roll_x_left_hand(); }
    void rollW() { roll_x_right_hand(); }
    void rollS() { roll_y_right_hand(); }

    void roll_x_right_hand() { roll(0, 3, 5, 2); }
    void roll_y_right_hand() { roll(0, 1, 5, 4); }
    void roll_z_right_hand() { roll(1, 2, 4, 3); }
    void roll_x_left_hand() { roll(0, 2, 5, 3); }
    void roll_y_left_hand() { roll(0, 4, 5, 1); }
    void roll_z_left_hand() { roll(1, 3, 4, 2); }

    // 6面サイコロを回転させるとき二つの面は変わらない
    // 3次元の軸に対して右回りの数列を渡すと右回りに回す
    // 例：roll_y
    // {0, 1, 5, 4} -> {0, 1, 4, 5} -> {0, 4, 1, 5} ->{4, 0, 1, 5}
    // 左回りの数列を渡すと左回りに回す
    // 例:roll_x
    // {0, 2, 5, 3} -> {3, 0, 2, 5}
    void roll(int i, int j, int k, int l) {
        swap(num[k], num[l]);
        swap(num[j], num[k]);
        swap(num[i], num[j]);
    }

    void roll(char c) {
        if (c == 'N') {
            rollN();
            return;
        }
        if (c == 'E') {
            rollE();
            return;
        }
        if (c == 'W') {
            rollW();
            return;
        }
        if (c == 'S') {
            rollS();
            return;
        }
        cerr << "回転失敗！\n";
    }

    int operator[](char c) {
        string s = "UFRLBD";
        for (size_t i = 0; i < 6; ++i)
            if (s[i] == c) return num[i];
        return -1;
    }

    bool operator==(Dice rhs) {
        if (num == rhs.num) return true;
        return false;
    }

    // 回転も含めてサイコロが同一か判定
    bool is_same(Dice other) {
        for (int i = 0; i < 6; ++i) {
            for (int j = 0; j < 4; ++j) {
                if (*this == other) {
                    return true;
                }
                other.roll_z_right_hand();
            }
            if (i % 2 == 0) {
                other.roll_x_right_hand();
            } else {
                other.roll_y_right_hand();
            }
        }
        return false;
    }
};

const pair<int, int> dxy[] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};

int main() {
    int n;
    cin >> n;

    Dice criteria = Dice(array<int, 6>{1, 2, 3, 4, 5, 6});
    Dice zero = Dice(array<int, 6>{0, 0, 0, 0, 0, 0});

    map<pair<int, int>, char> mp;
    mp[{1, 0}] = 'S';
    mp[{0, 1}] = 'E';
    mp[{-1, 0}] = 'N';
    mp[{0, -1}] = 'W';

    map<pair<int, int>, char> mp2;
    mp2[{1, 0}] = 'F';
    mp2[{0, 1}] = 'R';
    mp2[{-1, 0}] = 'B';
    mp2[{0, -1}] = 'L';

    while (n != 0) {
        int u, f;
        V<VV<Dice>> dspace(2 * n + 1, VV<Dice>(2 * n + 1, V<Dice>(n + 5, zero)));
        VV<int> height(2 * n + 1, V<int>(2 * n + 1));

        // 転がせられるなら落とせる座標を返す
        // 転がせないなら-1,-1を返す
        auto isRollable = [&](Dice& dice, int x, int y) -> pair<int, int> {
            // 4近傍との高さに2以上の差がある　かつ　転がる方向の面が4以上
            int rex = -1, rey = -1;
            int maxn = 3;
            for (auto [dx, dy] : dxy) {
                if (height[x][y] - height[x + dx][y + dy] > 1 && dice[mp2[{dx, dy}]] > maxn) {
                    rex = dx;
                    rey = dy;
                    maxn = dice[mp2[{dx, dy}]];
                }
            }
            if (maxn != 3) {
                dice.roll(mp[{rex, rey}]);
                rex = x + rex;
                rey = y + rey;
            }
            return {rex, rey};
        };

        auto fallDice = [&](auto self, Dice& dice, int x, int y) -> void {
            dspace[x][y][height[x][y]] = dice;
            height[x][y]++;
            auto [newx, newy] = isRollable(dice, x, y);
            if (newx != -1 && newy != -1) {
                height[x][y]--;
                dspace[x][y][height[x][y]] = zero;
                self(self, dice, newx, newy);
            }
        };

        for (int i = 0; i < n; i++) {
            cin >> u >> f;
            array<int, 6> num = {u, f, 0, 0, 7 - f, 7 - u};

            int k = 0;
            for (int j = 1; j <= 6; ++j)
                if (j != u && j != f && j != 7 - u && j != 7 - f) {
                    k = j;
                    break;
                }
            num[2] = k;
            num[3] = 7 - k;

            Dice dice = Dice(num);
            if (!dice.is_same(criteria)) swap(dice.num[2], dice.num[3]);

            // dice を落とす
            // 転がるか判定　→　転がるならまた落とす
            fallDice(fallDice, dice, n, n);
        }
        V<int> ans(6);
        for (int i = 0; i < 2 * n + 1; i++) {
            for (int j = 0; j < 2 * n + 1; j++) {
                if (height[i][j] > 0) {
                    ans[dspace[i][j][height[i][j] - 1].num[0] - 1]++;
                }
            }
        }
        pr.writeln(ans);

        cin >> n;
    }
}
accuracy: 1
time_ms: 830
memory_kb: 104256
final_rank: 19

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i, n) for (int i = 0; i < (n); ++i)

struct dice {
    vector<ll> n;
    dice(vector<ll> n = {1, 2, 3, 5, 4, 6}) : n(n) {}
    ll num() { return n[0]; }
    void rotate_left() { rotate(n.begin() + 1, n.begin() + 2, n.end() - 1); }
    void rotate_right() { rep(i, 3) rotate_left(); }
    void rotate_north() {
        swap(n[0], n[2]);
        swap(n[2], n[5]);
        swap(n[5], n[4]);
    }
    void rotate_east() {
        swap(n[0], n[3]);
        swap(n[3], n[5]);
        swap(n[5], n[1]);
    }
    void rotate_south() { rep(i, 3) rotate_north(); }
    void rotate_west() { rep(i, 3) rotate_east(); }
};

int main() {
    int n;
    while (cin >> n, n) {
        int a[201][201], b[201][201];
        rep(i, 201) rep(j, 201) a[i][j] = b[i][j] = 0;

        int t, f;
        rep(i, n) {
            cin >> t >> f;

            dice d;
            if (t == 2) d.rotate_west();
            if (t == 3) d.rotate_north();
            if (t == 4) d.rotate_south();
            if (t == 5) d.rotate_east();
            if (t == 6) d.rotate_north(), d.rotate_north();

            while (d.n[1] != f) d.rotate_left();

            int x = 100, y = 100;

            while (true) {
                vector<int> can;
                if (d.n[1] > 3 && a[x][y - 1] < a[x][y]) can.push_back(d.n[1]);
                if (d.n[2] > 3 && a[x + 1][y] < a[x][y]) can.push_back(d.n[2]);
                if (d.n[3] > 3 && a[x][y + 1] < a[x][y]) can.push_back(d.n[3]);
                if (d.n[4] > 3 && a[x - 1][y] < a[x][y]) can.push_back(d.n[4]);

                if (can.empty()) {
                    a[x][y]++;
                    b[x][y] = d.num();
                    break;
                }

                sort(can.begin(), can.end());
                int c = can.back();

                if (d.n[1] == c) y--, d.rotate_east();
                if (d.n[2] == c) x++, d.rotate_south();
                if (d.n[3] == c) y++, d.rotate_west();
                if (d.n[4] == c) x--, d.rotate_north();
            }
        }

        int cnt[6] = {};
        rep(i, 201) rep(j, 201) cnt[b[i][j] - 1]++;
        rep(i, 6) cout << cnt[i] << (i == 5 ? '\n' : ' ');
    }
}
accuracy: 1
time_ms: 10
memory_kb: 3680
final_rank: 2