stablegradients/pie-gem5-pairs huggingface dataset:
// Slower C++ solution:
#include<iostream>

#include<cstdio>

#include<cstdlib>

#include<cstring>

#include<algorithm>

using namespace std;



#define ll long long

#define mem(Arr,x) memset(Arr,x,sizeof(Arr))



const int maxN=320;

const int Mod=1e9+7;

const int inf=2147483647;



int n,D[maxN];

int F[maxN][maxN][2];

int Fac[maxN],Ifc[maxN];



int QPow(int x,int cnt);



int main(){

	Fac[0]=Ifc[0]=1;for (int i=1;i<maxN;i++) Fac[i]=1ll*Fac[i-1]*i%Mod;

	Ifc[maxN-1]=QPow(Fac[maxN-1],Mod-2);for (int i=maxN-2;i>=1;i--) Ifc[i]=1ll*Ifc[i+1]*(i+1)%Mod;

	bool fullring=1;

	scanf("%d",&n);for (int i=1;i<=n;i++) scanf("%d",&D[i]),fullring&=(D[i]==2);

	if (fullring){

		printf("%lld\n",1ll*Fac[n-1]*Ifc[2]%Mod);return 0;

	}

	F[0][0][0]=1;

	for (int i=1;i<=n;i++)

		for (int j=0;j<=i;j++)

			for (int k=0;k<=1;k++){

				F[i][j][k]=F[i-1][j][k];

				if ((D[i]>=2)&&(j>0)) F[i][j][k]=(1ll*F[i-1][j-1][k]*(D[i]-1)%Mod+F[i][j][k])%Mod;

				if ((D[i]>=3)&&(j>0)&&(k==1)) F[i][j][k]=(1ll*F[i-1][j-1][0]*(D[i]-1)%Mod*(D[i]-2)%Mod+F[i][j][k])%Mod;

			}

	int Ans=0;

	//for (int i=1;i<=n;i++) cout<<F[n][i][1]<<" ";cout<<endl;

	for (int i=3;i<=n;i++) Ans=(Ans+1ll*F[n][i][1]*Fac[i-1]%Mod*Ifc[2]%Mod*Fac[n-i-1]%Mod)%Mod;

	for (int i=1;i<=n;i++) Ans=1ll*Ans*Ifc[D[i]-1]%Mod;

	printf("%d\n",Ans);return 0;

}



int QPow(int x,int cnt){

	int ret=1;

	while (cnt){

		if (cnt&1) ret=1ll*ret*x%Mod;

		x=1ll*x*x%Mod;cnt>>=1;

	}

	return ret;

}


// Faster C++ solution for the same problem (measured speedup: 5.10563582750357x):
/*

考虑建立虚拟根 R 以后造 prufer 序列（和3776一样）

前 n-s-1 位随便，第 n-s 位是根节点，第 n-s+1 ~ n-1 位都是 R。

直接 dp 一下每个点的决策：

1、不作为根

2、作为根但是不填到 n-s 位去。 

3、作为根且搞定第 n-s 位。 

*/

#include<cstdio>



const int N = 5004, mod = 1000000007;



int n, ans, inv[N], fac[N], ifac[N], F[N][2];



int main()

{

	scanf("%d", &n);

	fac[0] = fac[1] = ifac[0] = ifac[1] = inv[1] = 1;

	for(int i = 2; i <= n; ++i)

	{

		fac[i] = 1ll * i * fac[i - 1] % mod;

		inv[i] = 1ll * (mod - mod / i) * inv[mod % i] % mod;

		ifac[i] = 1ll * ifac[i - 1] * inv[i] % mod;

	}

	F[0][0] = 1;

	for(int i = 1, d; i <= n; ++i)

	{

		scanf("%d", &d);

		for(int j = i - 1; ~j; --j)

		{

			if(d >= 2)

				F[j + 1][0] = (F[j + 1][0] + 1ll * F[j][0] * ifac[d - 2]) % mod,

				F[j + 1][1] = (F[j + 1][1] + 1ll * F[j][1] * ifac[d - 2]) % mod;

			if(d >= 3)

				F[j + 1][1] = (F[j + 1][1] + 1ll * F[j][0] * ifac[d - 3]) % mod;

			F[j][0] = 1ll * F[j][0] * ifac[d - 1] % mod;

			F[j][1] = 1ll * F[j][1] * ifac[d - 1] % mod;

		}

	}

	if(!F[1][1])

		ans = 1ll * fac[n - 1] * inv[2] % mod;

	else for(int j = 3; j < n; ++j)

		ans = (ans + 1ll * F[j][1] * fac[n - j - 1] % mod * fac[j - 1] % mod * inv[2]) % mod;

	printf("%d", ans);

	return 0;

}
// Slower C++ solution:
#include<cstdio>

