Problem:
Problem A:
Bicube
Mary Thomas has a number of sheets of squared paper. Some of squares are painted either in black or some
colorful
color (such as red and blue) on the front side. Cutting off the unpainted part, she will have eight opened-up unit cubes. A unit cube here refers to a cube of which each face consists of one square.
She is going to build those eight unit cubes with the front side exposed and then a bicube with them. A bicube is a cube of the size 2 × 2 × 2, consisting of eight unit cubes, that satisfies the following conditions:
faces of the unit cubes that comes to the inside of the bicube are all black;
each face of the bicube has a uniform
colorful
color; and
the faces of the bicube have colors all different.
Your task is to write a program that reads the specification of a sheet of squared paper and decides whether a
bicube can be built with the eight unit cubes resulting from it.
Input
The input contains the specification of a sheet. The first line contains two integers
H
and
W
, which denote the height and width of the sheet (3 ≤
H
,
W
≤ 50). Then H lines follow, each consisting of
W
characters. These lines show the squares on the front side of the sheet. A character represents the color of a grid: alphabets and digits ('A' to 'Z', 'a' to 'z', '0' to '9') for colorful squares, a hash ('#') for a black square, and a dot ('.') for an unpainted square. Each alphabet or digit denotes a unique color: squares have the same color if and only if they are represented by the same character.
Each component of connected squares forms one opened-up cube. Squares are regarded as connected when they have a common edge; those just with a common vertex are not.
Output
Print "
Yes
" if a bicube can be built with the given sheet; "
No
" otherwise.
Sample Input 1
3 40
.a....a....a....a....f....f....f....f...
#bc#.#cd#.#de#.#eb#.#cb#.#dc#.#ed#.#be#.
.#....#....#....#....#....#....#....#...
Output for the Sample Input 1
Yes
Sample Input 2
5 35
.a....a....a....a....f....f....f...
#bc#.#cd#.#de#.#eb#.#cb#.#dc#.#ed#.
.#..f.#....#....#....#....#....#...
..e##..............................
.b#................................
Output for the Sample Input 2
Yes
Sample Input 3
3 40
.a....a....a....a....f....f....f....f...
#bc#.#cd#.#de#.#eb#.#cb#.#dc#.#ed#.#eb#.
.#....#....#....#....#....#....#....#...
Output for the Sample Input 3
No

Submitted solutions:

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

// 0: top, 1: front, 2:right, 3:back, 4:left, 5:bottom
const vector<vector<string>> dice_map = {
    {"0...",
     "1234",
     "5..."},
    {"0...",
     "1234",
     ".5.."},
    {"0...",
     "1234",
     "..5."},
    {"0...",
     "1234",
     "...5"},
    {".0..",
     "4123",
     ".5.."},
    {".0..",
     "4123",
     "..5."},
    {"...0",
     "2341",
     "..5."},
    {"...0",
     "2341",
     ".5.."},
    {"...0",
     "2341",
     "5..."},
    {"..0.",
     "3412",
     ".5.."},
    {"..0.",
     "3412",
     "5..."},
    {".0..",
     "4123",
     "5..."},
    {"..025",
     "341.."},
    {"025..",
     "..143"},
    {"..02",
     "341.",
     "5..."},
    {"40..",
     ".123",
     "...5"},
    {"..02",
     "341.",
     ".5.."},
    {"40..",
     ".123",
     "..5."},
    {"..02",
     "341.",
     "..5."},
    {"40..",
     ".123",
     ".5.."},
    {"..02",
     ".41.",
     "35.."},
    {"40..",
     ".12.",
     "..53"},
};

vector<string> rot_map(vector<string> const& v) {
    const int n = v.size(), m = v[0].size();
    vector<string> res(m);
    for(int i = 0; i < n; ++i) {
        for(int j = 0; j < m; ++j) {
            res[j] += v[n - i - 1][j];
        }
    }
    return res;
};

using dice = string;

constexpr int rot_d[2][6] = {
    {3, 0, 2, 5, 4, 1}, // Front
    {0, 4, 1, 2, 3, 5}, // Side
};

dice rot_dice(dice const& v, int dir) {
    dice res(6, ' ');
    for(int j = 0; j < 6; ++j) {
        res[j] = v[rot_d[dir][j]];
    }
    return res;
}

bool is_valid_dice(dice const& d) {
    bool res = true;
    for(int i = 0; i < 3; ++i) {
        res &= isalpha(d[i]) || isdigit(d[i]);
        res &= d[i + 3] == '#';
    }
    return res;
}

