stablegradients/pie-gem5-bysrc huggingface dataset:
// Original C++ solution (slower):
#include<bits/stdc++.h>



using namespace std;



const int mod=1e9+7;

long long dp[700][2002];



long long DP(int cur,long long sum)

{

    if(sum == 0)return dp[cur][0]=1;

    if(sum < 3)return dp[cur][sum]=0;

    long long &ans=dp[cur][sum];

    if(ans > -1)return ans;

    ans=0;

    for(int i=3;i<=sum;i++)ans=(ans+DP(cur+1,sum-i))%mod;

    return ans;

}



int main()

{

    ios_base::sync_with_stdio(false);

    cin.tie(NULL);cout.tie(NULL);

    int n;

    memset(dp,-1,sizeof(dp));

    cin >> n;

    cout << DP(1,n);

    return 0;

}


// Optimized solution to the same problem (faster):
#include<bits/stdc++.h>



using namespace std;



const int mod=1e9+7;

long long dp[2002];



int main()

{

    ios_base::sync_with_stdio(false);

    cin.tie(NULL);cout.tie(NULL);

    int i,j,n;

    cin >> n;

    dp[0]=1;

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

    {

        for(j=3;j<=i;j++)

        {

            dp[i]+=dp[i-j];

            dp[i]%=mod;

        }

    }

    cout << dp[n];

    return 0;

}


// Fastest known solution for this problem:
// Original C++ solution (slower):
//#define _GLIBCXX_DEBUG

#include <bits/stdc++.h>

//#include <atcoder/all>

//using namespace atcoder;

using namespace std;

#define all(v) v.begin(), v.end()

using in = int64_t;

#define rep(i, n) for (int i = 0; i < (int)(n); i++)

#define REP(i,a,b) for(int i=(int)(a);i<(int)(b);i++)

#define Yes cout<<"Yes"<<endl

#define No cout<<"No"<<endl

#define yes cout<<"yes"<<endl

#define no cout<<"no"<<endl

#define YES cout<<"YES"<<endl

#define NO cout<<"NO"<<endl

const double PI=3.14159265358979323846;

const in MOD = 1000000007;

const in INF=1e18+7;

const int inf=1e9+7;

using P=pair<int,int>;

vector<int> dx={0,1,-1,0};

vector<int> dy={1,0,0,-1};





int main(){

ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);

cout << fixed << setprecision(10);

    int s;

    cin>>s;

    vector<vector<in>> dp(666,vector<in>(s+1,0));

    REP(i,3,s+1) dp[0][i]=1;

    in ans=0;

    ans += dp[0][s];



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

        in sum=0;

        REP(j,4,s+1){

            sum += dp[i-1][j-3];

            sum %= MOD;

            dp[i][j]=sum;

        }

        ans += dp[i][s];

        ans %= MOD;

    }

    cout<<ans<<endl;

}/*

./problem.exe

*/

// Optimized solution to the same problem (faster):
//#define _GLIBCXX_DEBUG

#include <bits/stdc++.h>

//#include <atcoder/all>

//using namespace atcoder;

using namespace std;

#define all(v) v.begin(), v.end()

using in = int64_t;

#define rep(i, n) for (int i = 0; i < (int)(n); i++)

#define REP(i,a,b) for(int i=(int)(a);i<(int)(b);i++)

#define Yes cout<<"Yes"<<endl

#define No cout<<"No"<<endl

#define yes cout<<"yes"<<endl

#define no cout<<"no"<<endl

#define YES cout<<"YES"<<endl

#define NO cout<<"NO"<<endl

const double PI=3.14159265358979323846;

const in MOD = 1000000007;

const in INF=1e18+7;

const int inf=1e9+7;

using P=pair<int,int>;

vector<int> dx={0,1,-1,0};

vector<int> dy={1,0,0,-1};





int main(){

ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);

cout << fixed << setprecision(10);

    int s;

    cin>>s;

    vector<vector<in>> dp(max(s/3,1),vector<in>(s+1,0));

    REP(i,3,s+1) dp[0][i]=1;

    in ans=0;

    ans += dp[0][s];



    for(int i=1;i<s/3;i++){

        in sum=0;

        REP(j,3*i+3,s+1){

            sum += dp[i-1][j-3];

            sum %= MOD;

            dp[i][j]=sum;

        }

        ans += dp[i][s];

        ans %= MOD;

    }

    cout<<ans<<endl;

}/*

./problem.exe

*/

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include<bits/stdc++.h>

using namespace std;

#define ll long long 

#define pb push_back

#define M 1000000007

#define all(v) (v).begin(),(v).end()

#define rall(v) (v).rbegin(),(v).rend()

const int N = 1e6 + 1;

int dp[670][2001] , S;

int calc(int u , int sum){

	if(sum == S)return 1;

	if(sum > S)return 0;

	int& ret = dp[u][sum];

	if(ret+1)return ret;

	ret = 0;

	for (int i = 3; i <= S - sum; ++i){

		ret += calc(u+1 , sum+i);

		if(ret >= M)ret -= M;

	}

	return ret%M;

}

