/*
after dusk passed,
there is a starry sky.
*/
#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
#define m_k make_pair
using namespace std;
const int N=2*1e5+100;
int n,a[N],b[N],p[N],vi[N],wh[N];
vector <pair<int,int> > ans;
priority_queue <pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > > q;
inline int read()
{
	int f=1,x=0;char s=getchar();
	while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
	while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
	return x*f;
}
signed main()
{
	n=read();
	for (int i=1;i<=n;i++) a[i]=read();
	for (int i=1;i<=n;i++) b[i]=read();
	for (int i=1;i<=n;i++) p[i]=read();
	for (int i=1;i<=n;i++)
	{
		if (p[i]==i){vi[i]=1;continue;}
		if (a[i]<=b[p[i]])
		{
			printf("-1\n");
			return 0;
		}
		q.push(m_k(a[i],i));wh[p[i]]=i;
	}
	while (!q.empty())
	{
		int x=q.top().second,y;q.pop();
		if (vi[x]) continue;
		vi[x]=1;y=wh[x];
		ans.push_back(m_k(x,y));
		wh[p[x]]=y;
		swap(p[x],p[y]);
		if (y==p[y]) vi[y]=1;
	}
	printf("%d\n",(int)ans.size());
	for (int i=0;i<(int)ans.size();i++) printf("%d %d\n",ans[i].first,ans[i].second);
}

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <bits/stdc++.h>

using namespace __gnu_pbds;
using namespace std;

using ll = long long;
using ld = long double;

typedef tree<
        int,
        null_type,
        less<int>,
        rb_tree_tag,
        tree_order_statistics_node_update>
        ordered_set;

#define mp make_pair


const int MOD =  998244353;



int mul(int a, int b) {
    return (1LL * a * b) % MOD;
}

int add(int a, int b) {
    int s = (a+b);
    if (s>=MOD) s-=MOD;
    return s;
}

int sub(int a, int b) {
    int s = (a+MOD-b);
    if (s>=MOD) s-=MOD;
    return s;
}

int po(int a, ll deg)
{
    if (deg==0) return 1;
    if (deg%2==1) return mul(a, po(a, deg-1));
    int t = po(a, deg/2);
    return mul(t, t);
}

int inv(int n)
{
    return po(n, MOD-2);
}


mt19937 rnd(time(0));


const int LIM = 200000;

vector<int> facs(LIM), invfacs(LIM);

void init()
{
    facs[0] = 1;
    for (int i = 1; i<LIM; i++) facs[i] = mul(facs[i-1], i);
    invfacs[LIM-1] = inv(facs[LIM-1]);
    for (int i = LIM-2; i>=0; i--) invfacs[i] = mul(invfacs[i+1], i+1);
}

int C(int n, int k)
{
    if (n<k) return 0;
    if (n<0 || k<0) return 0;
    return mul(facs[n], mul(invfacs[k], invfacs[n-k]));
}

/*
struct DSU
{
    vector<int> sz;
    vector<int> parent;
    void make_set(int v) {
        parent[v] = v;
        sz[v] = 1;
    }

    int find_set(int v) {
        if (v == parent[v])
            return v;
        return find_set(parent[v]);
    }

    void union_sets(int a, int b) {
        a = find_set(a);
        b = find_set(b);

        if (a != b) {
            if (sz[a] < sz[b])
                swap(a, b);
            parent[b] = a;
            sz[a] += sz[b];
        }
    }

    DSU (int n)
    {
        parent.resize(n);
        sz.resize(n);
        for (int i = 0; i<n; i++) make_set(i);
    }
};*/

const int N = 10000;

int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(nullptr);

    init();
    int n; cin>>n;
    vector<int> w(n);
    for (int i = 0; i<n; i++) cin>>w[i];
    vector<vector<int>> dp(N+1, vector<int>(n+1));

    dp[0][0] = 1;
    for (int i = 0; i<n; i++)
    {
        for (int W = N; W>=w[i]; W--)
            for (int cnt = i+1; cnt>=1; cnt--) dp[W][cnt] = add(dp[W][cnt], dp[W-w[i]][cnt-1]);
    }

    int tot = 0; for (auto it: w) tot+=it;
    if (tot%2==1) {cout<<0<<endl; return 0;}
    int need = tot/2;

    int ans = 0;

    for (int take = 0; take<=n; take++)
    {
        ans = add(ans, mul(dp[need][take], mul(facs[take], facs[n-take])));
    }

    cout<<ans;
}