bool check(vector<dice>& ds, int i) {
    bool res = false;
    if(i == 8) {
        res = true;
        for(int j = 0; j < 4; ++j) {
            res &= ds[j][0] == ds[0][0]; // top
            res &= ds[j + 4][0] == ds[4][0]; // bottom
            // side
            res &= ds[j][2] == ds[(j + 1) % 4][1];
            //res &= ds[j + 4][1] == ds[(j + 1) % 4 + 4][2];
            res &= ds[j][1] == ds[j + 4][2] && ds[j][2] == ds[j + 4][1];
        }
        return res;
    } else {
        for(int j = 0; j < 3; ++j) {
            res |= check(ds, i + 1);
            rotate(begin(ds[i]), begin(ds[i]) + 1, end(ds[i]));
        }
    }
    return res;
}

int main() {
    int h, w; cin >> h >> w;
    vector<string> v(h);
    for(auto& s : v) cin >> s;

    { // check1
        map<char, int> cols;
        for(auto const& s : v) {
            for(auto const c : s) {
                if(c == '.' || c == '#') continue;
                cols[c] += 1;
            }
        }
        bool chk = cols.size() == 6u;
        for(auto const& p : cols) {
            chk &= p.second == 4;
        }
        if(!chk) {
            cout << "No" << endl;
            return 0;
        }
    }

    vector<dice> dices;
    auto in_range = [&] (int y, int x) {
        return 0 <= y && y < h && 0 <= x && x < w;
    };
    for(int i = 0; i < h; ++i) {
        for(int j = 0; j < w; ++j) {
            for(auto dm : dice_map) {
                string td;
                for(int k = 0; k < 4; ++k, dm = rot_map(dm)) {
                    const int n = dm.size(), m = dm[0].size();
                    if(!in_range(i + n - 1, j + m - 1)) continue;
                    string d(6, '.');
                    for(int y = i; y < i + n; ++y) {
                        for(int x = j; x < j + m; ++x) {
                            if(dm[y - i][x - j] == '.') continue;
                            d[dm[y - i][x - j] - '0'] = v[y][x];
                        }
                    }
                    if(d[0] == '.' || d[0] == '#') {
                        d = rot_dice(rot_dice(d, 0), 0);
                    }
                    for(int l = 0; l < 4; ++l, d = rot_dice(d, 1)) {
                        if(!is_valid_dice(d)) continue;
                        td = d.substr(0, 3);
                    }
                }
                if(!td.empty()) {
                    dices.push_back(td);
                }
            }
        }
    }

    // check
    sort(begin(dices), end(dices));
    bool ans = false;
    do {
        ans |= check(dices, 1);
    } while(!ans && next_permutation(begin(dices) + 1, end(dices)));

    cout << (ans ? "Yes" : "No") << endl;
}
accuracy: 1
time_ms: 470
memory_kb: 3228
final_rank: 3

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

// 0: top, 1: front, 2:right, 3:back, 4:left, 5:bottom
const vector<vector<string>> dice_map = {
    {"0...",
     "1234",
     "5..."},
    {"0...",
     "1234",
     ".5.."},
    {"0...",
     "1234",
     "..5."},
    {"0...",
     "1234",
     "...5"},
    {".0..",
     "4123",
     ".5.."},
    {".0..",
     "4123",
     "..5."},
    {"..025",
     "341.."},
    {"025..",
     "..341"},
    {"..02",
     "341.",
     "5..."},
    {"40..",
     ".123",
     "...5"},
    {"..02",
     "341.",
     ".5.."},
    {"40..",
     ".123",
     "..5."},
    {"..02",
     "341.",
     "..5."},
    {"40..",
     ".123",
     ".5.."},
    {"..02",
     ".41.",
     "35.."},
    {"40..",
     ".12.",
     "..53"},
};

vector<string> rot_map(vector<string> const& v) {
    const int n = v.size(), m = v[0].size();
    vector<string> res(m);
    for(int i = 0; i < n; ++i) {
        for(int j = 0; j < m; ++j) {
            res[j] += v[n - i - 1][j];
        }
    }
    return res;
};

using dice = string;

constexpr int rot_d[2][6] = {
    {3, 0, 2, 5, 4, 1}, // Front
    {0, 4, 1, 2, 3, 5}, // Side
};

dice rot_dice(dice const& v, int dir) {
    dice res(6, ' ');
    for(int j = 0; j < 6; ++j) {
        res[j] = v[rot_d[dir][j]];
    }
    return res;
}

bool is_valid_dice(dice const& d) {
    bool res = true;
    for(int i = 0; i < 3; ++i) {
        res &= isalpha(d[i]) || isdigit(d[i]);
        res &= d[i + 3] == '#';
    }
    return res;
}