#include<cstring>

#include<iostream>

#include<algorithm>

#define N 1000010

#define int long long

#define mxf(x,y) (x>y?x:y)

#define mif(x,y) (x<y?x:y)

#define rep(i,x,y) for(register int i=x;i<=y;++i)

#define dwn(i,x,y) for(register int i=x;i>=y;--i)

using namespace std;

int n,m,aor,bor,ans,num,a[N],aa[N],b[N],bb[N],fa[N],date[N];

inline int read(){

	int fl=1,sum=0;char w=getchar();

	while(w>'9'||w<'0'){if(w=='-')fl=-1;w=getchar();}

	while(w>='0'&&w<='9'){sum=sum*10+w-'0';w=getchar();}

	return fl*sum;

}

inline int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}

inline void merge(int x,int y){fa[find(x)]=find(y);}

signed main(){

//	freopen("duliu.in","r",stdin);

//	freopen("duliu.out","w",stdout);

	n=read();

	rep(i,1,n) a[i]=read(),aa[i]=a[i],aor^=a[i];

	rep(i,1,n) b[i]=read(),bb[i]=b[i],bor^=b[i];

	n++;a[n]=aa[n]=aor,b[n]=bb[n]=bor;

    sort(aa+1,aa+n+1);sort(bb+1,bb+n+1);

    rep(i,1,n-1) if(aa[i]!=bb[i]){puts("-1");return 0;}

    rep(i,1,n) if(a[i]!=b[i]||(i==n)){

        date[++num]=a[i];date[++num]=b[i];

        if(i<n) ans++;

    }

    if(!ans){puts("0");return 0;}

    sort(date+1,date+num+1);

    num=unique(date+1,date+num+1)-date-1;

    rep(i,1,num) fa[i]=i;

    rep(i,1,n) if(a[i]!=b[i]){

        a[i]=lower_bound(date+1,date+num+1,a[i])-date,

        b[i]=lower_bound(date+1,date+num+1,b[i])-date;

        merge(a[i],b[i]);

    }

    rep(i,1,num) if(fa[i]==i) ans++;

    printf("%lld",ans-1);

	return 0;

}

// Faster C++ solution for the same problem (measured speedup: 5.1822080302524265x):
#include<cstdio>

#include<algorithm>

using namespace std;



int a[100009],b[100009],c[100009],fa[100009],va[100009]={0},cva[100009]={0},cvb[100009]={0},xore=0;

bool is[100009]={0},vis=0;



int gf(int u){

	if(fa[u]==u){return u;}

	va[fa[u]]+=va[u];va[u]=0;

	return fa[u]=gf(fa[u]);

}



int main(){

	int n,res=0,tot,apos,bpos;

	scanf("%d",&n);

	for(int i=1;i<=n;i=-(~i)){scanf("%d",&a[i]);c[i]=a[i];xore^=a[i];}	

	sort(c+1,c+1+n);tot=unique(c+1,c+1+n)-c-1;

	for(int i=1;i<=tot;i=-(~i)){fa[i]=i;}fa[tot+1]=tot+1;

	for(int i=1;i<=n;i=-(~i)){

		scanf("%d",&b[i]);

		if(a[i]==b[i]){continue;}

		apos=lower_bound(c+1,c+1+tot,a[i])-c;

		bpos=lower_bound(c+1,c+1+tot,b[i])-c;

		if(c[bpos]!=b[i]){

			if(vis||b[i]!=xore){printf("-1\n");return 0;}

			else{vis=true;res--;bpos=tot+1;}//本质 xore 不参与离散化，也不参与并查集统计

		}

		cva[apos]++;cvb[bpos]++;

//		fprintf(stdout,"%d[%d:%d %d[%d:%d %d %d\n",a[i],c[apos],apos,b[i],c[bpos],bpos,tot,xore);

		if(gf(apos)!=gf(bpos)){va[fa[apos]]+=va[fa[bpos]];va[fa[bpos]]=0;fa[fa[bpos]]=fa[apos];}//注意顺序

		va[fa[bpos]]++;

	}

	for(int i=1;i<=tot;i=-(~i)){

		gf(i);

		if(c[i]==xore){vis=true;res--;cvb[i]--;}

		//不能直接用vis判断

		if(cva[i]<cvb[i]){printf("-1\n");return 0;}

	}

	for(int i=1;i<=tot;i=-(~i)){

		if(va[i]){res+=va[i]+1;}//fprintf(stdout,"%d:%d\n",c[i],va[i]+1);}

	}

	printf("%d\n",((res<0)?0:res));

	return 0;

}
// Slower C++ solution:
#include<algorithm>

