func_code_string: #include <bits/stdc++.h>   using namespace std;   int dpo[2010][15], dpe[2010][15], a[2010], b[2010];   long long combe[15], combo[15];   long long f[2010], c[2010];   long long nck(long long n, long long k) {     if (n < k) return 0;     long long ret = (f[n] * c[k]) % 998244353;     return (ret * c[n - k]) % 998244353;   }   long long pwr(long long b, long long e) {     b %= 998244353;     if (e == 0) return 1;     if (e == 1) return b;     return (pwr(b * b, e / 2) * pwr(b, e % 2)) % 998244353;   }   int conv(string str) {     int dir = 1, ret = 0;     for (auto x : str) ret += dir * (x - 48), dir *= -1;     ret %= 11;     if (ret < 0) ret += 11;     return ret;   }   int main() {     ios_base::sync_with_stdio(false);     f[0] = c[0] = 1;     for (int i = 1; i < 2010; i++) (f[i] = f[i - 1] * i) %= 998244353;     c[2010 - 1] = pwr(f[2010 - 1], 998244353 - 2);     for (int i = 2010 - 2; i; i--) (c[i] = c[i + 1] * (i + 1)) %= 998244353;     int T;     cin >> T;     while (T--) {       int n;       string str;       int otot = 0, etot = 0, ocnt = 0, ecnt = 0;       cin >> n;       for (int i = 0; i < n; i++) {         cin >> str;         if (str.length() % 2)           a[ocnt++] = conv(str);         else           b[ecnt++] = conv(str);       }       etot = accumulate(b, b + ecnt, 0) % 11;       if (ocnt == 0) {         cout << (etot ? 0 : f[n]) << endl;         continue;       }       for (int i = 0; i <= ecnt; i++) fill(dpe[i], dpe[i] + 15, 0);       dpe[0][0] = 1;       for (int i = 0; i < ecnt; i++)         for (int j = i; j >= 0; j--)           for (int rem = 0; rem < 11; rem++)             (dpe[j + 1][(rem + b[i]) % 11] += dpe[j][rem]) %= 998244353;       fill(combe, combe + 11, 0);       for (int i = 0; i <= ecnt; i++) {         long long r = f[i] * f[ecnt - i] % 998244353 *                       nck(ocnt / 2 + i, ocnt / 2) % 998244353 *                       nck((ocnt + 1) / 2 - 1 + ecnt - i, (ocnt + 1) / 2 - 1) %                       998244353;         for (int rpos = 0; rpos < 11; rpos++) {           int rneg = (rpos - etot) % 11;           if (rneg < 0) rneg += 11;           (combe[(rpos + rneg) % 11] += r * dpe[i][rpos]) %= 998244353;         }       }       otot = accumulate(a, a + ocnt, 0) % 11;       for (int i = 0; i <= ocnt; i++) fill(dpo[i], dpo[i] + 15, 0);       dpo[0][0] = 1;       for (int i = 0; i < ocnt; i++)         for (int j = i; j >= 0; j--)           for (int rem = 0; rem < 11; rem++)             (dpo[j + 1][(rem + a[i]) % 11] += dpo[j][rem]) %= 998244353;       fill(combo, combo + 11, 0);       {         int i = (ocnt + 1) / 2;         long long r = f[i] * f[ocnt - i] % 998244353;         for (int rpos = 0; rpos < 11; rpos++) {           int rneg = (rpos - otot) % 11;           if (rneg < 0) rneg += 11;           (combo[(rpos + rneg) % 11] += r * dpo[i][rpos]) %= 998244353;         }       }       long long res = 0;       for (int i = 0; i < 11; i++)         (res += combo[i] * combe[(11 - i) % 11]) %= 998244353;       cout << res << endl;     }     return 0;   }   