bool check(vector<dice>& ds, int i) {
    bool res = false;
    if(i == 8) {
        res = true;
        for(int j = 0; j < 4; ++j) {
            res &= ds[j][0] == ds[0][0]; // top
            res &= ds[j + 4][0] == ds[4][0]; // bottom
            // side
            res &= ds[j][2] == ds[(j + 1) % 4][1];
            res &= ds[j + 4][1] == ds[(j + 1) % 4 + 4][2];
            res &= ds[j][1] == ds[j + 4][2] && ds[j][2] == ds[j + 4][1];
        }
        return res;
    } else {
        for(int j = 0; j < 3; ++j) {
            res |= check(ds, i + 1);
            rotate(begin(ds[i]), begin(ds[i]) + 1, end(ds[i]));
        }
    }
    return res;
}

int main() {
    int h, w; cin >> h >> w;
    vector<string> v(h);
    for(auto& s : v) cin >> s;

    { // check1
        map<char, int> cols;
        for(auto const& s : v) {
            for(auto const c : s) {
                if(c == '.' || c == '#') continue;
                cols[c] += 1;
            }
        }
        bool chk = cols.size() == 6u;
        for(auto const& p : cols) {
            chk &= p.second == 4;
        }
        if(!chk) {
            cout << "No" << endl;
            return 0;
        }
    }

    vector<dice> dices;
    auto in_range = [&] (int y, int x) {
        return 0 <= y && y < h && 0 <= x && x < w;
    };
    for(int i = 0; i < h; ++i) {
        for(int j = 0; j < w; ++j) {
            for(auto dm : dice_map) {
                string td;
                for(int k = 0; k < 4; ++k, dm = rot_map(dm)) {
                    const int n = dm.size(), m = dm[0].size();
                    if(!in_range(i + n - 1, j + m - 1)) continue;
                    string d(6, '.');
                    for(int y = i; y < i + n; ++y) {
                        for(int x = j; x < j + m; ++x) {
                            if(dm[y - i][x - j] == '.') continue;
                            d[dm[y - i][x - j] - '0'] = v[y][x];
                        }
                    }
                    if(d[0] == '.' || d[0] == '#') {
                        d = rot_dice(rot_dice(d, 0), 0);
                    }
                    for(int l = 0; l < 4; ++l, d = rot_dice(d, 1)) {
                        if(!is_valid_dice(d)) continue;
                        td = d.substr(0, 3);
                    }
                }
                if(!td.empty()) {
                    dices.push_back(td);
                }
            }
        }
    }

    // check
    sort(begin(dices), end(dices));
    bool ans = false;
    do {
        ans |= check(dices, 0);
    } while(!ans && next_permutation(begin(dices) + 1, end(dices)));

    cout << (ans ? "Yes" : "No") << endl;
}
accuracy: 0.020833333333333332
time_ms: 1450
memory_kb: 3184
final_rank: 6

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i,n) for(int (i)=0;(i)<(int)(n);++(i))
#define all(x) (x).begin(),(x).end()
#define pb push_back
#define fi first
#define se second
#define dbg(x) cout<<#x" = "<<((x))<<endl
template<class T,class U> ostream& operator<<(ostream& o, const pair<T,U> &p){o<<"("<<p.fi<<","<<p.se<<")";return o;}
template<class T> ostream& operator<<(ostream& o, const vector<T> &v){o<<"[";for(T t:v){o<<t<<",";}o<<"]";return o;}

struct Dice{
    char f[7];

    Dice(){
        rep(i,6) f[i] = '?';
    }

    void R(){
        char tmp = f[0];
        f[0] = f[4];
        f[4] = f[5];
        f[5] = f[2];
        f[2] = tmp;
    }

    void L(){
        char tmp = f[0];
        f[0] = f[2];
        f[2] = f[5];
        f[5] = f[4];
        f[4] = tmp;
    }

    void B(){
        char tmp = f[0];
        f[0] = f[1];
        f[1] = f[5];
        f[5] = f[3];
        f[3] = tmp;
    }

    void F(){
        char tmp = f[0];
        f[0] = f[3];
        f[3] = f[5];
        f[5] = f[1];
        f[1] = tmp;
    }

    void CCW(){
        char tmp = f[1];
        f[1] = f[4];
        f[4] = f[3];
        f[3] = f[2];
        f[2] = tmp;
    }
};

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

int h,w;
string s[55];
bool vis[55][55];

bool IN(int y, int x){
    return (0<=y && y<h && 0<=x && x<w && s[y][x]!='.');
}