#include<cstdio>

#include<queue>

#include<iostream>

#include<stack>

#include<cstring>

using namespace std;



inline int read(){

	int fl=1,sum=0;char w=getchar();

	while(w>'9'||w<'0'){if(w=='-')fl=-1;w=getchar();}

	while(w>='0'&&w<='9'){sum=(sum*10)+(w^48);w=getchar();}

	return fl*sum;

}

const int N=100010;

int n,now,ans,cnt;

int fa[N];

struct nod{

	int num,id;

}a[N],b[N];

bool cmp(nod x,nod y){return x.num<y.num;}

bool cmp2(nod x,nod y){return x.id<y.id;}

bool vis[N],fl;

int find(int x){if(x==fa[x])return x;return fa[x]=find(fa[x]);}

int main()

{

	//freopen("duliu.in","r",stdin);

	//freopen("duliu.out","w",stdout);

	n=read();

	for(int i=1;i<=n;i++)a[i].num=read(),a[n+1].num=a[n+1].num^a[i].num,a[i].id=i;

	for(int j=1;j<=n;j++)b[j].num=read(),b[n+1].num=b[n+1].num^b[j].num,b[j].id=j;

	n++;now=-1;a[n].id=b[n].id=n;

	sort(a+1,a+n+1,cmp);sort(b+1,b+n+1,cmp);

	for(int i=1;i<=n;i++)

	{;

		if(a[i].num!=b[i].num){fl=1;break;}

		if(a[i].num!=now)

		{

			now=a[i].num;

			a[i].num=b[i].num=++cnt;

		}else a[i].num=b[i].num=cnt;

	}

	if(fl){printf("-1\n");return 0;}

	sort(a+1,a+n+1,cmp2);sort(b+1,b+n+1,cmp2);

	for(int i=1;i<=cnt;i++)fa[i]=i;

	for(int i=1;i<=n;i++)

	{

		if(b[i].num!=a[i].num||i==n){

			if(i!=n)ans++;

			fa[find(b[i].num)]=find(a[i].num);

			vis[a[i].num]=1;vis[b[i].num]=1;

		}

	}

	for(int i=1;i<=cnt;i++)if(vis[i]&&fa[i]==i)ans++;

	ans--;cout<<ans<<endl;

	return 0;

}

// Faster C++ solution for the same problem (measured speedup: 5.23038867232295x):
#include<cstdio>

#include<algorithm>

using namespace std;



int a[100009],b[100009],c[100009],fa[100009],va[100009]={0},cva[100009]={0},cvb[100009]={0},xore=0;

bool is[100009]={0},vis=0;



int gf(int u){

	if(fa[u]==u){return u;}

	va[fa[u]]+=va[u];va[u]=0;

	return fa[u]=gf(fa[u]);

}



