Problem:
H: Rectangular Stamps
ICPC で良い成績を収めるには修行が欠かせない．うさぎは ICPC で勝ちたいので，今日も修行をすることにした．
今日の修行は，絵を描くことによって，創造力を高めようというものである．四角いスタンプを用いて，上手く模様を描こう．
大小さまざまなスタンプを使い，4 × 4 のマス目の紙に指定された赤・緑・青の通りの絵を完成させたい．スタンプは長方形であり，マス目にぴったり合わせて使う．スタンプの縦と横を入れ替えることはできない．
紙は最初色が塗られていない状態にある．紙にスタンプを押すと，押された部分がスタンプの色に変わり，下に隠れた色は全く見えなくなる．スタンプの色は付けるインクにより決定されるので，どのスタンプでも，好きな色を選ぶことが可能である．スタンプは紙から一部がはみ出た状態で押すことも可能であり，はみ出た部分は無視される．
1 つのスタンプを複数回使うことは可能である．同じスタンプを別の色に対して使ってもよい．スタンプを押すのはやや神経を使う作業なので，出来るだけスタンプを押す回数を少なくしたい．
Input
N
H
1
W
1
...
H
N
W
N
C
1,1
C
1,2
C
1,3
C
1,4
C
2,1
C
2,2
C
2,3
C
2,4
C
3,1
C
3,2
C
3,3
C
3,4
C
4,1
C
4,2
C
4,3
C
4,4
N
はスタンプの個数，
H
i
,
W
i
(1 ≤
i
≤
N
) はそれぞれ，
i
番目のスタンプの縦の長さ，横の長さを表す整数である．
C
i
,
j
(1 ≤
i
≤ 4，1 ≤
j
≤ 4) は，上から
i
行目，左から
j
列目のマスについて指定された絵の色を表す文字である．赤は
R
，緑は
G
，青は
B
で表される．
1 ≤
N
≤ 16，1 ≤
H
i
≤ 4，1 ≤
W
i
≤ 4 を満たす．(
H
i
,
W
i
) として同一の組は複数回現れない．
Output
絵を完成させるためにスタンプを押さなければならない最小の回数を 1 行に出力せよ．
Sample Input 1
2
4 4
1 1
RRRR
RRGR
RBRR
RRRR
Sample Output 1
3
Sample Input 2
1
2 3
RRGG
BRGG
BRRR
BRRR
Sample Output 2
5

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define all(v) (v).begin(),(v).end()
#define pb(a) push_back(a)
#define rep(i, n) for(int i=0;i<n;i++)
#define foa(e, v) for(auto&& e : v)
using ll = long long;
const ll MOD7 = 1000000007, MOD998 = 998244353, INF = (1LL << 60);
#define dout(a) cout<<fixed<<setprecision(10)<<a<<endl;

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    int n;
    cin >> n;
    vector<int> h(n), w(n);
    rep(i, n) cin >> h[i] >> w[i];
    vector<string> s(4);
    rep(i, 4) cin >> s[i];
    vector<vector<int>> col(4, vector(4, -1));
    map<char, int> mp;
    mp['R'] = 0;
    mp['B'] = 1;
    mp['G'] = 2;
    rep(i, 4) rep(j, 4) col[i][j] = mp[s[i][j]];
    int inf = 1 << 30;
    vector<int> dp(1 << 16, inf);
    dp[0] = 0;
    queue<int> que;
    que.push(0);
    while(!que.empty()) {
        int now = que.front();
        que.pop();
        rep(id, n) {
            for(int i = -h[id] + 1; i <= 3; i ++) {
                for(int j = -w[id] + 1; j <= 3; j ++) {
                    rep(c, 3) {
                        int nx = now;
                        int Mini = max(i, 0);
                        int Minj = max(j, 0);
                        int Maxi = min(i + h[id] - 1, 3);
                        int Maxj = min(j + w[id] - 1, 3);
                        for(int ii = Mini; ii <= Maxi; ii ++) {
                            for(int jj = Minj; jj <= Maxj; jj ++) {
                                int idx = (ii * 4 + jj);
                                if(col[ii][jj] == c) {
                                    if(nx >> idx & 1) {
                                        ;
                                    } else {
                                        nx ^= (1 << idx);
                                    }
                                } else {
                                    if(nx >> idx & 1) {
                                        nx ^= (1 << idx);
                                    } else {
                                        ;
                                    }
                                }
                            }
                        }
                        if(dp[nx] > dp[now] + 1) {
                            dp[nx] = dp[now] + 1;
                            que.push(nx);
                        }
                    }
                }
            }
        }
    }
    cout << dp[(1 << 16) - 1] << endl;
    return 0;
}
accuracy: 1
time_ms: 660
memory_kb: 3648
final_rank: 8

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define all(v) (v).begin(),(v).end()
#define pb(a) push_back(a)
#define rep(i, n) for(int i=0;i<n;i++)
#define foa(e, v) for(auto&& e : v)
using ll = long long;
const ll MOD7 = 1000000007, MOD998 = 998244353, INF = (1LL << 60);
#define dout(a) cout<<fixed<<setprecision(10)<<a<<endl;

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    int n;
    cin >> n;
    vector<int> h(n), w(n);
    rep(i, n) cin >> h[i] >> w[i];
    vector<string> s(4);
    rep(i, 4) cin >> s[i];
    vector<vector<int>> col(4, vector(4, -1));
    map<char, int> mp;
    mp['R'] = 0;
    mp['B'] = 1;
    mp['G'] = 2;
    rep(i, 4) rep(j, 4) col[i][j] = mp[s[i][j]];
    int inf = 1 << 30;
    vector<int> dp(1 << 16, inf);
    dp[0] = 0;
    queue<int> que;
    que.push(0);
    while(!que.empty()) {
        int now = que.front();
        que.pop();
        rep(id, n) {
            for(int i = -h[id] + 1; i <= 3; i ++) {
                for(int j = -w[id] + 1; j <= 3; j ++) {
                    rep(c, 3) {
                        int nx = now;
                        int Mini = max(i, 0);
                        int Minj = max(j, 0);
                        int Maxi = min(i + h[id] - 1, 3);
                        int Maxj = min(j + w[id] - 1, 3);
                        for(int ii = Mini; ii <= Maxi; ii ++) {
                            for(int jj = Minj; jj <= Maxj; jj ++) {
                                int idx = (ii * 4 + jj);
                                if(col[ii][jj] == c) {
                                    if(nx >> idx & 1) {
                                        ;
                                    } else {
                                        nx |= (1 << idx);
                                    }
                                } else {
                                    if(nx >> idx & 1) {
                                        nx |= (1 << idx);
                                    } else {
                                        ;
                                    }
                                }
                            }
                        }
                        if(dp[nx] > dp[now] + 1) {
                            dp[nx] = dp[now] + 1;
                            que.push(nx);
                        }
                    }
                }
            }
        }
    }
    cout << dp[(1 << 16) - 1] << endl;
    return 0;
}
accuracy: 0.03278688524590164
time_ms: 100
memory_kb: 3316
final_rank: 16

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
 */