Dice t;
void dfs(int y, int x){
    vis[y][x] = true;
    t.f[0] = s[y][x];

    rep(i,4){
        int ny = y+dy[i], nx = x+dx[i];
        if(IN(ny,nx) && !vis[ny][nx]){
            if(i==0) t.B();
            else if(i==1) t.F();
            else if(i==2) t.L();
            else if(i==3) t.R();

            dfs(ny,nx);

            if(i==0) t.F();
            else if(i==1) t.B();
            else if(i==2) t.R();
            else if(i==3) t.L();
        }
    }
}

int black[8][3]={ {2,3,5}, {3,4,5}, {1,4,5}, {1,2,5}, {0,2,3}, {0,3,4}, {0,1,4}, {0,1,2} };

bool solve(){
    cin >>h >>w;
    rep(i,h) cin >>s[i];

    vector<Dice> d;
    rep(i,h)rep(j,w)if(s[i][j]!='.' && !vis[i][j]){
        t = Dice();
        dfs(i,j);
        d.pb(t);
    }

    assert(d.size() == 8);

    // rep(i,8){
    //     rep(j,6) printf(" %c",d[i].f[j]);
    //     printf("\n");
    // }

    rep(i,8){
        int b_ct = 0;
        rep(j,6) b_ct += (d[i].f[j]=='#');
        if(b_ct != 3) return false;
    }

    vector<int> p(8);
    rep(i,8) p[i] = i;

    do{
        bool ok = true;

        vector<vector<char>> aa,bb;
        for(int i:{0,6}){
            t = d[p[i]];

            int CT = 0;
            rep(z1,4){
                t.R();
                rep(z2,4){
                    t.F();
                    rep(z3,4){
                        t.CCW();

                        int b_ct = 0;
                        rep(j,3) b_ct += (t.f[black[i][j]]=='#');
                        if(b_ct == 3){
                            ++CT;

                            if(i==0){
                                aa.pb({t.f[0],t.f[1],t.f[4]});
                            }
                            else{
                                bb.pb({t.f[2],t.f[3],t.f[5]});
                            }
                        }
                    }
                }
            }

            if(CT == 0){
                ok = false;
                break;
            }
        }
        if(!ok) continue;

        // dbg(p);
        sort(all(aa));
        aa.erase(unique(all(aa)), aa.end());
        sort(all(bb));
        bb.erase(unique(all(bb)), bb.end());

        int AA = aa.size(), BB = bb.size();
        rep(ai,AA)rep(bi,BB){
            char ch[7];
            ch[0] = aa[ai][0];
            ch[1] = aa[ai][1];
            ch[2] = bb[bi][0];
            ch[3] = bb[bi][1];
            ch[4] = aa[ai][2];
            ch[5] = bb[bi][2];

            set<char> cols;
            rep(i,6) cols.insert(ch[i]);
            if(cols.size() != 6) continue;

            ok = true;
            rep(i,8){
                bool found = false;
                t = d[p[i]];
                rep(z1,4){
                    t.R();
                    rep(z2,4){
                        t.F();
                        rep(z3,4){
                            t.CCW();

                            int b_ct = 0;
                            rep(j,3) b_ct += (t.f[black[i][j]]=='#');
                            if(b_ct == 3){
                                int ok_ct = 0;
                                rep(j,6){
                                    if(t.f[j]!='#'){
                                        ok_ct += (t.f[j] == ch[j]);
                                    }
                                }

                                if(ok_ct == 3) found = true;
                            }
                        }
                    }
                }

                if(!found){
                    ok = false;
                    break;
                }
            }
            if(ok) return true;
        }
    }while(next_permutation(all(p)));

    return false;
}

int main(){
    cout << (solve()?"Yes":"No") << endl;
    return 0;
}
accuracy: 1
time_ms: 150
memory_kb: 3244
final_rank: 2

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i,n) for(int (i)=0;(i)<(int)(n);++(i))
#define all(x) (x).begin(),(x).end()
#define pb push_back
#define fi first
#define se second
#define dbg(x) cout<<#x" = "<<((x))<<endl
template<class T,class U> ostream& operator<<(ostream& o, const pair<T,U> &p){o<<"("<<p.fi<<","<<p.se<<")";return o;}
template<class T> ostream& operator<<(ostream& o, const vector<T> &v){o<<"[";for(T t:v){o<<t<<",";}o<<"]";return o;}

struct Dice{
    char f[7];

    Dice(){
        rep(i,6) f[i] = '?';
    }