int main(){

	int n,res=0,tot,apos,bpos;

	scanf("%d",&n);

	for(int i=1;i<=n;i=-(~i)){scanf("%d",&a[i]);c[i]=a[i];xore^=a[i];}	

	sort(c+1,c+1+n);tot=unique(c+1,c+1+n)-c-1;

	for(int i=1;i<=tot;i=-(~i)){fa[i]=i;}fa[tot+1]=tot+1;

	for(int i=1;i<=n;i=-(~i)){

		scanf("%d",&b[i]);

		if(a[i]==b[i]){continue;}

		apos=lower_bound(c+1,c+1+tot,a[i])-c;

		bpos=lower_bound(c+1,c+1+tot,b[i])-c;

		if(c[bpos]!=b[i]){

			if(vis||b[i]!=xore){printf("-1\n");return 0;}

			else{vis=true;res--;bpos=tot+1;}//本质 xore 不参与离散化，也不参与并查集统计

		}

		cva[apos]++;cvb[bpos]++;

//		fprintf(stdout,"%d[%d:%d %d[%d:%d %d %d\n",a[i],c[apos],apos,b[i],c[bpos],bpos,tot,xore);

		if(gf(apos)!=gf(bpos)){va[fa[apos]]+=va[fa[bpos]];va[fa[bpos]]=0;fa[fa[bpos]]=fa[apos];}//注意顺序

		va[fa[bpos]]++;

	}

	for(int i=1;i<=tot;i=-(~i)){

		gf(i);

		if(c[i]==xore){vis=true;res--;cvb[i]--;}

		//不能直接用vis判断

		if(cva[i]<cvb[i]){printf("-1\n");return 0;}

	}

	for(int i=1;i<=tot;i=-(~i)){

		if(va[i]){res+=va[i]+1;}//fprintf(stdout,"%d:%d\n",c[i],va[i]+1);}

	}

	printf("%d\n",((res<0)?0:res));

	return 0;

}
// Slower C++ solution:
#include<cstdio>

#include<cmath>

#include<algorithm>

#include<cstring>

#include<queue>

#include<iostream>

#include<map>

#define ll long long

#define rint register int

#define in inline

using namespace std;

int n,a[100010],b[100010],tot,cnt[100010],fa[100010],ans; 

map<int,int> f;//离散化 

in ll read()

{

    ll x=0,f=1; char ch=getchar();

    while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar(); }

    while(ch>='0'&&ch<='9') { x=x*10+ch-'0'; ch=getchar(); }

    return x*f;

}

in int find(int x){ return x==fa[x]?x:fa[x]=find(fa[x]); }

in void merge(int x,int y)

{

    int fx=find(x),fy=find(y);

    if(fx!=fy) fa[fx]=fy;

}

int main()

{

    n=read();

    for(rint i=1;i<=n;i++) a[i]=read(),a[n+1]^=a[i];

    for(rint i=1;i<=n;i++) b[i]=read(),b[n+1]^=b[i];

    n++;

    for(rint i=1;i<=n;i++)

        if(a[i]!=b[i]||i==n) //n其实是n+1 需要特判 

        {

            if(!f[a[i]]) f[a[i]]=++tot;

            cnt[f[a[i]]]++;

        }

    for(rint i=1;i<=n;i++)

        if(a[i]!=b[i]||i==n) 

            cnt[f[b[i]]]--;

    for(rint i=0;i<=tot;i++) if(cnt[i]) { printf("-1"); return 0; }//从0开始枚举是为了避免b中出现a中没有的数

    for(rint i=1;i<=tot;i++) fa[i]=i;//并查集 

    for(rint i=1;i<=n;i++) a[i]=f[a[i]],b[i]=f[b[i]];

    for(rint i=1;i<=n;i++)

        if(a[i]!=b[i]) 

        {

            if(i<n) ans++;//最后一个点要单独处理 因为不需要连到b[n+1] 连一条边操作就多一次 

            merge(a[i],b[i]);

        }

    for(rint i=1;i<=tot;i++) if(find(i)==i) ans++;//有多少个环 就要在环之间连多少边-1

    if(ans) printf("%d",ans-1);

    return 0;

}

// Faster C++ solution for the same problem (measured speedup: 5.249763510834216x):
#include<cstdio>

#include<algorithm>

using namespace std;



int a[100009],b[100009],c[100009],fa[100009],va[100009]={0},cva[100009]={0},cvb[100009]={0},xore=0;

bool is[100009]={0},vis=0;



int gf(int u){

	if(fa[u]==u){return u;}

	va[fa[u]]+=va[u];va[u]=0;

	return fa[u]=gf(fa[u]);

}



