This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include <bits/stdc++.h>
using namespace std;
const int M = 40;
const int MM = 20;
int g[55][55];
int f[(1 << MM) + 5];///1 daca masca asta e ok, 0 daca nu
int f2[(1 << MM) + 5];///cate supramasti sunt ok
int m;
void testcase()
{
    cin >> m;
    if (m == 0)
    {
        cout << 0 << '\n';
        return;
    }
    m++;
    for (int mask2 = 0; mask2 < (1 << MM); mask2++)
    {
        int mm = 0;
        for (int i = 0; i < MM; i++)
        {
            for (int j = i + 1; j < MM; j++)
            {
                if ((mask2 & (1 << i)) and (mask2 & (1 << j)))
                {
                    int gg = g[MM + 1 + i][MM + 1 + j];
                    mm |= (1 << (gg - 1));
                }
            }
        }
        if (m > f2[mm])
            m -= f2[mm];
        else
        {
            for (int mask = 0; mask < (1 << MM); mask++)
            {
                if ((mm & mask) == mm and f[mask] == 1)
                {
                    m--;
                    if (m == 0)
                    {
                        vector<int> v;
                        for (int i = 0; i < MM; i++)
                            if (mask & (1 << i))
                                v.push_back(i + 1);
                        for (int i = 0; i < MM; i++)
                            if (mask2 & (1 << i))
                                v.push_back(MM + 1 + i);
                        cout << v.size() << ' ';
                        for (auto it : v)
                            cout << it << ' ';
                        cout << '\n';
                        return;
                    }
                }
            }
        }
    }
}
int main()
{
    for (int i = 1; i <= 50; i++)
        for (int j = 1; j <= 50; j++)
            g[i][j] = __gcd(i, j);
    for (int mask = 0; mask < (1 << MM); mask++)
    {
        bool nah = false;
        for (int i = 0; i < MM; i++)
        {
            for (int j = 0; j < MM; j++)
            {
                if ((mask & (1 << i)) and (mask & (1 << j)))
                {
                    if (!(mask & (1 << (g[i + 1][j + 1] - 1))))
                        nah = true;
                }
            }
        }
        if (!nah)
            f[mask] = 1;
    }
    for (int i = 0; i < (1 << MM); i++)
        f2[i] = f[i];
    for (int i = 0; i < MM; i++)
    {
        for (int j = 0; j < (1 << MM); j++)
        {
            if (!(j & (1 << i)))
                f2[j] += f2[j + (1 << i)];
        }
    }
    int tc;
    cin >> tc;
    while (tc--)
        testcase();
    return 0;
}
/**
maximul <= M (M <= 44 sigur, probabil considerabil mai putin dar idk)
Aleg brut pe care din ultimele M / 2 le folosesc, direct ele isi vor genera un set
Acum vreau sa vad: din primele M / 2, cate seturi valide am care si includ setul impus de alea mari?
Sounds like SOS
Acum ca am gasit exact ce masca voi avea din ultimele M / 2, doar dau brut prin alea mici
Ar trebui sa fie vreo 2^(M / 2) * M sau cv
**/
| # | 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... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... |