struct EnumCliques{
    const int n;
    int m;
    vector<vector<int>> g;
    vector<int> deg;
    EnumCliques(int _n):n(_n),m(0),g(n,vector<int>(n)),deg(n){}
    void add_edge(int u,int v){
        g[u][v]=g[v][u]=1;
        deg[u]++; deg[v]++;
        m++;
    }
    vector<vector<int>> run(){
        int L=sqrt(m);
        vector<vector<int>> res;
        auto process=[&](vector<int>& vs,bool fix=true)->void{
            vector<int> nbhd(vs.size());
            rep(i,0,vs.size())rep(j,0,vs.size())if(i!=j){
                nbhd[i]|=(!g[vs[i]][vs[j]])<<j;
            }
            rep(mask,1,1<<vs.size()){
                if(fix and (mask&1)==0)continue;;
                bool check=1;
                rep(i,0,vs.size())if(mask>>i&1){
                    if(mask&nbhd[i]){
                        check=0;
                        break;
                    }
                }
                if(check){
                    vector<int> add;
                    rep(i,0,vs.size())if(mask>>i&1){
                        add.push_back(vs[i]);
                    }
                    res.push_back(add);
                }
            }
        };

        vector<int> used(n);
        queue<int> que;
        rep(v,0,n)if(deg[v]<L){
            que.push(v);
            used[v]=1;
        }
        while(!que.empty()){
            int v=que.front();
            que.pop();
            vector<int> vs;
            vs.push_back(v);
            rep(u,0,n)if(g[v][u])vs.push_back(u);
            process(vs);
            rep(u,0,n)if(g[v][u]){
                g[v][u]=g[u][v]=0;
                deg[u]--;
                if(!used[u] and deg[u]<L){
                    que.push(u);
                    used[u]=1;
                }
            }
        }
        vector<int> vs;
        rep(v,0,n)if(!used[v])vs.push_back(v);
        process(vs,false);
        return res;
    }
};

/**
 * @brief Enumerate Cliques
 */

int main() {
    int N;
    cin >> N;
    vector<int> A(N), B(N);
    rep(i,0,N) cin >> A[i] >> B[i];
    char C[4][4];
    rep(i,0,4) rep(j,0,4) cin >> C[i][j];
    string S = "RGB";
    vector D(N, vector(3, vector(7, vector<int>(7,0))));
    vector X(N, vector(3, vector(7, vector<int>(7,0))));
    rep(i,0,N) {
        rep(j,0,3) {
            char T = S[j];
            rep(k,-3,4) {
                rep(l,-3,4) {
                    rep(a,0,A[i]) {
                        rep(b,0,B[i]) {
                            int x = a+k, y = b+l;
                            if (0<=x&&x<4&&0<=y&&y<4) {
                                if (C[x][y] != T) D[i][j][k+3][l+3] |= (1<<(x*4+y));
                                X[i][j][k+3][l+3] |= (1<<(x*4+y));
                            }
                        }
                    }
                }
            }
        }
    }
    vector<int> DP(1<<16,inf);
    DP[0] = 0;
    rep(i,0,1<<16) {
        if (DP[i] == inf) continue;
        bool BB[4][4] = {};
        rep(j,0,16) {
            if (i & (1<<j)) BB[j/4][j%4] = true;
        }
        rep(j,0,N) {
            rep(a,0,3) {
                char T = S[a];
                rep(b,0,7) {
                    rep(c,0,7) {
                        if ((i & D[j][a][b][c]) == D[j][a][b][c]) chmin(DP[i|X[j][a][b][c]],DP[i]+1);
                    }
                }
            }
        }
    }
    cout << DP[(1<<16)-1] << endl;
}
accuracy: 1
time_ms: 210
memory_kb: 3548
final_rank: 2

code_snippet: #include <bits/stdc++.h>
using namespace std;
#if __has_include(<atcoder/all>)
#include <atcoder/all>
using namespace atcoder;
template<int mod>istream &operator>>(istream &is,static_modint<mod> &a){long long b;is>>b;a=b;return is;}
istream &operator>>(istream &is,modint &a){long long b;cin>>b;a=b;return is;}
#endif
#ifdef LOCAL
#include "debug.h"
#else
#define debug(...) static_cast<void>(0)
#define debugg(...) static_cast<void>(0)
#define esper(...) static_cast<void>(0)
template<typename T1,typename T2>ostream &operator<<(ostream &os,const pair<T1,T2>&p){os<<p.first<<' '<<p.second;return os;}
#endif
using ll=long long;
using ull=unsigned long long;
using P=pair<ll,ll>;
template<typename T>using minque=priority_queue<T,vector<T>,greater<T>>;
template<typename T>bool chmax(T &a,const T &b){return (a<b?(a=b,true):false);}
template<typename T>bool chmin(T &a,const T &b){return (a>b?(a=b,true):false);}
template<typename T1,typename T2>istream &operator>>(istream &is,pair<T1,T2>&p){is>>p.first>>p.second;return is;}
template<typename T>istream &operator>>(istream &is,vector<T> &a){for(auto &i:a)is>>i;return is;}
template<typename T1,typename T2>void operator++(pair<T1,T2>&a,int n){a.first++,a.second++;}
template<typename T1,typename T2>void operator--(pair<T1,T2>&a,int n){a.first--,a.second--;}
template<typename T>void operator++(vector<T>&a,int n){for(auto &i:a)i++;}
template<typename T>void operator--(vector<T>&a,int n){for(auto &i:a)i--;}
#define reps(i,a,n) for(int i=(a);i<int(n);i++)
#define rep(i,n) reps(i,0,n)
#define all(x) x.begin(),x.end()
#define pcnt(x) __builtin_popcountll(x)
#define fin(x) return cout<<x<<'\n',static_cast<void>(0)
ll myceil(ll a,ll b){return (a+b-1)/b;}
template<typename T,size_t n,size_t id=0>
auto vec(const int (&d)[n],const T &init=T()){
  if constexpr (id<n)return vector(d[id],vec<T,n,id+1>(d,init));
  else return init;
}
void SOLVE();
int main(){
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  cout<<fixed<<setprecision(16);
  #ifdef LOCAL
  clock_t start=clock();
  #endif
  int testcase=1;
  //cin>>testcase;
  for(int i=0;i<testcase;i++){
    SOLVE();
  }
  #ifdef LOCAL
  cerr<<"time:";
  cerr<<(clock()-start)/1000;
  cerr<<"ms\n";
  #endif
}
void SOLVE(){
  int n;
  cin>>n;
  vector<pair<int,int>>a(n);
  cin>>a;
  vector<vector<int>>b(4,vector<int>(4));
  rep(i,4)rep(j,4){
    char c;
    cin>>c;
    if(c=='R')b[i][j]=0;
    else if(c=='G')b[i][j]=1;
    else b[i][j]=2;
  }
  vector<int>dp(1<<16,0);
  for(int i=(1<<16)-1;i--;){
    dp[i]=1e9;
    rep(j,n){
      reps(dx,-a[j].first+1,4)reps(dy,-a[j].second+1,4){
        int nx=i;
        int st=-1;
        rep(x,a[j].first)rep(y,a[j].second){
          if(x+dx>=0&&y+dy>=0&&x+dx<4&&y+dy<4){
            if(i>>((x+dx)*4+y+dy)&1)continue;
            if(st==-1)st=b[x+dx][y+dy];
            else if(st!=b[x+dx][y+dy])st=-2;
            nx|=1<<((x+dx)*4+y+dy);
          }
        }
        if(st!=-2)chmin(dp[i],dp[nx]+1);
      }
    }
  }
  cout<<dp[0]<<endl;
}
accuracy: 1
time_ms: 780
memory_kb: 3476
final_rank: 9

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