    void R(){
        char tmp = f[0];
        f[0] = f[4];
        f[4] = f[5];
        f[5] = f[2];
        f[2] = tmp;
    }

    void L(){
        char tmp = f[0];
        f[0] = f[2];
        f[2] = f[5];
        f[5] = f[4];
        f[4] = tmp;
    }

    void B(){
        char tmp = f[0];
        f[0] = f[1];
        f[1] = f[5];
        f[5] = f[3];
        f[3] = tmp;
    }

    void F(){
        char tmp = f[0];
        f[0] = f[3];
        f[3] = f[5];
        f[5] = f[1];
        f[1] = tmp;
    }
};

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

int h,w;
string s[55];
bool vis[55][55];

bool IN(int y, int x){
    return (0<=y && y<h && 0<=x && x<w && s[y][x]!='.');
}

Dice t;
void dfs(int y, int x){
    vis[y][x] = true;
    t.f[0] = s[y][x];

    rep(i,4){
        int ny = y+dy[i], nx = x+dx[i];
        if(IN(ny,nx) && !vis[ny][nx]){
            if(i==0) t.B();
            else if(i==1) t.F();
            else if(i==2) t.L();
            else if(i==3) t.R();

            dfs(ny,nx);

            if(i==0) t.F();
            else if(i==1) t.B();
            else if(i==2) t.R();
            else if(i==3) t.L();
        }
    }
}

int black[8][3]={ {2,3,5}, {3,4,5}, {1,4,5}, {1,2,5}, {0,2,3}, {0,3,4}, {0,1,4}, {0,1,2} };

bool solve(){
    cin >>h >>w;
    rep(i,h) cin >>s[i];

    vector<Dice> d;
    rep(i,h)rep(j,w)if(s[i][j]!='.' && !vis[i][j]){
        t = Dice();
        dfs(i,j);
        d.pb(t);
    }

    assert(d.size() == 8);

    // rep(i,8){
    //     rep(j,6) printf(" %c",d[i].f[j]);
    //     printf("\n");
    // }

    rep(i,8){
        int b_ct = 0;
        rep(j,6) b_ct += (d[i].f[j]=='#');
        if(b_ct != 3) return false;
    }

    vector<int> p(8);
    rep(i,8) p[i] = i;

    do{
        bool ok = true;

        vector<vector<char>> aa,bb;
        for(int i:{0,6}){
            t = d[p[i]];

            int CT = 0;
            rep(j,4){
                t.R();
                rep(k,4){
                    t.F();

                    int b_ct = 0;
                    rep(l,3) b_ct += (t.f[black[i][l]]=='#');
                    if(b_ct == 3){
                        ++CT;

                        if(i==0){
                            aa.pb({t.f[0],t.f[1],t.f[4]});
                        }
                        else{
                            bb.pb({t.f[2],t.f[3],t.f[5]});
                        }
                    }
                }
            }

            if(CT == 0){
                ok = false;
                break;
            }
        }
        if(!ok) continue;

        // dbg(p);
        int AA = aa.size(), BB = bb.size();
        rep(ai,AA)rep(bi,BB){
            char ch[7];
            ch[0] = aa[ai][0];
            ch[1] = aa[ai][1];
            ch[2] = bb[bi][0];
            ch[3] = bb[bi][1];
            ch[4] = aa[ai][2];
            ch[5] = bb[bi][2];

            set<char> cols;
            rep(i,6) cols.insert(ch[i]);
            if(cols.size() != 6) continue;

            ok = true;
            rep(i,8){
                bool found = false;
                t = d[p[i]];
                rep(j,4){
                    t.R();
                    rep(k,4){
                        t.F();

                        int b_ct = 0;
                        rep(l,3) b_ct += (t.f[black[i][l]]=='#');
                        if(b_ct == 3){
                            int ok_ct = 0;
                            rep(l,6){
                                if(t.f[l]!='#'){
                                    ok_ct += (t.f[l] == ch[l]);
                                }
                            }

                            if(ok_ct == 3){
                                found = true;
                            }
                        }
                    }
                }

                if(!found){
                    ok = false;
                    break;
                }
            }
            if(ok) return true;
        }
    }while(next_permutation(all(p)));

    return false;
}

int main(){
    cout << (solve()?"Yes":"No") << endl;
    return 0;
}
accuracy: 0.020833333333333332
time_ms: 30
memory_kb: 3216
final_rank: 4

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i,n) for(int (i)=0;(i)<(int)(n);++(i))
#define all(x) (x).begin(),(x).end()
#define pb push_back
#define fi first
#define se second
#define dbg(x) cout<<#x" = "<<((x))<<endl
template<class T,class U> ostream& operator<<(ostream& o, const pair<T,U> &p){o<<"("<<p.fi<<","<<p.se<<")";return o;}
template<class T> ostream& operator<<(ostream& o, const vector<T> &v){o<<"[";for(T t:v){o<<t<<",";}o<<"]";return o;}

