#pragma GCC optimize("O3, unroll-loops, Ofast")
#include<bits/stdc++.h>
using namespace std;
#define pii pair<int,int>
#define int long long
#define tiii tuple<char,char,cg>
int mod = 998244353; 
vector<vector<vector<int32_t>>> cnt(8, vector<vector<int32_t>>(7, vector<int32_t>(7)));
vector<int> cur(8);
int pt;
int res = 0;
vector<pii> edges;
set<pii> edgesSet;
void gen(int n){
    if(n == 0){ 
        for(int l = 3; l <= 10; l++){
            int cp = 1;
            for(auto e : edges){
                int v =  cnt[l-3][cur[e.first]][cur[e.second]];
                cp *=v;
                cp %= mod;
                if(cp == 0) break;
            }
        
            res += cp;
            res %= mod;
        }
        return;
    }
    for(int i = 0; i < 7; i++){
        cur[pt++] = i;
        gen(n-1);
        cur[--pt] = 0;
    }   
}
int id(string& s){
    int r = 0;
    for(int i = 0; i < s.size(); i++){
        r += pow(7, i)*(s[i]-'a'+1);
    }
    return r;
}
int32_t main(){
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    int n;
    cin >> n;
    // vector<tiii> arr(n);
    set<int> occ;
    for(int i = 0; i < n; i++){
        string s;
        cin >> s;
        string r = s;
        reverse(r.begin(),r.end());
        // arr[i] = {s.size(), s[0]-'a', s.back()-'a'};
        if(occ.count(id(s))) continue;  
        occ.insert(id(r));
        char ind1 = s[0]-'a';
        char ind2 = s.back()-'a';
        cnt[s.size()-3][ind1][ind2]++;
    
        if(r != s){
            cnt[r.size()-3][r[0]-'a'][r.back()-'a']++;
        }
    }
    auto start = clock();
    for(int v = 0; v < 4; v++){
        auto ins = [&](int a, int b){
            if(a > b) swap(a,b);
            edgesSet.insert({a,b});
        };
        ins(v, (v+1)%4);
        ins(v, (v+3)%4);
        ins(v, v+4);
        ins(4+v, 4+((v+1)%4));
        ins(4+v, 4+((v+3)%4));
    }
    edges = vector<pii>(edgesSet.begin(),edgesSet.end());
    
    gen(8);
    
     
    cout << res << endl; 
    auto end = clock();
    cout << end - start << "ms elapsed" << endl;
}
Compilation message (stderr)
cubeword.cpp:1:47: warning: bad option '-f unroll-loops' to pragma 'optimize' [-Wpragmas]
    1 | #pragma GCC optimize("O3, unroll-loops, Ofast")
      |                                               ^
cubeword.cpp:1:47: warning: bad option '-f Ofast' to pragma 'optimize' [-Wpragmas]
cubeword.cpp:17:15: warning: bad option '-f unroll-loops' to attribute 'optimize' [-Wattributes]
   17 | void gen(int n){
      |               ^
cubeword.cpp:17:15: warning: bad option '-f Ofast' to attribute 'optimize' [-Wattributes]
cubeword.cpp:40:17: warning: bad option '-f unroll-loops' to attribute 'optimize' [-Wattributes]
   40 | int id(string& s){
      |                 ^
cubeword.cpp:40:17: warning: bad option '-f Ofast' to attribute 'optimize' [-Wattributes]
cubeword.cpp:48:14: warning: bad option '-f unroll-loops' to attribute 'optimize' [-Wattributes]
   48 | int32_t main(){
      |              ^
cubeword.cpp:48:14: warning: bad option '-f Ofast' to attribute 'optimize' [-Wattributes]
cubeword.cpp: In function 'int32_t main()':
cubeword.cpp:79:36: warning: bad option '-f unroll-loops' to attribute 'optimize' [-Wattributes]
   79 |         auto ins = [&](int a, int b){
      |                                    ^
cubeword.cpp:79:36: warning: bad option '-f Ofast' to attribute 'optimize' [-Wattributes]| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... |