int main(){

	int n,res=0,tot,apos,bpos;

	scanf("%d",&n);

	for(int i=1;i<=n;i=-(~i)){scanf("%d",&a[i]);c[i]=a[i];xore^=a[i];}	

	sort(c+1,c+1+n);tot=unique(c+1,c+1+n)-c-1;

	for(int i=1;i<=tot;i=-(~i)){fa[i]=i;}fa[tot+1]=tot+1;

	for(int i=1;i<=n;i=-(~i)){

		scanf("%d",&b[i]);

		if(a[i]==b[i]){continue;}

		apos=lower_bound(c+1,c+1+tot,a[i])-c;

		bpos=lower_bound(c+1,c+1+tot,b[i])-c;

		if(c[bpos]!=b[i]){

			if(vis||b[i]!=xore){printf("-1\n");return 0;}

			else{vis=true;res--;bpos=tot+1;}//本质 xore 不参与离散化，也不参与并查集统计

		}

		cva[apos]++;cvb[bpos]++;

//		fprintf(stdout,"%d[%d:%d %d[%d:%d %d %d\n",a[i],c[apos],apos,b[i],c[bpos],bpos,tot,xore);

		if(gf(apos)!=gf(bpos)){va[fa[apos]]+=va[fa[bpos]];va[fa[bpos]]=0;fa[fa[bpos]]=fa[apos];}//注意顺序

		va[fa[bpos]]++;

	}

	for(int i=1;i<=tot;i=-(~i)){

		gf(i);

		if(c[i]==xore){vis=true;res--;cvb[i]--;}

		//不能直接用vis判断

		if(cva[i]<cvb[i]){printf("-1\n");return 0;}

	}

	for(int i=1;i<=tot;i=-(~i)){

		if(va[i]){res+=va[i]+1;}//fprintf(stdout,"%d:%d\n",c[i],va[i]+1);}

	}

	printf("%d\n",((res<0)?0:res));

	return 0;

}
// Slower C++ solution:
#include<bits/stdc++.h>

#define For(i,l,r) for(int i=l;i<=r;i++)

#define ll long long

using namespace std;

const int M=1e5+5;

int n,a[M],b[M],x[M],y[M],vis[M],cnt,ans;

map<int,int>d;

vector<int>Q[M];

inline int read(){

	int f=1,sum=0;

	char ch=getchar();

	while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}

	while(isdigit(ch)){sum=(sum<<1)+(sum<<3)+(ch^48);ch=getchar();}

	return f*sum; 

}

inline void dfs(int x){

	vis[x]=1;

	For(i,0,Q[x].size()-1){

		if(!vis[Q[x][i]]){

			dfs(Q[x][i]);

		}

	}

}

int main(){

	n=read();

	For(i,1,n){

		a[i]=read();a[n+1]^=a[i];

	    if(!d[a[i]]) d[a[i]]=++cnt;

	}

	if(!d[a[n+1]]) d[a[n+1]]=++cnt;

	For(i,1,n){

		b[i]=read();b[n+1]^=b[i];

		if(!d[b[i]]) d[b[i]]=++cnt;

	}

	if(!d[b[n+1]]) d[b[n+1]]=++cnt;

	memcpy(x,a,sizeof(x));memcpy(y,b,sizeof(y));

	sort(x+1,x+n+2);sort(y+1,y+n+2);

	For(i,1,n) if(x[i]!=y[i]){printf("-1");return 0;}

	For(i,1,n+1) a[i]=d[a[i]],b[i]=d[b[i]];

	For(i,1,n) if(a[i]!=b[i]) ans++,Q[a[i]].push_back(b[i]);

	if(a[n+1]!=b[n+1]) Q[a[n+1]].push_back(b[n+1]); 

	For(i,1,cnt-1) if(Q[i].size()&&!vis[i]) dfs(i),ans++;

	if(!vis[cnt]) ans++;

	printf("%d",ans-1);

	return 0;

}

// Faster C++ solution for the same problem (measured speedup: 5.253771574284823x):
#include<bits/stdc++.h>

#define int long long

using namespace std;

const int N=4e5+10;

int a[N],b[N];

int ta[N],tb[N];

int dp[N],fa[N];

int n,m,ans;

int find(int x){

	return fa[x]==x?x:fa[x]=find(fa[x]);

}

signed main(){

	scanf("%lld",&n);

	for(int i=1;i<=n;++i){

		scanf("%lld",&a[i]);

		a[n+1]^=a[i];

		ta[i]=a[i];

	}

	for(int i=1;i<=n;++i){

		scanf("%lld",&b[i]);

		b[n+1]^=b[i];

		tb[i]=b[i];

	}

	++n;

	ta[n]=a[n];tb[n]=b[n];

	sort(ta+1,ta+n+1);sort(tb+1,tb+n+1);

	for(int i=1;i<n;++i)

		if(ta[i]!=tb[i]){

			printf("-1");

			return 0;

		}

	for(int i=1;i<=n;++i) 

		if(a[i]!=b[i]||i==n){

			dp[++m]=a[i];

			dp[++m]=b[i];

			if(i<n)++ans;

		}

	if(!ans){

		printf("0");

		return 0;

	}

	sort(dp+1,dp+m+1);

	m=unique(dp+1,dp+m+1)-dp-1;

	for(int i=1;i<=m;++i)

		fa[i]=i;

	for(int i=1;i<=n;++i)

		if(a[i]!=b[i]){

			a[i]=lower_bound(dp+1,dp+m+1,a[i])-dp,

			b[i]=lower_bound(dp+1,dp+m+1,b[i])-dp;

			fa[find(a[i])]=find(b[i]);

		}

	for(int i=1;i<=m;++i)

		if(fa[i]==i)

			++ans;

	printf("%lld",ans-1);

	return 0;

}
// Slower C++ solution:
#include <cstdio>