int main(){	

	cin >> S;

	memset(dp , -1 ,sizeof dp);

	cout << calc(0 , 0) << endl;

	

	

		

}	

// Optimized solution to the same problem (faster):
#include<bits/stdc++.h>

using namespace std;

#define ll long long 

#define pb push_back

#define M 1000000007

#define all(v) (v).begin(),(v).end()

#define rall(v) (v).rbegin(),(v).rend()

const int N = 1e6 + 1;

int dp[3000] , S;

int main(){	

	cin >> S;

	for (int i = 3; i <= S; ++i){

		if(++dp[i] >= M) dp[i] -= M;

		for (int j = 3; j <= S && i - j >= 3; ++j){

			dp[i] += dp[i-j];

			if(dp[i] >= M) dp[i] -= M;

		}

	}

	cout << dp[S] << endl;

	

	

		

}	

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include<bits/stdc++.h>

using namespace std;

long long mod = 1e9+7;

int mark[200003] = {};

int limit = 0;

long long dp[200005] = {};

long long getSum(long long n)

{

    if(dp[n] != -1 && n >= 0)

    {

        return dp[n];

    }

    if(n == 0)

    {

        return 1;

    }

    if(n < 0)

    {

        return 0;

    }

    long long res = 0;

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

    {

        if(n-mark[i] >= 0)

        {

            res =(res+getSum(n-mark[i]))%mod;

        }

    }

    return dp[n] = res%mod;

}

void solve()

{

    long long n; cin >> n;

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

    {

        limit++;

        mark[limit] = i;

    }

    long long sum = getSum(n)%mod;

    cout << sum << endl;

}

int main()

{

    memset(dp, -1, sizeof(dp));

    solve();

    return 0;

}


// Optimized solution to the same problem (faster):
#include<bits/stdc++.h>

using namespace std;

long long mod = 1e9+7;

int mark[2009] = {};

int limit = 0;

long long dp[2050] = {};

long long getSum(long long n)

{

    if(dp[n] != -1 && n >= 0)

    {

        return dp[n];

    }

    if(n == 0)

    {

        return 1;

    }

    if(n < 0)

    {

        return 0;

    }

    long long res = 0;

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

    {

        if(n-mark[i] >= 0)

        {

            res =(res+getSum(n-mark[i]))%mod;

        }

    }

    return dp[n] = res%mod;

}

void solve()

{

    long long n; cin >> n;

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

    {

        limit++;

        mark[limit] = i;

    }

    long long sum = getSum(n)%mod;

    cout << sum << endl;

}

int main()

{

    memset(dp, -1, sizeof(dp));

    solve();

    return 0;

}


// Fastest known solution for this problem:
// Original C++ solution (slower):
#include<iostream>

using namespace std;

typedef long long int ll;

const int maxn=2e5+10;

const int mod=1e9+7;

ll a[maxn];

int main(){

	a[1]=0;

	a[2]=0;

	a[3]=1;

	for(int i=4;i<maxn;i++){

		a[i]=(a[i-1]+a[i-3])%mod;

	}

	int n;

	cin>>n;

	cout<<a[n]<<endl;

}

// Optimized solution to the same problem (faster):
#include<iostream>

#include<math.h>

#include<algorithm>

typedef long long ll;

const ll mod=1e9+7;

using namespace std;

ll n,a,b;

ll dp[2010];

int main(){

cin>>n;

for (int i=3;i<10;i++)

dp[n-i]= 1;

dp[n]=1;

for (int i=n-3;i>=0;i--){

for (int j= 3;j<10;j++){

dp[i-j]=(dp[i-j+1]+dp[i])%mod;

}

}

cout<<dp[0];

return 0;

} 




// Fastest known solution for this problem:
// Original C++ solution (slower):
#include<iostream>

using namespace std;

typedef long long int ll;

const int maxn=2e5+10;

const int mod=1e9+7;

ll a[maxn];

int main(){

	a[1]=0;

	a[2]=0;

	a[3]=1;

	for(int i=4;i<maxn;i++){

		a[i]=(a[i-1]+a[i-3])%mod;

	}

	int n;

	cin>>n;

	cout<<a[n]<<endl;

}

// Optimized solution to the same problem (faster):
#include<iostream>

#include<math.h>

#include<algorithm>

typedef long long ll;



using namespace std;



ll n, a, b;

ll dp[2005];



int main() {

	cin >> n;

	for (int i = 3; i < 10; i++) {

		dp[n - i] = 1;

	}

	dp[n] = 1;

	for (int i = n-3; i >= 0; i--){

		for (int j = 3; j < 10; j++){

			dp[i - j] = (dp[i - j + 1] + dp[i])%1000000007;

		}

	}

	cout << dp[0];

	return 0;

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#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;

}


// Optimized solution to the same problem (faster):
/*

考虑建立虚拟根 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;

}


// Fastest known solution for this problem:
// Original C++ solution (slower):
#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;

}

// Optimized solution to the same problem (faster):
#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;

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#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;

}

// Optimized solution to the same problem (faster):
#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;

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#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;

}

// Optimized solution to the same problem (faster):
#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;

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#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;

}

// Optimized solution to the same problem (faster):
#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;

}

// Fastest known solution for this problem: