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

//======================
//
// Template OleschY
//
// Die M�glichkeiten der deutschen Grammatik k�nnen
// einen, wenn man sich darauf, was man ruhig, wenn
// man m�chte, sollte, einl�sst, �berraschen.
// - @Gedankenbalsam
//
//======================

//======================
//      Output/Debug
//======================

template <typename T>
ostream& operator<<(ostream& os, const vector<T>& v)
{
    os << "[";
    for (int i = 0; i < v.size(); ++i)
    {
        os << v[i];
        if (i != v.size() - 1)
            os << ", ";
    }
    os << "]\n";
    return os;
}

template <typename T, typename U>
ostream& operator<<(ostream& os, const pair<T, U>& p)
{
    os << "[";
    os << p.first;
    os << ", ";
    os << p.second;
    os << "]";
    return os;
}

#ifndef ONLINE_JUDGE
#define debug(x) cout << (#x) << " is " << (x) << endl
#else
#define debug(...) 42
#endif

//======================
//      MODULE
//======================
struct ModInt;
vector<ModInt> inverse();

using ModType = long long; // set Type. Cann multiply ints if using long long.
struct ModInt
{
    static inline vector<ModInt> precalcInverse;
    static void precalc()
    {
        precalcInverse = inverse();
    }

    static inline ModType mod = 998244353; // Set this value
    ModType val;
    ModInt(ModType v = 0) : val(v % mod) { }
    static void setMod(ModType m)
    {
        mod = m;
        if(precalcInverse.size() > 0)
        {
            precalcInverse = inverse();
        }
    }
    ModInt &operator+=(ModInt a)
    {
        if ((val += a.val) >= mod) val -= mod;
        return *this;
    }
    ModInt &operator-=(ModInt a)
    {
        if ((val -= a.val) < 0) val += mod;
        return *this;
    }
    ModInt &operator*=(ModInt a)
    {
        val = (val * a.val) % mod;
        return *this;
    }
    ModInt &operator/=(ModInt a)
    {
        if(precalcInverse.size() > a.val)
        {
            *this *= precalcInverse[a.val];
            return *this;
        }
        ModType u = 1, v = a.val, s = 0, t = mod;
        while (v)
        {
            ModType q = t / v;
            swap(s -= u * q, u);
            swap(t -= v * q, v);
        }
        a.val = (s < 0 ? s + mod : s);
        val /= t;
        return (*this) *= a;
    }
    ModInt inv() const
    {
        return ModInt(1) /= (*this);
    }
    bool operator<(ModInt x) const
    {
        return val < x.val;
    }
};
ostream &operator<<(ostream &os, ModInt a)
{
    os << a.val;
    return os;
}
ModInt operator+(ModInt a, ModInt b)
{
    return a += b;
}
ModInt operator-(ModInt a, ModInt b)
{
    return a -= b;
}
ModInt operator*(ModInt a, ModInt b)
{
    return a *= b;
}
ModInt operator/(ModInt a, ModInt b)
{
    return a /= b;
}
ModInt pow(ModInt a, ModType e)
{
    ModInt x(1);
    for (; e > 0; e /= 2)
    {
        if (e % 2 == 1) x *= a;
        a *= a;
    }
    return x;
}
// compute inv[1], inv[2], ..., inv[mod-1] in O(n) time
vector<ModInt> inverse()
{
    ModType mod = ModInt::mod;
    vector<ModInt> inv(mod);
    inv[1].val = 1;
    for (ModType a = 2; a < mod; ++a)
        inv[a] = inv[mod % a] * ModInt(mod - mod / a);
    return inv;
}
ModInt stringToModInt(string s)
{
    ModType val = 0;
    for (int i = 0; i < s.size(); ++i)
        val = (val * 10 + (s[i] - '0')) % ModInt::mod;
    return ModInt(val);
}

//======================
// Solution Single testcase
//======================

int n;
vector<vector<int>> num; // array, column
vector<vector<int>> cnt; // column, number
vector<bool> chosen;
int nchosen;
vector<int> ans;
int anscomb;

void remrow(int row)
{
    if(chosen[row])
        return;
    chosen[row] = true;
    nchosen++;
    for(int col = 0; col < n; ++col)
    {
        cnt[col][num[row][col]]--;
    }
}


void choose(int row)
{
    ans.push_back(row);
    remrow(row);
    for(int row2 = 0; row2 < 2 * n; ++row2)
    {
        for(int col = 0; col < n; ++col)
        {
            if(num[row][col] == num[row2][col])
            {
                remrow(row2);
                break;
            }
        }
    }
}

void choose(int col, int val)
{
    for(int row = 0; row < 2 * n; row++)
    {
        if(chosen[row])
            continue;
        if(num[row][col] == val)
        {
            choose(row);
            break;
        }
    }

}


int solve()
{
    cin >> n;
    ans.clear();
    anscomb = 0;
    nchosen = 0;
    num.clear();
    cnt.clear();
    chosen.clear();
    num.resize(2 * n, vector<int>(n)); // array, column
    cnt.resize(n, vector<int>(n, 0)); // column, number
    chosen.resize(2 * n, false);
    for(int i = 0; i < 2 * n; ++i)
    {
        for(int j = 0; j < n; ++j)
        {
            cin >> num[i][j];
            num[i][j]--;
            cnt[j][num[i][j]]++;
        }
    }
    ModInt comb = 1;
    while(true)
    {
        bool found = false;;
        for(int col = 0; col < n; ++col)
        {
            for(int val = 0; val < n; ++val)
            {
                if(cnt[col][val] == 1)
                {
                    choose(col, val);
                    found = true;
                }
            }
        }
        if(nchosen == 2 * n)
        {
            break;
        }
        if(!found)
        {
            for(int row = 0; row < 2 * n; ++row)
            {
                if(!chosen[row])
                {
                    choose(row);
                    comb *= 2;
                    break;
                }
            }
        }
        if(nchosen == 2 * n)
        {
            break;
        }
    }

    debug(ans);
    cout << comb << "\n";
    for(int i = 0; i < n; i++)
    {
        cout << ans[i] + 1 << " ";
    }
    cout << "\n";
    return 0;
}

//======================
// Technical stuff
//======================

int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    //freopen("a.out","w",stdout); // console output is better (in most cases)
#else
    // add i/o method of specific testing system
#endif
    int ntest = 1;
    cin >> ntest;
    for(int test = 0; test < ntest; ++test)
    {
        solve();
    }
    return 0;
}
