求全部原根的板子:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<string>
#include<queue>
#define ll long long
#define llu unsigned ll
#define int ll
using namespace std;
const int maxn=1001000;
int prime[maxn],pi[maxn],ans[maxn],cnt=0;
bool ha[maxn],vis[maxn];
int p[110],tot;
void Prime(void)
{
    ha[1]=true;
    pi[1]=1;
    for(int i=2;i<maxn;i++)
    {
        if(!ha[i]) prime[cnt++]=i,pi[i]=i-1;
        for(int j=0;j<cnt&&prime[j]*i<maxn;j++)
        {
            ha[i*prime[j]]=true;
            if(i%prime[j]==0)
            {
                pi[i*prime[j]]=pi[i]*prime[j];
                break;
            }
            pi[i*prime[j]]=pi[i]*pi[prime[j]];
        }
    }
    vis[2]=vis[4]=true;
    for(int i=1;i<cnt;i++)
    {
        for(int j=1;j*prime[i]<maxn;j*=prime[i])
        {
            vis[j*prime[i]]=true;
            if(2*j*prime[i]<maxn)
                vis[2*j*prime[i]]=true;
        }
    }

}

int gcd(int a,int b)
{
    if(b==0) return a;
    return gcd(b,a%b);
}

int mypow(int a,int b,int p)
{
    int ans=1;
    while(b)
    {
        if(b&1) ans=ans*a%p;
        a=a*a%p;
        b>>=1;
    }
    return ans;
}

void only(int n)
{
    tot=0;
    for(int i=0;i<cnt&&prime[i]*prime[i]<=n;i++)
    {
        if(n%prime[i]) continue;
        p[++tot]=prime[i];
        while(n%prime[i]==0) n/=prime[i];
    }
    if(n>1) p[++tot]=n;
}

bool check(int g,int n)
{
    if(mypow(g,pi[n],n)!=1) return false;
    for(int i=1;i<=tot;i++)
    {
        if(mypow(g,pi[n]/p[i],n)==1) return false;
    }
    return true;
}

int getmin(int n)
{
    int pm=2;
    while(1)
    {
        if(check(pm,n))
            break;
        pm++;
    }
    return pm;
}

void doit(int g,int n,int d)
{
    int cm=0;
    for(int i=1;i<=pi[n];i++)
    {
        if(gcd(i,pi[n])==1)
            ans[++cm]=mypow(g,i,n);
    }
    sort(ans+1,ans+cm+1);
    printf("%lld\n",cm);
    for(int i=1;i<=cm/d;i++)
        printf("%lld ",ans[i*d]);
    putchar('\n');

}

signed main(void)
{
    Prime();
    int t;
    scanf("%lld",&t);
    while(t--)
    {
        int n,d;
        scanf("%lld%lld",&n,&d);
        if(!vis[n])
        {
            printf("0\n\n");
            continue;
        }
        only(pi[n]);
        doit(getmin(n),n,d);
    }

    return 0;
}