struct Dice{
    char f[7];

    Dice(){
        rep(i,6) f[i] = '?';
    }

    void R(){
        char tmp = f[0];
        f[0] = f[4];
        f[4] = f[5];
        f[5] = f[2];
        f[2] = tmp;
    }

    void L(){
        char tmp = f[0];
        f[0] = f[2];
        f[2] = f[5];
        f[5] = f[4];
        f[4] = tmp;
    }

    void B(){
        char tmp = f[0];
        f[0] = f[1];
        f[1] = f[5];
        f[5] = f[3];
        f[3] = tmp;
    }

    void F(){
        char tmp = f[0];
        f[0] = f[3];
        f[3] = f[5];
        f[5] = f[1];
        f[1] = tmp;
    }
};

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

int h,w;
string s[55];
bool vis[55][55];

bool IN(int y, int x){
    return (0<=y && y<h && 0<=x && x<w && s[y][x]!='.');
}

Dice t;
void dfs(int y, int x){
    vis[y][x] = true;
    t.f[0] = s[y][x];

    rep(i,4){
        int ny = y+dy[i], nx = x+dx[i];
        if(IN(ny,nx) && !vis[ny][nx]){
            if(i==0) t.B();
            else if(i==1) t.F();
            else if(i==2) t.L();
            else if(i==3) t.R();

            dfs(ny,nx);

            if(i==0) t.F();
            else if(i==1) t.B();
            else if(i==2) t.R();
            else if(i==3) t.L();
        }
    }
}

int black[8][3]={ {2,3,5}, {3,4,5}, {1,4,5}, {1,2,5}, {0,2,3}, {0,3,4}, {0,1,4}, {0,1,2} };

bool solve(){
    cin >>h >>w;
    rep(i,h) cin >>s[i];

    vector<Dice> d;
    rep(i,h)rep(j,w)if(s[i][j]!='.' && !vis[i][j]){
        t = Dice();
        dfs(i,j);
        d.pb(t);
    }

    assert(d.size() == 8);

    rep(i,8){
        int b_ct = 0;
        rep(j,6) b_ct += (d[i].f[j]=='#');
        if(b_ct != 3) return false;
    }

    vector<int> p(8);
    rep(i,8) p[i] = i;

    do{
        bool ok = true;

        vector<vector<char>> aa,bb;
        for(int i:{0,6}){
            t = d[p[i]];
            bool found = false;

            int CT = 0;
            rep(j,4){
                t.R();
                rep(k,4){
                    t.F();

                    int b_ct = 0;
                    rep(l,3) b_ct += (t.f[black[i][l]]=='#');
                    if(b_ct == 3){
                        ++CT;

                        if(i==0){
                            aa.pb({t.f[0],t.f[1],t.f[4]});
                        }
                        else{
                            bb.pb({t.f[2],t.f[3],t.f[5]});
                        }
                    }
                }
            }

            if(CT == 0){
                ok = false;
                break;
            }
        }
        if(!ok) continue;

        int AA = aa.size(), BB = bb.size();
        rep(ai,AA)rep(bi,BB){
            char ch[6];
            ch[0] = aa[ai][0];
            ch[1] = aa[ai][1];
            ch[2] = bb[bi][0];
            ch[3] = bb[bi][1];
            ch[4] = aa[ai][2];
            ch[5] = bb[bi][2];

            ok = true;
            rep(i,8){
                bool found = false;
                t = d[p[i]];
                rep(j,4){
                    t.R();
                    rep(k,4){
                        t.F();

                        int b_ct = 0;
                        rep(l,3) b_ct += (t.f[black[i][l]]=='#');
                        if(b_ct == 3){
                            int ok_ct = 0;
                            rep(l,6){
                                if(t.f[l]!='#'){
                                    ok_ct += (t.f[l] == ch[l]);
                                }
                            }

                            if(ok_ct == 3){
                                found = true;
                                break;
                            }
                        }
                    }
                    if(found) break;
                }

                if(!found){
                    ok = false;
                    break;
                }
            }
            if(ok) return true;
        }
    }while(next_permutation(all(p)));

    return false;
}

int main(){
    cout << (solve()?"Yes":"No") << endl;
    return 0;
}
accuracy: 0.020833333333333332
time_ms: 30
memory_kb: 3216
final_rank: 4