int main() {
    std::cin.tie(nullptr)->sync_with_stdio(false);

    int N;
    std::cin >> N;
    std::vector<int> H(N), W(N);
    for (int i{} ; i < N ; i++) {
        std::cin >> H[i] >> W[i];
    }
    char input[4][4];
    int C[4][4];
    for (int i{} ; i < 4 ; i++) {
        for (int j{} ; j < 4 ; j++) {
            std::cin >> input[i][j];
            if (input[i][j] == 'R') C[i][j] = 0;
            else if (input[i][j] == 'G') C[i][j] = 1;
            else if (input[i][j] == 'B') C[i][j] = 2;
            else assert(false);
        }
    }
    std::vector<int> dp((1 << 16), -1);
    auto in{[&](int x, int y) -> bool {
        return 0 <= x and x < 4 and 0 <= y and y < 4;
    }};
    auto f{[&](int x, int y) -> int {
        return x * 4 + y;
    }};
    const int INF{(int)1e9};
    auto rec{[&](auto rec, int bit) -> int {
        if (dp[bit] != -1) return dp[bit];
        if (bit == (1 << 16) - 1) return dp[bit] = 0;
        dp[bit] = INF;
        for (int i{} ; i < N ; i++) {
            for (int u{-H[i] + 1} ; u < 4 ; u++) {
                for (int l{-W[i] + 1} ; l < 4 ; l++) {
                    int app{};
                    int mask{bit};
                    for (int x{std::max(u, 0)} ; x < std::min(4, u + H[i]) ; x++) {
                        for (int y{std::max(l, 0)} ; y < std::min(4, l + W[i]) ; y++) {
                            int val{f(x, y)};
                            if (bit & (1 << val)) continue;
                            app |= (1 << C[x][y]);
                            mask |= (1 << val);
                        }
                    }
                    if (__builtin_popcount(app) == 1) {
                        dp[bit] = std::min(dp[bit], rec(rec, mask) + 1);
                    }
                }
            }
        }
        return dp[bit];
    }};
    std::cout << rec(rec, 0) << '\n';
}
accuracy: 1
time_ms: 460
memory_kb: 3464
final_rank: 3

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;
    }
};

using f64 = long double;

} // namespace macro

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

int main() {
    int N = in();
    vector<int> H(N), W(N);
    for(int i : rep(N)) H[i] = in(), W[i] = in();
    vector<string> C = in(4);
    vector<int> dist(1 << 16, -1);
    dist[0] = 0;
    queue<int> q;
    q.push(0);
    while(not q.empty()) {
        int u = q.front(); q.pop();
        for(int i = 0; i < N; i++) {
            for(int dx = 1 - H[i]; dx <= +3; dx++) {
                for(int dy = 1 - W[i]; dy <= +3; dy++) {
                    for(char c : {'R', 'G', 'B'}) {
                        int v = u;
                        for(int x = max(0, dx); x < min(4, H[i] + dx); x++) {
                            for(int y = max(0, dy); y < min(4, W[i] + dy); y++) {
                                int p = 1 << (x * 4 + y);
                                if(C[x][y] == c) {
                                    v |=  p;
                                } else {
                                    v &= ~p;
                                }
                            }
                        }
                        if(dist[v] == -1) {
                            dist[v] = dist[u] + 1;
                            q.push(v);
                        }
                    }
                }
            }
        }
    }
    print(dist[(1 << 16) - 1]);
}
accuracy: 1
time_ms: 1210
memory_kb: 3628
final_rank: 11

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;
    }
};

using f64 = long double;

} // namespace macro

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

int main() {
    int N = in();
    vector<int> H(N), W(N);
    for(int i : rep(N)) H[i] = in(), W[i] = in();
    vector<string> C = in(4);
    vector<int> dist(1 << 16, -1);
    dist[0] = 0;
    queue<int> q;
    q.push(0);
    while(not q.empty()) {
        int u = q.front(); q.pop();
        if(u == (1 << 16) - 1) break;
        for(int i = 0; i < N; i++) {
            for(int dx = 1 - H[i]; dx <= +3; dx++) {
                for(int dy = 1 - W[i]; dy <= +3; dy++) {
                    for(char c : {'R', 'G', 'B'}) {
                        int v = u;
                        for(int x = max(0, dx); x < min(4, H[i] + dx); x++) {
                            for(int y = max(0, dy); y < min(4, W[i] + dy); y++) {
                                int p = 1 << (x * 4 + y);
                                if(C[x][y] == c) {
                                    v |=  p;
                                } else {
                                    v &= ~p;
                                }
                            }
                        }
                        if(dist[v] == -1) {
                            dist[v] = dist[u] + 1;
                            q.push(v);
                        }
                    }
                }
            }
        }
    }
    print(dist[(1 << 16) - 1]);
}
accuracy: 1
time_ms: 550
memory_kb: 3632
final_rank: 7

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

template<class T>
bool chmax(T &a, const T &b) {if (a < b) {a = b; return 1;} return 0;}

template<class T>
bool chmin(T &a, const T &b) {if (a > b) {a = b; return 1;} return 0;}

using ll = long long;
using ld = long double;

bool is_end = false;

int dp[1<<16];

void init()
{
	for (int i = 0; i < (1<<16); ++i)
	{
		dp[i] = 1e9;
	}
	return;
}

void calc()
{
	int N; cin >> N;
	vector<int> H(N), W(N);
	for (int i = 0; i < N; ++i) {cin >> H[i] >> W[i];}
	
	int C[4][4];
	for (int i = 0; i < 4; ++i)
	{
		for (int j = 0; j < 4; ++j)
		{
			char c; cin >> c;
			if (c == 'R') C[i][j] = 0;
			if (c == 'G') C[i][j] = 1;
			if (c == 'B') C[i][j] = 2;
		}
	}
	
	vector<int> cbit(3, 0);
	for (int i = 0; i < 4; ++i)
	{
		for (int j = 0; j < 4; ++j)
		{
			int c = C[i][j];
			cbit[c] ^= (1<<(i*4+j));
		}
	}
	
	init();
	
	dp[0] = 0;
	for (int i = 1; i <= 16; ++i)
	{
		for (int n = 0; n < N; ++n)
		{
			for (int x1 = 0; x1 < 3 + H[n]; ++x1)
			{
				for (int y1 = 0; y1 < 3 + W[n]; ++y1)
				{
					int x0 = max(x1 - H[n] + 1, 0);
					int y0 = max(y1 - W[n] + 1, 0);
					int mask = 0;
					for (int x = x0; x <= min(x1, 3); ++x)
					{
						for (int y = y0; y <= min(y1, 3); ++y)
						{
							mask ^= (1<<(4*x+y));
						}
					}
					
					
					for (int c = 0; c < 3; ++c)
					{
						for (int bit = 0; bit < (1<<16); ++bit)
						{
							if (dp[bit] > 100) {continue;}
							
							int nbit = bit & (~mask);
							nbit |= (mask & cbit[c]);
							chmin(dp[nbit], dp[bit] + 1);
						}
					}
				}
			}
		}
	}
	
	cout << dp[(1<<16)-1] << endl;
		
	return;
}

int main()
{
	calc();
	
	return 0;
}
accuracy: 1
time_ms: 1930
memory_kb: 3720
final_rank: 15

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