#include <iostream>

#include <cstring>

#include <algorithm> 

#include <vector>

#include <map>

#define N 100010

using namespace std;

vector<int>Q[N];

map<int,int>d;

bool vis[N];

int n,a[N],b[N],x[N],y[N],cnt,ans;

void dfs(int x){

    vis[x]=1;

    for (int i=0;i<Q[x].size();i++) if (!vis[Q[x][i]]) dfs(Q[x][i]);

}

int main(){

    scanf("%d",&n);



    for(int i=1;i<=n;i++){

        scanf("%d",&a[i]),a[n+1]^=a[i];

        if(!d[a[i]]) d[a[i]]=++cnt;

    }



    if(!d[a[n+1]]) d[a[n+1]]=++cnt;



    for(int i=1;i<=n;i++){

        scanf("%d",&b[i]),b[n+1]^=b[i];

        if(!d[b[i]]) d[b[i]]=++cnt;

    }



    if(!d[b[n+1]]) d[b[n+1]]=++cnt;



    memcpy(x,a,sizeof x),memcpy(y,b,sizeof y);



    sort(x+1,x+n+2),sort(y+1,y+n+2);



    for(int i=1;i<=n;i++) if(x[i]!=y[i]) {printf("-1");return 0;}



    for(int i=1;i<=n+1;i++) a[i]=d[a[i]],b[i]=d[b[i]];



    for(int i=1;i<=n;i++) if(a[i]!=b[i]) ans++,Q[a[i]].push_back(b[i]);



    if(a[n+1]!=b[n+1]) Q[a[n+1]].push_back(b[n+1]);



    for(int i=1;i<cnt;i++) if(Q[i].size()&&!vis[i]) dfs(i),ans++;



    if(!vis[cnt]) ans++;



    printf("%d",ans-1);



	return 0;

}


// Faster C++ solution for the same problem (measured speedup: 5.643170598209343x):
#include<stdio.h>

#include<map>

using namespace std;

int n,ch[1000005],sh[1000005],ans,sum,fa[1000005],tot,mk[1000005];

map <int,int> mp,mmp;

int gf(int p){

	if(fa[p]==p)return p;

	return fa[p]=gf(fa[p]);

}

void mg(int a,int b){

	int fx=gf(a),fy=gf(b);

	if(fx!=fy){

		fa[fx]=fy;

	}

}

int main(){

	scanf("%d",&n);

	for(int i=1;i<=n;i++){

		scanf("%d",&sh[i]);sum^=sh[i];mp[sh[i]]++;

	}mp[sum]++;

	for(int i=1;i<=n;i++){

		scanf("%d",&ch[i]);mp[ch[i]]--;

		if(mp[ch[i]]<0){

			ans=-999999999;

		}

		if(sh[i]!=ch[i]){mk[i]=1;

			ans++;

		}

	}

	sh[n+1]=sum;

	for(int i=1;i<=n+1;i++){

		if(mp[sh[i]]>0){

			ch[n+1]=sh[i];break;

		}

	}

	n++;tot=n+n;

	mk[n]=1;

	for(int i=1;i<=n;i++){

		if(!mk[i])continue;

		if(mmp[sh[i]]==0)mmp[sh[i]]=++tot;

		fa[i]=i;fa[i+n]=i+n;

	}

	for(int i=1;i<=tot;i++)fa[i]=i;

	for(int i=1;i<=n;i++){

		if(!mk[i]){

			fa[i]=fa[i+n]=0;

		}

	}

	for(int i=1;i<=n;i++){

		if(sh[i]!=ch[i])mg(i,i+n);

		mg(i,mmp[sh[i]]);mg(i+n,mmp[ch[i]]);

	}

	for(int i=1;i<=tot;i++){

		if(fa[i]==i){//printf("i:%d\n",i);

			ans++;

		}

	}

	ans--;

	if(ans<0)printf("-1");

	else printf("%d",ans);

}
// Slower C++ solution:
#include <cstdio>