code_snippet: #include<iostream>
#include<set>
#include<cassert>
#include<algorithm>
#include<queue>
using namespace std;
#define REP(i,b,n) for(int i=b;i<n;i++)
#define rep(i,n)   REP(i,0,n)

#define r_swap(x,a,b,c,d) swap(x.a,x.b);swap(x.b,x.c);swap(x.c,x.d);
const char black = '#';
const int N = 10;
const int inf = (1<<20);
char m[50][50];
enum{TOP=0,FRONT,BACK,BOTTOM,RIGHT,LEFT};
class Dice{
public:
  char top,front,right,left,back,bottom;
  bool operator<(const Dice & a)const{
    if (top != a.top)return top < a.top;
    if (front != a.front)return front < a.front;
    if (right != a.right)return right < a.right;
    if (left != a.left  )return left < a.left;
    if (back != a.back)return back < a.back;
    if (bottom != a.bottom)return bottom < a.bottom;
    return false;
  }
};

void rotate_r(Dice &x){
  r_swap(x,top,left,bottom,right);
}

void rotate_l(Dice &x){
  r_swap(x,top,right,bottom,left);
}

void rotate_f(Dice &x){
  r_swap(x,top,back,bottom,front);
}

void rotate_b(Dice &x){
  r_swap(x,top,front,bottom,back);
}

void rotate_cw(Dice &x){
  r_swap(x,back,left,front,right);
}

void rotate_ccw(Dice &x){
  r_swap(x,back,right,front,left);
}

void generate(Dice x,Dice *data){
  rep(i,6){
    rep(j,4){
      data[i*4+j]=x;
      rotate_cw(x);
    }
    if (i%2 == 0)rotate_r(x);
    else rotate_f(x);
  }
}

bool isout(int y,int x,int r,int c){
  return x==-1||y==-1||x==c||y==r;
}

int dx[]={0,1,0,-1};
int dy[]={1,0,-1,0};
int next[6][4]={
  FRONT,RIGHT,BACK,LEFT,
  BOTTOM,RIGHT,TOP,LEFT,
  TOP,RIGHT,BOTTOM,LEFT,
  BACK,RIGHT,FRONT,LEFT,
  BACK,TOP,FRONT,LEFT,
  BACK,BOTTOM,FRONT,TOP
};

bool validcheck(int m[N][N],int y,int x){
  int now = m[y][x];
  rep(l,4){
    bool isok=true;
    rep(i,4){
      int nex=x+dx[i],ney=y+dy[i];
      if (isout(ney,nex,N,N) || m[ney][nex] == -1)continue;
      if (m[ney][nex] != next[now][(l+i)%4]){
	isok=false;
	break;
      }
    }
    if (isok)return true;
  }
  return false;
}

Dice generate(int *y,int *x,char *color){
  int array[]={0,1,2,3,4,5};
  int lmost=inf,dmost=inf;
  int m[10][10]={-1};
  rep(i,6){
    lmost=min(lmost,x[i]);
    dmost=min(dmost,y[i]);
  }
  rep(i,6){
    x[i]-=lmost;
    y[i]-=dmost;
  }

  do{
    rep(i,10)rep(j,10)m[i][j]=-1;
    rep(i,6){
      m[y[i]][x[i]]=array[i];
    }
    bool isok=true;
    rep(i,6){
      if (!validcheck(m,y[i],x[i])){
	isok=false;
	break;
      }
    }
    if (isok){
      Dice ret;
      //answer construction
      rep(i,6){
	switch(m[y[i]][x[i]]){
	case TOP:
	  ret.top=color[i];
	  break;
	case FRONT :
	  ret.front=color[i];
	  break;
	case BOTTOM:
	  ret.bottom=color[i];
	  break;
	case BACK:
	  ret.back=color[i];
	  break;
	case RIGHT:
	  ret.right=color[i];
	  break;
	case LEFT:
	  ret.left=color[i];
	  break;
	default:
	  assert(false);
	};
      }
      return ret;
    }
  }while(next_permutation(array,array+6));
  assert(false);
}

void output(Dice &a){
  cout <<"TOP "<< a.top << endl;
  cout <<"FRONT "<<a.front << endl;
  cout <<"BOTTOM " << a.bottom << endl;
  cout <<"BACK " << a.back << endl;
  cout <<"RIGHT " << a.right << endl;
  cout <<"LEFT " << a.left << endl;
}

bool vis[50][50];