typedef long long ll;
typedef __int128_t lll;
typedef long double ld;
typedef pair<ll, ll> pl;
typedef tuple<ll, ll, ll> tt;
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 vector<tt> vt;
typedef vector<string> vs;

const ll INF = 1000000010;
const ll INFL = INF * INF;
const ld epsilon = 1e-10;

#define ovl(a, b, c, d, e, ...) e
#define pb push_back
#define eb emplace_back
#define MP make_pair
#define DEBUG(...) DEBUG_(#__VA_ARGS__, __VA_ARGS__)
#define REP1(i, r) for (int i = 0; i < (r); i++)
#define REP2(i, l, r) for (int i = (l); i < (r); i++)
#define REP3(i, l, r, d) for (int i = (l); i < (r); i += (d))
#define REP(...) ovl(__VA_ARGS__, REP3, REP2, REP1)(__VA_ARGS__)
#define RREP1(i, r) for (int i = (r)-1; i >= 0; i--)
#define RREP2(i, l, r) for (int i = (r)-1; i >= (l); i--)
#define RREP3(i, l, r, d) for (int i = (r)-1; i >= (l); i -= (d))
#define RREP(...) ovl(__VA_ARGS__, RREP3, RREP2, RREP1)(__VA_ARGS__)
#define EACH1(x, a) for (auto &x : 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(...) ovl(__VA_ARGS__, EACH3, EACH2, EACH1)(__VA_ARGS__)
#define ALL(x) begin(x), end(x)
#define RALL(x) (x).rbegin(), (x).rend()
#define sz(x) (ll) x.size()
#define LB(a, x) (lower_bound(ALL(a), x) - a.begin())
#define UB(a, x) (upper_bound(ALL(a), x) - a.begin())
#define FLG(x, i) (((x) >> (i)) & 1)
#define CNTBIT(x) __builtin_popcountll(x)
#define IN(x, a, b) ((a) <= (x) && (x) < (b))
#define int ll

template <class T>
void DEBUG_(string_view name, const T &a) {
    cerr << name << ": " << a << endl;
}

template <class T>
void DEBUG_(string_view name, const vector<T> &a) {
    cerr << name << ": ";
    REP(i, sz(a)) cerr << a[i] << " ";
    cerr << endl;
}

template <class T, class U>
bool chmax(T &x, const U &y) {
    return x < y ? x = y, 1 : 0;
}
template <class T, class U>
bool chmin(T &x, const U &y) {
    return x > y ? x = y, 1 : 0;
}

//-----------------------------------------------------------------------

int N;
vp HWs;
vvl grid;

map<int, int> memo;
int dp(const int bit = 0) {
    // DEBUG(bit);
    if (bit == (1 << 16) - 1) {
        return 0;
    }
    if (memo.count(bit)) {
        return memo[bit];
    }

    int ans = INF;
    EACH(h, w, HWs) {
        REP(h1, 4) {
            REP2(h2, h1, 4) {
                if (h2 - h1 + 1 > h) continue;
                if (1 <= h1 && h2 <= 2 && h2 - h1 + 1 != h) continue;
                REP(w1, 4) {
                    REP2(w2, w1, 4) {
                        if (w2 - w1 + 1 > w) continue;
                        if (1 <= w1 && w2 <= 2 && w2 - w1 + 1 != w) continue;
                        int seen = -1;
                        int nbit = bit;
                        REP(hh, h1, h2 + 1) {
                            REP(ww, w1, w2 + 1) {
                                if (nbit & (1 << (4 * hh + ww))) continue;
                                nbit |= (1 << (4 * hh + ww));
                                if (seen == -1) {
                                    seen = grid[hh][ww];
                                } else if (seen != grid[hh][ww]) {
                                    seen = -INFL;
                                    break;
                                }
                            }
                        }
                        if (seen == -INFL) continue;
                        if (bit == nbit) continue;
                        chmin(ans, dp(nbit) + 1);
                    }
                }
            }
        }
    }

    // DEBUG(bit);
    // DEBUG(ans);

    return memo[bit] = ans;
}

void solve() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout << fixed << setprecision(15);

    int N;
    cin >> N;
    HWs.resize(N);
    REP(i, N) {
        int H, W;
        cin >> H >> W;
        HWs[i] = {H, W};
    }
    grid.resize(4, vl(4));
    REP(h, 4) {
        string S;
        cin >> S;
        REP(w, 4) {
            if (S[w] == 'R') grid[h][w] = 1;
            if (S[w] == 'G') grid[h][w] = 2;
            if (S[w] == 'B') grid[h][w] = 3;
        }
    }

    cout << dp() << endl;

    // EACH(key, val, memo) {
    //     if (val != 0) {
    //         DEBUG(key);
    //         DEBUG(val);
    //     }
    // }
}

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

    while (T--) solve();

    // random_test();

    return 0;
}
accuracy: 1
time_ms: 1680
memory_kb: 7564
final_rank: 14

code_snippet: #include<bits/stdc++.h>
#define int ll
#define rep(i, N) for(int i = 0; i < (int)(N); ++i)
#define rep1(i, N) for(int i = 1; i <= (int)(N); ++i)
#define per(i, N) for(int i = (N)-1; i >= 0; --i)
#define all(v) (v).begin(), (v).end()
#define rall(v) (v).rbegin(), (v).rend()
#define bit(n, k) ((n) >> (k))
#define pcnt(n) (__builtin_popcount(n))
#define TakAo(ans) ans ? cout << "Takahashi\n" : cout << "Aoki\n"
#define YesNo(ans) ans ? cout << "Yes\n" : cout << "No\n"
#define endl '\n'
#define fi first
#define se second
#define mkpr make_pair
#define mktpl make_tuple
#define eb emplace_back

using namespace std;
using ll = int64_t;
using ull = uint64_t;
using ld = long double;
using point = struct{ ll x, y; };
using pointld = struct{ ld x, y; };
using State = string::const_iterator;
template<class T> using max_heap = priority_queue<T>;
template<class T> using min_heap = priority_queue<T, vector<T>, greater<T>>;
template<class T> using vec = vector<T>;
template<class T> using vvec = vec<vec<T>>;
template<class T> using vvvec = vec<vvec<T>>;
template<class T> using vvvvec = vvec<vvec<T>>;

constexpr ld EPS = 1e-10;
constexpr int INF = 1001001001;
constexpr ll LINF = 1001001001001001001ll;
constexpr ll MOD = (0) ? 998244353 : 1e9+7;
constexpr int NIL = -1;
constexpr int pm[2] = {1, -1};
constexpr int dy[4] = {0, 1, 0, -1};
constexpr int dx[4] = {1, 0, -1, 0};

ll cel(ll a, ll b){ return (a + b - 1) / b;}
ll Gcd(ll a, ll b){ return b ? Gcd(b, a % b) : abs(a);}
template<class T> T powi(T x, ll exp){
    return exp > 0 ? (exp & 1 ? x : 1) * powi(x * x, exp >> 1) : x / x;
}
ll modpow(ll x, ll exp, ll mod){
    x %= mod;
    return exp > 0 ? (exp & 1 ? x : 1) * modpow(x * x, exp >> 1, mod) % mod : 1;
}
template<class T> bool chmin(T &a, T b){ return a > b ? (a = b, true) : 0;}
template<class T> bool chmax(T &a, T b){ return a < b ? (a = b, true) : 0;}

using Pair = pair<ll, ll>;
using Tpl = tuple<int, int, int>;

