#include <bits/stdc++.h>

namespace Oct {

template <typename Type, Type P, typename MulType>
class ModInt {
   protected:
    Type x;

   public:
    inline ModInt() : x(0) {}
    inline ModInt(Type a) : x(a) {}
    explicit inline operator Type() { return x; }
    friend inline ModInt operator+(ModInt a, ModInt b) { return (a.x += b.x) >= P ? a.x - P : a.x; }
    friend inline ModInt operator-(ModInt a, ModInt b) { return (a.x -= b.x) < 0 ? a.x + P : a.x; }
    friend inline ModInt operator*(ModInt a, ModInt b) { return MulType(a.x) * b.x % P; }
    friend inline ModInt &operator+=(ModInt &a, ModInt b) { return (a.x += b.x) >= P ? a.x -= P, a : a; }
    friend inline ModInt &operator-=(ModInt &a, ModInt b) { return (a.x -= b.x) < 0 ? a.x += P, a : a; }
    friend inline ModInt &operator*=(ModInt &a, ModInt b) { return a.x = MulType(a.x) * b.x % P, a; }
    #define templ template <typename ExpType>
    templ inline ModInt Pow(ExpType Exp) {
        ModInt Base(x), Ret(1);
        while (Exp) {
            if (Exp & 1) Ret *= Base;
            Base *= Base, Exp >>= 1;
        }
        return Ret;
    }
    templ friend inline ModInt Pow(ModInt Base, ExpType Exp) { return Base.Pow(Exp); }
    #undef templ
    inline ModInt Inv() { return Pow(P - 2); }
    friend inline ModInt Inv(ModInt a) { return a.Inv(); }
    friend inline ModInt operator~(ModInt a) { return a.Inv(); }
    friend inline ModInt operator/(ModInt a, ModInt b) { return a * ~b; }
    friend inline ModInt &operator/=(ModInt &a, ModInt b) { return a *= ~b; }
};

} // namespace Oct

using int64 = long long;

using MInt = Oct::ModInt<int, 998244353, int64>;

struct Node {
    int Po;
    MInt Nu;
    inline Node() : Po(0), Nu(0) {}
    inline Node(int P, MInt N) : Po(P), Nu(N) {}
};

inline Node operator+(Node a, int x) { return Node(a.Po + x, a.Nu); }

inline Node operator+(Node a, Node b) {
    if (a.Po == b.Po) return Node(a.Po, a.Nu + b.Nu);
    return a.Po > b.Po ? a : b;
}

const int C = 15;
const int N = 1 << C;

int T, a, b, c;

Node f1[N], f2[N], *f = f1, *g = f2;

std::vector<int> Bi[N];

inline bool Check(int x) { return !(x & (x >> 1)); }

inline std::string BiInt(int x) {
    std::string Str;
    for (int i = 0; i < 7; ++i) Str += char('0' + ((x >> i) & 1));
    return Str;
}

int main() {
    freopen("geometry.in", "r", stdin);
    freopen("geometry.out", "w", stdout);
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr), std::cout.tie(nullptr);
    for (int i = 0; i < N; ++i) {
        Bi[i].resize(1 << __builtin_popcount(i));
        int *Ii = &*Bi[i].begin(), n = 1, m = 1;
        for (int u = i & -i, t = i; t; t ^= u, u = t & -t, n = m) {
            for (int j = 0; j < n; ++j) {
                if (Check(Ii[j] | u)) Ii[m++] = Ii[j] | u;
            }
        }
        Bi[i].resize(n);
    }
    std::cin >> T;
    while (T--) {
        std::cin >> a >> b >> c;
        int n = a * 4 - 1, m = b * 4 - 1;
        int al = -2 * a + 1, ar = 2 * a - 1;
        int bl = -2 * b + 1, br = 2 * b - 1;
        int cl = -2 * c + 1, cr = 2 * c - 1;
        memset(f, 0, sizeof(Node) * (1 << n));
        f[0] = Node(0, 1);
        int U = 0, rU = 0;
        for (int i = bl; i <= br; ++i) {
            rU = U, U = 0;
            for (int j = al; j <= ar; ++j) {
                U |= (((i & 1) | (j & 1)) && i + j >= cl && i + j <= cr) << j - al;
            }
            memset(g, 0, sizeof(Node) * (1 << n));
            for (int *Bj = &*Bi[rU].begin(), J = Bi[rU].size(), cj = 0; cj < J; ++cj) {
                int j = Bj[cj];
                if (!int(f[j].Nu)) continue;
                int V = ~(j | j >> 1) & U;
                for (int *B = &*Bi[V].begin(), K = Bi[V].size(), k = 0; k < K; ++k) {
                    g[B[k]] = g[B[k]] + (f[j] + __builtin_popcount(B[k]));
                }
            }
            std::swap(f, g);
        }
        Node Ans;
        for (int *Bj = &*Bi[U].begin(), J = Bi[U].size(), cj = 0; cj < J; ++cj) Ans = Ans + f[Bj[cj]];
        std::cout << Ans.Po << ' ' << int(Ans.Nu) << std::endl;
    }
    return 0;
}