#include <iostream>

#include <cstring>

#include <algorithm> 

#include <vector>

#include <map>

using namespace std;

#define Max(a,b) ((a)>(b)?(a):(b))

#define Min(a,b) ((a)<(b)?(a):(b))

#define ll long long 

#define ri register int

#define f(i,a,b) for(ri i=a;i<=b;i++)

#define rf(i,b,a) for(ri i=b;i>=a;i--)

const int N=1e5+10;

int n,cnt,ans;

int a[N],b[N],x[N],y[N];

bool vis[N];

vector<int>Q[N];

map<int,int>d;

inline void read(int &x) {

    x=0;int f=1;char c=getchar();

    while (c>'9'||c<'0') {if (c=='-') f=-1;c=getchar();}

    while (c>='0'&&c<='9') {x=x*10+c-'0';c=getchar();}

    x*=f;

}

void dfs(int x)

{

    vis[x]=1;

    for (int i=0;i<Q[x].size();i++) 

    	if (!vis[Q[x][i]]) dfs(Q[x][i]);

}

int main()

{

   	read(n);

    for (int i=1;i<=n;i++) {

        read(a[i]),a[n+1]^=a[i];

        if (!d[a[i]]) d[a[i]]=++cnt;

    }

    if (!d[a[n+1]]) d[a[n+1]]=++cnt;

    for (int i=1;i<=n;i++) {

        read(b[i]),b[n+1]^=b[i];

        if (!d[b[i]]) d[b[i]]=++cnt;

    }

    if (!d[b[n+1]]) d[b[n+1]]=++cnt;

    memcpy(x,a,sizeof x),memcpy(y,b,sizeof y);

    sort(x+1,x+n+2),sort(y+1,y+n+2);

    for (int i=1;i<=n;i++) 

    	if (x[i]!=y[i]) {printf("-1");return 0;}

    for (int i=1;i<=n+1;i++) 

    	a[i]=d[a[i]],b[i]=d[b[i]];

    for (int i=1;i<=n;i++) 

    	if (a[i]!=b[i]) ans++,Q[a[i]].push_back(b[i]);

    if (a[n+1]!=b[n+1]) Q[a[n+1]].push_back(b[n+1]);

    for (int i=1;i<cnt;i++) 

    	if (Q[i].size()&&!vis[i]) dfs(i),ans++;

    if (!vis[cnt]) ans++;

    printf("%d",ans-1);

}

// Faster C++ solution for the same problem (measured speedup: 5.614132921430973x):
#include<stdio.h>

#include<map>

using namespace std;

int n,ch[1000005],sh[1000005],ans,sum,fa[1000005],tot,mk[1000005];

map <int,int> mp,mmp;

int gf(int p){

	if(fa[p]==p)return p;

	return fa[p]=gf(fa[p]);

}

void mg(int a,int b){

	int fx=gf(a),fy=gf(b);

	if(fx!=fy){

		fa[fx]=fy;

	}

}

int main(){

	scanf("%d",&n);

	for(int i=1;i<=n;i++){

		scanf("%d",&sh[i]);sum^=sh[i];mp[sh[i]]++;

	}mp[sum]++;

	for(int i=1;i<=n;i++){

		scanf("%d",&ch[i]);mp[ch[i]]--;

		if(mp[ch[i]]<0){

			ans=-999999999;

		}

		if(sh[i]!=ch[i]){mk[i]=1;

			ans++;

		}

	}

	sh[n+1]=sum;

	for(int i=1;i<=n+1;i++){

		if(mp[sh[i]]>0){

			ch[n+1]=sh[i];break;

		}

	}

	n++;tot=n+n;

	mk[n]=1;

	for(int i=1;i<=n;i++){

		if(!mk[i])continue;

		if(mmp[sh[i]]==0)mmp[sh[i]]=++tot;

		fa[i]=i;fa[i+n]=i+n;

	}

	for(int i=1;i<=tot;i++)fa[i]=i;

	for(int i=1;i<=n;i++){

		if(!mk[i]){

			fa[i]=fa[i+n]=0;

		}

	}

	for(int i=1;i<=n;i++){

		if(sh[i]!=ch[i])mg(i,i+n);

		mg(i,mmp[sh[i]]);mg(i+n,mmp[ch[i]]);

	}

	for(int i=1;i<=tot;i++){

		if(fa[i]==i){//printf("i:%d\n",i);

			ans++;

		}

	}

	ans--;

	if(ans<0)printf("-1");

	else printf("%d",ans);

}
// Slower C++ solution:
#include <cstdio>