void Main(){
    int N; cin >> N;
    vec<int> H(N), W(N);
    rep(i, N) cin >> H[i] >> W[i];

    vvec<char> G(4, vec<char>(4));
    rep(i, 4)rep(j, 4) cin >> G[i][j];

    const int goal = (1 << 16) - 1;
    queue<Pair> que;
    vec<bool> used(1 << 16, 0);
    que.push(mkpr(0, 0));
    used[0] = 1;
    char col[3] = {'R', 'G', 'B'};

    while(!que.empty()){
        Pair p = que.front();
        que.pop();
        int num = p.fi, cst = p.se;
        
        rep(i, N){
            for(int j = -H[i] + 1; j < 4; j++){
                for(int k = -W[i] + 1; k < 4; k++){
                    for(int l = 0; l < 3; l++){
                        int tmp = num;

                        for(int a = max(j, ll(0)); a < min(j + H[i], ll(4)); a++){
                            for(int b = max(k, ll(0)); b < min(k + W[i], ll(4)); b++){
                                if(col[l] == G[a][b]){
                                    tmp |= (1 << (4 * a + b));
                                }
                                else{
                                    //cout << bitset<16>(tmp) << endl;
                                    tmp &= ~(1 << (4 * a + b));
                                    //cout << bitset<16>(tmp) << endl;
                                }
                            }
                        }

                        if(tmp == goal){
                            cout << cst + 1 << endl;
                            return;
                        }
                        else{
                            if(!used[tmp]){
                                used[tmp] = 1;
                                que.push(mkpr(tmp, cst + 1));
                            }
                        }
                    }
                }
            }
        }
    }

    cout << -1 << endl;
}
 
signed main(){
    cin.tie(nullptr);
    ios_base::sync_with_stdio(false);
    cout << fixed << setprecision(10);
    Main();
    return 0;
}
accuracy: 1
time_ms: 540
memory_kb: 3964
final_rank: 6

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vi = vector<int>;
using pii = pair<int, int>;
#define rep(i, x)    for(int i = 0; i < (x); i++)
#define rng(i, l, r) for(int i = (l); i < (r); i++)
#define sz(x)        (int)(x).size()
#define all(v)       (v).begin(), (v).end()

int ctoi(char c) { return c == 'R' ? 2 : c == 'G'; }
const int inf = 1 << 30;
int main() {
	int n;
	cin >> n;
	vector<pii> hw;
	rep(i, n) {
		int u, v;
		cin >> u >> v;
		hw.emplace_back(u, v);
	}
	vector<string> s(4);
	for(auto &v : s) cin >> v;
	int N = 1 << 16;
	vector<vi> g(N);
	rep(bit, N) {
		set<int> st;
	}
	vi dist(N, inf);
	dist[0] = 0;
	queue<int> que;
	que.push(0);
	while(!que.empty()) {
		auto bit = que.front();
		que.pop();
		rep(i, n) {
			auto [h, w] = hw[i];
			rng(x, -h, 4) {
				rng(y, -w, 4) {
					rep(c, 3) {
						int to = bit;
						rng(nx, max(0, x), min(4, x + h)) {
							rng(ny, max(0, y), min(4, y + w)) {
								if(nx >= 0 and nx < 4 and ny >= 0 and ny < 4) {
									int id = nx * 4 + ny;
									int col = ctoi(s[nx][ny]);
									if(c == col) {
										to |= 1 << id;
									} else {
										if(to >> id & 1) to ^= 1 << id;
									}
								}
							}
						}
						if(dist[to] != inf) continue;
						dist[to] = dist[bit] + 1;
						que.push(to);
					}
				}
			}
		}
	}
	cout << dist.back() << endl;
}
accuracy: 1
time_ms: 1220
memory_kb: 4972
final_rank: 12

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vi = vector<int>;
using pii = pair<int, int>;
#define rep(i, x)    for(int i = 0; i < (x); i++)
#define rng(i, l, r) for(int i = (l); i < (r); i++)
#define sz(x)        (int)(x).size()
#define all(v)       (v).begin(), (v).end()

int ctoi(char c) { return c == 'R' ? 2 : c == 'G'; }
const int inf = 1 << 30;
int main() {
	int n;
	cin >> n;
	vector<pii> hw;
	rep(i, n) {
		int u, v;
		cin >> u >> v;
		hw.emplace_back(u, v);
	}
	vector<string> s(4);
	for(auto &v : s) cin >> v;
	int N = 1 << 16;
	vector<vi> g(N);
	rep(bit, N) {
		set<int> st;
	}
	vi dist(N, inf);
	dist[0] = 0;
	queue<int> que;
	que.push(0);
	while(!que.empty()) {
		auto bit = que.front();
		que.pop();
		rep(i, n) {
			auto [h, w] = hw[i];
			rng(x, -h, 4) {
				rng(y, -w, 4) {
					rep(c, 3) {
						int to = bit;
						rep(dx, h) {
							rep(dy, w) {
								int nx = x + dx, ny = y + dy;
								if(nx >= 0 and nx < 4 and ny >= 0 and ny < 4) {
									int id = nx * 4 + ny;
									int col = ctoi(s[nx][ny]);
									if(c == col) {
										to |= 1 << id;
									} else {
										if(1 >> id & 1) to ^= 1 << id;
									}
								}
							}
						}
						if(dist[to] != inf) continue;
						dist[to] = dist[bit] + 1;
						que.push(to);
					}
				}
			}
		}
	}
	cout << dist.back() << endl;
}
accuracy: 0.03278688524590164
time_ms: 250
memory_kb: 4924
final_rank: 18

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vi = vector<int>;
using pii = pair<int, int>;
#define rep(i, x)    for(int i = 0; i < (x); i++)
#define rng(i, l, r) for(int i = (l); i < (r); i++)
#define sz(x)        (int)(x).size()
#define all(v)       (v).begin(), (v).end()

int ctoi(char c) { return c == 'R' ? 2 : c == 'G'; }
const int inf = 1 << 30;
int main() {
	int n;
	cin >> n;
	vector<pii> hw;
	set<pii> st;
	rep(i, n) {
		int u, v;
		cin >> u >> v;
		rng(x, 1, u + 1) {
			rng(y, 1, v + 1) {
				st.insert({x, y});
			}
		}
	}
	for(auto &p : st) hw.push_back(p);
	n = sz(hw);
	vector<string> s(4);
	for(auto &v : s) cin >> v;
	int N = 1 << 16;
	vector<vi> g(N);
	rep(bit, 1 << 16) {
		rep(i, n) {
			auto [h, w] = hw[i];
			rep(x, 4) {
				rep(y, 4) {
					if(x + h > 4 or y + w > 4) continue;
					vector<vi> ids(3), bads(3);
					rep(dx, h) {
						rep(dy, w) {
							int nx = x + dx, ny = y + dy;
							int id = nx * 4 + ny;
							int col = ctoi(s[nx][ny]);
							rep(j, 3) {
								if(j == col)
									ids[j].push_back(id);
								else
									bads[j].push_back(id);
							}
						}
					}
					rep(j, 3) {
						if(ids[j].empty()) continue;
						int nb = bit;
						for(auto v : ids[j]) {
							if(!(nb >> v & 1)) nb |= 1 << v;
						}
						for(auto v : bads[j]) {
							if(nb >> v & 1) nb ^= 1 << v;
						}
						g[bit].push_back(nb);
					}
				}
			}
		}
	}
	vi dist(N, inf);
	dist[0] = 0;
	queue<int> que;
	que.push(0);
	while(!que.empty()) {
		auto v = que.front();
		que.pop();
		for(auto to : g[v]) {
			if(dist[to] != inf) continue;
			dist[to] = dist[v] + 1;
			que.push(to);
		}
	}
	cout << dist.back() << endl;
}
accuracy: 0.03278688524590164
time_ms: 1540
memory_kb: 71352
final_rank: 19

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vi = vector<int>;
using pii = pair<int, int>;
#define rep(i, x)    for(int i = 0; i < (x); i++)
#define rng(i, l, r) for(int i = (l); i < (r); i++)
#define sz(x)        (int)(x).size()
#define all(v)       (v).begin(), (v).end()