void dfs(int y,int x,int r,int c,int *ally,int *allx,char *allc,int &p){
  if (vis[y][x])return;
  if (m[y][x]== '.')return;
  vis[y][x]=true;
  ally[p]=y;
  allx[p]=x;
  allc[p]=m[y][x];
  p++;
  rep(i,4){
    int nex=x+dx[i],ney=y+dy[i];
    if (isout(ney,nex,r,c)||m[ney][nex] == '.')continue;
    dfs(ney,nex,r,c,ally,allx,allc,p);
  }
}

void getall(Dice *in,int r,int c){
  rep(i,r)rep(j,c)vis[i][j]=false;
  int now=0;
  rep(i,r){
    rep(j,c){
      if (m[i][j] != '.' && !vis[i][j]){
	int allx[6],ally[6];
	char allc[6];
	int tmpp=0;
	dfs(i,j,r,c,ally,allx,allc,tmpp);
	in[now++]=generate(ally,allx,allc);
	//output(in[now-1]);
      }
    }
  }
}

Dice all[8][24];

bool mustblack(int i,Dice &a){
  switch(i){
  case 0:
    return a.right == black && a.back == black && a.bottom == black;
    break;
  case 1:
    return a.left == black && a.back == black && a.bottom == black;
    break;
  case 2:
    return a.front == black && a.right == black && a.bottom == black;
    break;
  case 3:
    return a.front == black && a.left == black && a.bottom == black;
    break;
  case 4:
    return a.right == black && a.top == black && a.back == black;
    break;
  case 5:
    return a.left == black && a.top == black && a.back == black;
    break;
  case 6:
    return a.right == black && a.top == black && a.front == black;
    break;
  case 7:
    return a.left == black && a.top == black && a.front == black;
    break;
  };
  assert(false);
}

bool allsame(Dice *in,int a,int b,int c,int d,int tar){
  switch(tar){
  case FRONT:
    return in[a].front==in[b].front && in[a].front==in[c].front&&in[a].front == in[d].front;
    break;
  case TOP:
    return in[a].top==in[b].top && in[a].top==in[c].top&&in[a].top == in[d].top;
    break;
  case RIGHT:
    return in[a].right==in[b].right && in[a].right==in[c].right&&in[a].right == in[d].right;
    break;
  case LEFT:
    return in[a].left==in[b].left && in[a].left==in[c].left&&in[a].left == in[d].left;
    break;
  case BACK:
    return in[a].back==in[b].back && in[a].back==in[c].back&&in[a].back == in[d].back;
    break;
  case BOTTOM:
    return in[a].bottom==in[b].bottom && in[a].bottom==in[c].bottom&&in[a].bottom == in[d].bottom;
    break;
  }
  return false;
}

bool solve(int now,Dice *ans){
  if (now == 5+1){
    if (!allsame(ans,0,1,4,5,FRONT))return false;
  }else if (now == 3+1){
    if (!allsame(ans,0,1,2,3,TOP))return false;
  }else if (now == 7+1){
    if (!allsame(ans,1,3,5,7,RIGHT))return false;
    if (!allsame(ans,4,5,6,7,BOTTOM))return false;
    if (!allsame(ans,2,3,6,7,BACK))return false;
  }else if (now == 6+1){
    if (!allsame(ans,0,2,4,6,LEFT))return false;
  }

  if (now == 8){
    char hoge[6]={ans[1].front,ans[1].top,ans[3].right,ans[2].left,
		  ans[3].back,ans[5].bottom};
    Dice a[8];
    rep(i,8)a[i]=ans[i];
    rep(i,6){
      if (hoge[i] == '#')return false;
      REP(j,i+1,6){
	if (hoge[i] == hoge[j])return false;
      }
    }

    return true;
  }

  rep(i,24){
    if (!mustblack(now,all[now][i]))continue;

    ans[now]=all[now][i];
    if (solve(now+1,ans))return true;
  }
  return false;
}


bool solve(int r,int c){
  Dice in[8];
  Dice ans[8];
  int array[8]={0,1,2,3,4,5,6,7};
  getall(in,r,c);

  do{
    rep(i,8){
      generate(in[array[i]],all[i]);
    }
    rep(i,24){
      //output(all[0][i]);
      Dice a = all[0][i];
      //cout << a.right <<" " << a.back <<" " << a.bottom << endl;
    }
    //cout << endl;
    if (solve(0,ans))return true;
  }while(next_permutation(array+1,array+8));
  return false;
}

main(){
  int r,c;
  cin>>r>>c;
  rep(i,r)cin>>m[i];
  if (solve(r,c))cout <<"Yes"<<endl;
  else cout <<"No"<<endl;
}
accuracy: 1
time_ms: 180
memory_kb: 844
final_rank: 1