#include <iostream>

#include <cstring>

#include <algorithm> 

#include <vector>

#include <map>

#define N 100010

using namespace std;

vector<int>Q[N];

map<int,int>d;

bool vis[N];

int n,a[N],b[N],x[N],y[N],cnt,ans;

void dfs(int x){

    vis[x]=1;

    for (int i=0;i<Q[x].size();i++) if (!vis[Q[x][i]]) dfs(Q[x][i]);

}

int main(){

    scanf("%d",&n);



    for(int i=1;i<=n;i++){

        scanf("%d",&a[i]),a[n+1]^=a[i];

        if(!d[a[i]]) d[a[i]]=++cnt;

    }



    if(!d[a[n+1]]) d[a[n+1]]=++cnt;



    for(int i=1;i<=n;i++){

        scanf("%d",&b[i]),b[n+1]^=b[i];

        if(!d[b[i]]) d[b[i]]=++cnt;

    }



    if(!d[b[n+1]]) d[b[n+1]]=++cnt;



    memcpy(x,a,sizeof x),memcpy(y,b,sizeof y);



    sort(x+1,x+n+2),sort(y+1,y+n+2);



    for(int i=1;i<=n;i++) if(x[i]!=y[i]) {printf("-1");return 0;}



    for(int i=1;i<=n+1;i++) a[i]=d[a[i]],b[i]=d[b[i]];



    for(int i=1;i<=n;i++) if(a[i]!=b[i]) ans++,Q[a[i]].push_back(b[i]);



    if(a[n+1]!=b[n+1]) Q[a[n+1]].push_back(b[n+1]);



    for(int i=1;i<cnt;i++) if(Q[i].size()&&!vis[i]) dfs(i),ans++;



    if(!vis[cnt]) ans++;



    printf("%d",ans-1);



	return 0;

}


// Faster C++ solution for the same problem (measured speedup: 5.260608703159894x):
#include<bits/stdc++.h>

using namespace std;

int n, a[100007], b[100007], cnt, f[200007], aa[100007], bb[100007], ss[200007], tot;

int read()

{

	int num = 0;

	char c = getchar();

	while (c < '0' || c>'9')c = getchar();

	while (c >= '0' && c <= '9')num = num * 10 + c - '0', c = getchar();

	return num;

}

int find(int x)

{

	if (f[x] == x)return x;

	else return f[x] = find(f[x]);

}

int main()

{

	n = read();

	for (int i = 1; i <= n; i++)

	{

		aa[i] = a[i] = read();

		a[n + 1] ^= a[i];

	}

	for (int i = 1; i <= n; i++)

	{

		bb[i] = b[i] = read();

		b[n + 1] ^= b[i];

	}

	aa[n + 1] = a[n + 1];

	bb[n + 1] = b[n + 1];

	n++;

	sort(aa + 1, aa + n + 1);

	sort(bb + 1, bb + n + 1);

	for (int i = 1; i <= n - 1; i++)

		if (aa[i] != bb[i])

		{

			cout << -1 << endl;

			return 0;

		}

	for(int i=1;i<=n;i++)

		if (a[i] != b[i] || i == n)

		{

			ss[++tot] = a[i];

			ss[++tot] = b[i];

			if (i != n)cnt++;

		}

	sort(ss + 1, ss + tot + 1);

	tot = unique(ss + 1, ss + tot + 1) - ss - 1;

	for (int i = 1; i <= tot; i++)

		f[i] = i;

	for (int i = 1; i <= n; i++)

		if (a[i] != b[i])

		{

			int x = lower_bound(ss + 1, ss + tot + 1, a[i]) - ss;

			int y = lower_bound(ss + 1, ss + tot + 1, b[i]) - ss;

			f[find(x)] = find(y);

		}

	for (int i = 1; i <= n; i++)

		if (f[i] == i)cnt++;

	cout << cnt - 1 << endl;

	return 0;

}