int ctoi(char c) { return c == 'R' ? 2 : c == 'G'; }
const int inf = 1 << 30;
int main() {
	int n;
	cin >> n;
	vector<pii> hw;
	rep(i, n) {
		int u, v;
		cin >> u >> v;
		hw.emplace_back(u, v);
	}
	vector<string> s(4);
	for(auto &v : s) cin >> v;
	int N = 1 << 16;
	vector<vi> g(N);
	rep(bit, 1 << 16) {
		rep(i, n) {
			auto [h, w] = hw[i];
			rep(x, 4) {
				rep(y, 4) {
					if(x + h > 4 or y + w > 4) continue;
					set<char> st;
					vector<vi> ids(3), bads(3);
					rep(dx, h) {
						rep(dy, w) {
							int nx = x + dx, ny = y + dy;
							int id = nx * 4 + ny;
							int col = ctoi(s[nx][ny]);
							rep(j, 3) {
								if(j == col)
									ids[j].push_back(id);
								else
									bads[j].push_back(id);
							}
						}
					}
					rep(j, 3) {
						if(ids[j].empty()) continue;
						int nb = bit;
						for(auto v : ids[j]) {
							if(!(nb >> v & 1)) nb |= 1 << v;
						}
						for(auto v : bads[j]) {
							if(nb >> v & 1) nb ^= 1 << v;
						}
						g[bit].push_back(nb);
					}
				}
			}
		}
	}
	vi dist(N, inf);
	dist[0] = 0;
	queue<int> que;
	que.push(0);
	while(!que.empty()) {
		auto v = que.front();
		que.pop();
		for(auto to : g[v]) {
			if(dist[to] != inf) continue;
			dist[to] = dist[v] + 1;
			que.push(to);
		}
	}
	cout << dist.back() << endl;
}
accuracy: 0.01639344262295082
time_ms: 130
memory_kb: 13892
final_rank: 20

code_snippet: #define _GLIBCXX_DEBUG
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vi = vector<int>;
using pii = pair<int, int>;
#define rep(i, x)    for(int i = 0; i < (x); i++)
#define rng(i, l, r) for(int i = (l); i < (r); i++)
#define sz(x)        (int)(x).size()
#define all(v)       (v).begin(), (v).end()

int ctoi(char c) { return c == 'R' ? 2 : c == 'G'; }

int main() {
	int n;
	cin >> n;
	vector<pii> hw;
	rep(i, n) {
		int u, v;
		cin >> u >> v;
		hw.emplace_back(u, v);
	}
	vector<string> s(4);
	for(auto &v : s) cin >> v;
	vector<int> res(1 << 16, 1 << 30);
	auto dfs = [&](auto dfs, int bit) -> int {
		if(bit == 0) return 0;
		if(res[bit] != (1 << 30)) return res[bit];
		int ans = 1 << 30;
		rep(i, n) {
			auto [h, w] = hw[i];
			rep(x, 4) {
				rep(y, 4) {
					if(x + h > 4 or y + w > 4) continue;
					set<char> st;
					vector<vi> ids(3);
					rep(dx, h) {
						rep(dy, w) {
							int nx = x + dx, ny = y + dy;
							int id = nx * 4 + ny;
							if(!(bit >> id & 1)) continue;
							ids[ctoi(s[nx][ny])].push_back(id);
						}
					}
					rep(j, 3) {
						if(ids[j].empty()) continue;
						int nb = bit;
						for(auto v : ids[j]) nb ^= (1 << v);
						ans = min(ans, dfs(dfs, nb) + 1);
					}
				}
			}
		}
		return res[bit] = ans;
	};
	dfs(dfs, (1 << 16) - 1);
	cout << res.back() << endl;
}
accuracy: 0.03278688524590164
time_ms: 120
memory_kb: 3372
final_rank: 17

code_snippet: #include <stdio.h>
#include <queue>
using namespace std;

char targ[8][8], state[4][4], tstate[4][4], vis[65536];
int stamp[16][2], dist[65536];
queue<int> q;

int main(void) {
    int n, s, t;
    scanf("%d", &n);
    for (int i = 0; i < n; i++) {
        scanf("%d %d", &stamp[i][0], &stamp[i][1]);
    }
    for (int i = 0; i < 4; i++) {
        scanf("%s", targ[i]);
        for (int j = 0; j < 4; j++) {
            if (targ[i][j] == 'R') targ[i][j] = 1;
            else if (targ[i][j] == 'G') targ[i][j] = 2;
            else targ[i][j] = 3;
        }
    }
    vis[0] = 1;
    q.push(0);
    while (q.size()) {
        s = q.front();
        q.pop();
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) state[i][j] = ((s >> (i * 4 + j)) & 1);
        }
        for (int i = 0; i < n; i++) {
            for (int j = 1; j <= 3; j++) {
                for (int x = -stamp[i][0] + 1; x <= 3; x++) {
                    for (int y = -stamp[i][1] + 1; y <= 3; y++) {
                        for (int xx = 0; xx < 4; xx++) {
                            for (int yy = 0; yy < 4; yy++) tstate[xx][yy] = state[xx][yy];
                        }
                        for (int xx = x; xx < x + stamp[i][0]; xx++) {
                            if (xx < 0 || xx >= 4) continue;
                            for (int yy = y; yy < y + stamp[i][1]; yy++) {
                                if (yy < 0 || yy >= 4) continue;
                                if (targ[xx][yy] == j) tstate[xx][yy] = 1;
                                else tstate[xx][yy] = 0;
                            }
                        }
                        t = 0;
                        for (int xx = 0; xx < 4; xx++) {
                            for (int yy = 0; yy < 4; yy++) t += (1 << (xx * 4 + yy)) * tstate[xx][yy];
                        }
                        if (!vis[t]) {
                            vis[t] = 1;
                            q.push(t);
                            dist[t] = dist[s] + 1;
                        }
                    }
                }
            }
        }
    }

    printf("%d\n", dist[65535]);
    return 0;
}
accuracy: 1
time_ms: 1790
memory_kb: 3420
final_rank: 13

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

vector<pair<int,int>> X;
vector<vector<char>> A(4,vector<char>(4));
int memo[65536];

int dfs(int n,int nw){
  //cout << n << " " << nw << endl;
  //if(nw == 65471 )cout << n << endl;
  if(nw == 0){
    return memo[nw] = 0;
  }else if(memo[nw]){
    return memo[nw];
  }
   int ret = -1;
  for(int i = 0; X.size() > i; i++){
    for(int j = -X[i].first+1; 4 > j; j++){
      for(int k = -X[i].second+1; 4 > k; k++){
        int nwc = -1;
        bool ok = true;
        int mns = 0;
        for(int l = 0; X[i].first > l && ok; l++){
          for(int m = 0; X[i].second > m && ok; m++){
            int nwy = j+l;
            int nwx = k+m;
            if(nwy < 0 || 3 < nwy || nwx < 0 || 3 < nwx)continue;
            
            if(!((1<<(nwy*4+nwx)) & nw))continue;
            //cout << "!!" << nwy << " " << nwx << endl;
            mns += (1<<(nwy*4+nwx));
           // if(n == 0 && i == 1 && nwy == 1 && nwx == 2)cout << nw-mns << endl;
            if(nwc == -1){
              nwc = A[nwy][nwx];
            }else if(nwc != A[nwy][nwx]){
              ok = false;
              break;
            }
          }
        }
        // if(n == 0 && i == 1 && j == 1 && k == 2){
        //   cout << ok << " " << nwc << " " << mns << endl;
        // }
        //cout << i << " " << j << " " << k <<endl;
        if(mns == 0)continue;
        if(ok && nwc!=-1){
          if(ret == -1)ret = dfs(n+1,nw-mns)+1;
          else ret = min(ret,(dfs(n+1,nw-mns)+1));
        }

      }
    }
  }
   return memo[nw] = ret;
}

int main(){
  int n;cin>>n;
  for(int i = 0; n > i; i++){
    int x,y;cin>>x>>y;X.push_back({x,y});
  }
  
  int nw = 1;
  for(int i = 0; 4 > i; i++){
    for(int j = 0; 4 > j; j++){
      cin>>A[i][j];
      nw *= 2;
    }
  }
  cout << dfs(0,nw-1) << endl;
  //cout << memo[65535-3] << endl;

}
accuracy: 1
time_ms: 870
memory_kb: 3680
final_rank: 10

code_snippet: #include<bits/stdc++.h>
#define rep(i,a,...) for(int i = (a)*(strlen(#__VA_ARGS__)!=0);i<(int)(strlen(#__VA_ARGS__)?__VA_ARGS__:(a));++i)
#define per(i,a,...) for(int i = (strlen(#__VA_ARGS__)?__VA_ARGS__:(a))-1;i>=(int)(strlen(#__VA_ARGS__)?(a):0);--i)
#define foreach(i, n) for(auto &i:(n))
#define all(x) (x).begin(), (x).end()
#define bit(x) (1ll << (x))
#define lambda(RES_TYPE, ...) (function<RES_TYPE(__VA_ARGS__)>)[&](__VA_ARGS__) -> RES_TYPE
#define method(FUNC_NAME, RES_TYPE, ...) function<RES_TYPE(__VA_ARGS__)> FUNC_NAME = lambda(RES_TYPE, __VA_ARGS__)
using namespace std;
using ll = long long;
using pii = pair<int,int>;
using pll = pair<ll,ll>;
//const ll MOD = (ll)1e9+7;
const ll MOD = 998244353;
const int INF = (ll)1e9+7;
const ll INFLL = (ll)1e18;
template<class t>
using vvector = vector<vector<t>>;
template<class t>
using vvvector = vector<vector<vector<t>>>;
template<class t>
using priority_queuer = priority_queue<t, vector<t>, greater<t>>;
template<class t, class u> bool chmax(t &a, u b){if(a<b){a=b;return true;}return false;}
template<class t, class u> bool chmin(t &a, u b){if(a>b){a=b;return true;}return false;}
#ifdef DEBUG
#define debug(x) cout<<"LINE "<<__LINE__<<": "<<#x<<" = "<<x<<endl;
#else
#define debug(x) (void)0
#endif

namespace templates{
    ll modpow(ll x, ll b,ll mod=MOD){
        ll res = 1;
        while(b){
            if(b&1)res = res * x % mod;
            x = x * x % mod;
            b>>=1;
        }
        return res;
    }

    ll modinv(ll x){
        return modpow(x, MOD-2);
    }

    bool was_output = false;

    void print();
    template <class t> void print(const vector<t> &);
    template <class t, class u> void print(const pair<t, u> &);
    template <class t> void print(const t&);
    template <class Head, class... Tail> void print(const Head&, const Tail&...);

    template <class t> void println(const vector<vector<t>>&);
    template <class t> void println(const vector<t>&);
    template <class t> void println(const t&);
    template <class Head, class... Tail> void println(const Head&, const Tail&...);
    void println();
    void newline();

    void print(){
        return;
    }

    template <class t>
    void print(const vector<t>&x){
        for(const t&i:x)print(i);
    }
    template <class t, class u>
    void print(const pair<t,u>&p){
        print(p.first);
        print(p.second);
    }
    template <class t>
    void print(const t&x){
        if(was_output)cout<<" ";
        cout<<x;
        was_output = true;
    }
    template <class Head, class... Tail>
    void print(const Head&head,const Tail&...tail){
        print(head);
        print(tail...);
    }

    template<class t>
    void println(const vector<vector<t>>&x){
        for(vector<t> i:x)println(i);
    }
    template<class t>
    void println(const vector<t>&x){
        for(const t&i:x)print(i);
        println();
    }
    template <class t>
    void println(const t&x){
        print(x);
        println();
    }
    void println(){
        if(was_output){
            cout << endl;
            was_output = false;
        }
    }
    template <class Head, class... Tail>
    void println(const Head&head,const Tail&...tail){
        print(head);
        println(tail...);
    }

    void newline(){
        was_output = true;
        println();
    }

    template<class t>
    istream& operator>>(istream&is, vector<t>&x){
        for(auto &i:x)is >> i;
        return is;
    }

    template<class t, class u>
    istream& operator>>(istream&is, pair<t, u>&x){
        is >> x.first >> x.second;
        return is;
    }

    template<class t>
    ostream& operator<<(ostream&os, vector<t> &v){
        os << "{";
        for(t &i:v){
            os << i << ", ";
        }
        os << "}";
        return os;
    }

    template<class t = long long>
    t in(){
        t res; cin >> res; return res;
    }

    template<class t>
    vector<t> sorted(vector<t> line,function<bool(t,t)> comp=[](t a,t b){return a<b;}){
        sort(line.begin(),line.end(),comp);
        return line;
    }

    template<class t>
    vector<t> reversed(vector<t> line){
        reverse(line.begin(),line.end());
        return line;
    }
    string reversed(string str){
        reverse(str.begin(),str.end());
        return str;
    }

    long long gcd(long long a,long long b){
        while(b){
            a %= b;
            swap(a,b);
        }
        return a;
    }

    long long lcm(long long a,long long b){
        return a / gcd(a,b) * b;
    }

    class output_initializer{
    public:
        output_initializer(){
            ios::sync_with_stdio(false);
            cin.tie(nullptr);
            cout << setprecision(20);
        }
    };output_initializer OUTPUT_INITIALIZER_INSTANCE = output_initializer();
}

using namespace templates;

int func(){
    int n = in();
    vector<pii> stamps(n);
    foreach(i,stamps)i=in<pii>();
    vector<int> need(16);
    foreach(i,need){
        char c = in<char>();
        if(c=='R')i = 1;
        else if(c=='G')i = 2;
        else if(c=='B')i = 4;
    }
    vector<int> dp(bit(16),-1);
    method(rec,int,int p){
        if(p==bit(16)-1)return 0;
        int &it = dp[p];
        if(it >= 0)return it;
        it = INF;
        foreach(stamp,stamps){
            rep(i,-stamp.first+1,4+stamp.first-1){
                rep(j,-stamp.second+1,4+stamp.second-1){
                    int ok = 0;
                    int ps = 0;
                    rep(y,max(0,i),min(4,i+stamp.first)){
                        rep(x,max(0,j),min(4,j+stamp.second)){
                            if(bit(4*y+x)&p)continue;
                            ok |= need[y*4+x];
                            ps |= bit(4*y+x);
                        }
                    }
                    if(__builtin_popcount(ok)==1){
                        chmin(it,rec(p|ps)+1);
                    }
                }
            }
        }
        return it;
    };
    return rec(0);
}

int main(){
    println(func());
    return 0;
}
accuracy: 1
time_ms: 530
memory_kb: 3444
final_rank: 4

code_snippet: #include<bits/stdc++.h>
#define int ll
#define rep(i, N) for(int i = 0; i < (int)(N); ++i)
#define rep1(i, N) for(int i = 1; i <= (int)(N); ++i)
#define per(i, N) for(int i = (N)-1; i >= 0; --i)
#define all(v) (v).begin(), (v).end()
#define rall(v) (v).rbegin(), (v).rend()
#define bit(n, k) ((n) >> (k))
#define pcnt(n) (__builtin_popcount(n))
#define TakAo(ans) ans ? cout << "Takahashi\n" : cout << "Aoki\n"
#define YesNo(ans) ans ? cout << "Yes\n" : cout << "No\n"
#define endl '\n'
#define fi first
#define se second
#define mkpr make_pair
#define mktpl make_tuple
#define eb emplace_back

using namespace std;
using ll = int64_t;
using ull = uint64_t;
using ld = long double;
using point = struct{ ll x, y; };
using pointld = struct{ ld x, y; };
using State = string::const_iterator;
template<class T> using max_heap = priority_queue<T>;
template<class T> using min_heap = priority_queue<T, vector<T>, greater<T>>;
template<class T> using vec = vector<T>;
template<class T> using vvec = vec<vec<T>>;
template<class T> using vvvec = vec<vvec<T>>;
template<class T> using vvvvec = vvec<vvec<T>>;

constexpr ld EPS = 1e-10;
constexpr int INF = 1001001001;
constexpr ll LINF = 1001001001001001001ll;
constexpr ll MOD = (0) ? 998244353 : 1e9+7;
constexpr int NIL = -1;
constexpr int pm[2] = {1, -1};
constexpr int dy[4] = {0, 1, 0, -1};
constexpr int dx[4] = {1, 0, -1, 0};

ll cel(ll a, ll b){ return (a + b - 1) / b;}
ll Gcd(ll a, ll b){ return b ? Gcd(b, a % b) : abs(a);}
template<class T> T powi(T x, ll exp){
    return exp > 0 ? (exp & 1 ? x : 1) * powi(x * x, exp >> 1) : x / x;
}
ll modpow(ll x, ll exp, ll mod){
    x %= mod;
    return exp > 0 ? (exp & 1 ? x : 1) * modpow(x * x, exp >> 1, mod) % mod : 1;
}
template<class T> bool chmin(T &a, T b){ return a > b ? (a = b, true) : 0;}
template<class T> bool chmax(T &a, T b){ return a < b ? (a = b, true) : 0;}

using Pair = pair<ll, ll>;
using Tpl = tuple<int, int, int>;

void Main(){
    int N; cin >> N;
    vec<int> H(N), W(N);
    rep(i, N) cin >> H[i] >> W[i];

    vvec<char> G(4, vec<char>(4));
    rep(i, 4)rep(j, 4) cin >> G[i][j];

    const int goal = (1 << 16) - 1;
    queue<Pair> que;
    vec<bool> used(1 << 16, 0);
    que.push(mkpr(0, 0));
    used[0] = 1;
    char col[3] = {'R', 'G', 'B'};

    while(!que.empty()){
        Pair p = que.front();
        que.pop();
        int num = p.fi, cst = p.se;
        
        rep(i, N){
            for(int j = -H[i] + 1; j < 4; j++){
                for(int k = -W[i] + 1; k < 4; k++){
                    for(int l = 0; l < 3; l++){
                        int tmp = num;

                        for(int a = max(j, ll(0)); a < min(j + H[i], ll(4)); a++){
                            for(int b = max(k, ll(0)); b < min(k + W[i], ll(4)); b++){
                                if(col[l] == G[a][b]){
                                    tmp |= (1 << (4 * a + b));
                                }
                                else{
                                    //cout << bitset<16>(tmp) << endl;
                                    tmp &= ~(1 << (4 * a + b));
                                    //cout << bitset<16>(tmp) << endl;
                                }
                            }
                        }

                        if(tmp == goal){
                            cout << cst + 1 << endl;
                            return;
                        }
                        else{
                            if(!used[tmp]){
                                used[tmp] = 1;
                                que.push(mkpr(tmp, cst + 1));
                            }
                        }
                    }
                }
            }
        }
    }

    cout << -1 << endl;
}
 
signed main(){
    cin.tie(nullptr);
    ios_base::sync_with_stdio(false);
    cout << fixed << setprecision(10);
    Main();
    return 0;
}
accuracy: 1
time_ms: 540
memory_kb: 3936
final_rank: 5

code_snippet: #include<bits/stdc++.h>
// #include<atcoder/modint>
using namespace std;
// using namespace atcoder;
char G[4][4];
int n;
int dist[1 << 17];
int bi[20];
void solve(){
	cin >> n;
	vector<pair<int, int>> hw(n);
	for(int i = 0; i < n; i++) cin >> hw[i].first >> hw[i].second;
	for(int i = 0; i < (1 << 16); i++) dist[i] = -1;
	for(int i = 0; i < 4; i++){
		for(int j = 0; j < 4; j++){
			cin >> G[i][j];
		}
	}
	for(int i = 0; i < 20; i++) bi[i] = 1 << i;
	string rgb = "RGB";
	set<pair<int, int>> bits;
	for(auto &[h, w]: hw){
		for(auto c:rgb){				
			for(int i = -h + 1; i <= 3; i++){
				for(int j = -w + 1; j <= 3; j++){
					int andbit = (1 << 16) - 1;
					int orbit = 0;
					for(int ii = i; ii < i + h; ii++){
						for(int jj = j; jj < j + w; jj++){
							if(0 <= ii && ii < 4 && 0 <= jj && jj < 4){
								int ij = ii * 4 + jj;
								andbit ^= bi[ij];
								if(G[ii][jj] == c) orbit |= bi[ij];
							}
						}
					}
					bits.insert({orbit, andbit});
				}
			}
		}
	}
	
	dist[0] = 0;
	queue<int> que;
	que.push(0);
	while(!que.empty()){
		int bit = que.front();
		que.pop();
		for(auto &[orbit, andbit]: bits){
			int nbit = bit;
			nbit &= andbit;
			nbit |= orbit;
			if(dist[nbit] == -1){
				dist[nbit] = dist[bit] + 1;
				que.push(nbit);
			}
		}
	}
	cout << dist[(1 << 16) - 1] << "\n";


}

int main(){
    cin.tie(0)->sync_with_stdio(0);
    int t;
    t = 1;
    // cin >> t;
    while(t--) solve();
}
accuracy: 1
time_ms: 50
memory_kb: 3844
final_rank: 1