#include <algorithm>
#include <iostream>
#include <string.h>
#include <vector>
#include <map>

using namespace std;

#define pb push_back
#define mp make_pair
#define ll long long
#define ull unsigned ll
#define db double
#define lb long double
#define INF 0x3f3f3f3f
#define MOD 1000000007
#define PII pair<int, int>

ll gcd(ll a,ll b) {
    return b==0?a:gcd(b,a%b);
}

ll mul(ll a,ll b,ll mod) {
    ll ret=0;
    while (b) {
        if (b&1) ret=(ret+a)%mod;
        a=(a+a)%mod;
        b>>=1;
    }
    return ret;
}

ll qp(ll a,ll b,ll mod) {
    ll ret=1;
    while (b) {
        if (b&1) ret=mul(ret,a,mod);
        a=mul(a,a,mod);
        b>>=1;
    }
    return ret;
}

bool check(ll n,ll p) {
    ll m=n-1;
    while (m%2==0) m/=2;
    ll val=qp(p,m,n);
    while (m<n) {
        ll tmp=mul(val,val,n);
        if (tmp==1&&val!=1&&val!=n-1) return false;
        val=tmp;
        m<<=1;
    }
    return val==1;
}

bool miller_rabin(ll n) {
    if (n==2) return true;
    if (n<2||n%2==0) return false;
    for (int i=0;i<3;i++) {
        if (!check(n,rand()%(n-1)+1)) return false;
    }
    return true;
}

ll pollard_rho(ll n,ll c) {
    ll x=rand()%n,fixed=x,i=1,k=2;
    while (true) {
        i++;
        x=(mul(x,x,n)+c)%n;
        ll tmp=gcd(x-fixed,n);
        if (1<tmp&&tmp<n) return tmp;
        if (x==fixed) return n;
        if (i==k) {
            fixed=x;
            k+=k;
        }
    }
    return n;
}

static int idx=1;
void fac(ll n,ll c,map<ll,vector<int>>& out) {
    if (n==1) return;
    if (miller_rabin(n)) {
        out[n].pb(idx++);
        return;
    }
    ll m=n;
    while (m==n) m=pollard_rho(n,c--);
    fac(m,c,out),fac(n/m,c,out);
}

const int N=2000,M=100000;
int n,m,a[N];
map<ll,vector<int>> fc[N];

struct edge {
    int to,next;
} e[M];
int head[N*5],tot;
void add_edge(int u,int v) {
    e[tot].to=v;
    e[tot].next=head[u];
    head[u]=tot++;
}
bool vis[N];
int match[N];
bool dfs(int u) {
    vis[u]=true;
    for (int i=head[u];i!=-1;i=e[i].next) {
        int to=e[i].to;
        int w=match[to];
        if (!w||!vis[w]&&dfs(w)) {
            match[u]=to;
            match[to]=u;
            return true;
        }
    }
    return false;
}

int main()
{
    scanf("%d%d",&n,&m);
    vector<ll> vec;
    for (int i=1;i<=n;i++) {
        scanf("%d",a+i);
        fac(a[i],41041,fc[i]);
    }

    // build graph
    memset(head,-1,sizeof(head));
    for (int i=1;i<=m;i++) {
        int p,q;
        scanf("%d%d",&p,&q);
        for (auto entry:fc[p]) {
            for (int u:entry.second) {
                for (int v:fc[q][entry.first]) {
                    add_edge(u,v);
                }
            }
        }
    }
    int ans=0;
    for (int i=1;i<idx;i++) {
        if (!match[i]) {
            memset(vis,0,sizeof(vis));
            if (dfs(i)) ans++;
        }
    }
    printf("%d\n",ans);
}


#include <algorithm>
#include <iostream>
#include <string.h>
#include <vector>
#include <map>

using namespace std;

#define pb push_back
#define mp make_pair
#define ll long long
#define ull unsigned ll
#define db double
#define lb long double
#define INF 0x3f3f3f3f
#define MOD 1000000007
#define PII pair<int, int>

ll gcd(ll a,ll b) {
    return b==0?a:gcd(b,a%b);
}

ll mul(ll a,ll b,ll mod) {
    ll ret=0;
    while (b) {
        if (b&1) ret=(ret+a)%mod;
        a=(a+a)%mod;
        b>>=1;
    }
    return ret;
}

ll qp(ll a,ll b,ll mod) {
    ll ret=1;
    while (b) {
        if (b&1) ret=mul(ret,a,mod);
        a=mul(a,a,mod);
        b>>=1;
    }
    return ret;
}

bool check(ll n,ll p) {
    ll m=n-1;
    while (m%2==0) m/=2;
    ll val=qp(p,m,n);
    while (m<n) {
        ll tmp=mul(val,val,n);
        if (tmp==1&&val!=1&&val!=n-1) return false;
        val=tmp;
        m<<=1;
    }
    return val==1;
}

bool miller_rabin(ll n) {
    if (n==2) return true;
    if (n<2||n%2==0) return false;
    for (int i=0;i<3;i++) {
        if (!check(n,rand()%(n-1)+1)) return false;
    }
    return true;
}

ll pollard_rho(ll n,ll c) {
    ll x=rand()%n,fixed=x,i=1,k=2;
    while (true) {
        i++;
        x=(mul(x,x,n)+c)%n;
        ll tmp=gcd(x-fixed,n);
        if (1<tmp&&tmp<n) return tmp;
        if (x==fixed) return n;
        if (i==k) {
            fixed=x;
            k+=k;
        }
    }
    return n;
}

static int idx=1;
void fac(ll n,ll c,map<ll,vector<int>>& out) {
    if (n==1) return;
    if (miller_rabin(n)) {
        out[n].pb(idx++);
        return;
    }
    ll m=n;
    while (m==n) m=pollard_rho(n,c--);
    fac(m,c,out),fac(n/m,c,out);
}

const int N=100,M=2010;
int n,m,a[N];
map<ll,vector<int>> fc[N];

struct edge {
    int to,next;
} e[M];
int head[N*5],tot;
void add_edge(int u,int v) {
    e[tot].to=v;
    e[tot].next=head[u];
    head[u]=tot++;
}
bool vis[N*5];
int match[N*5];
bool dfs(int u) {
    vis[u]=true;
    for (int i=head[u];i!=-1;i=e[i].next) {
        int to=e[i].to;
        int w=match[to];
        if (!w||!vis[w]&&dfs(w)) {
            match[u]=to;
            match[to]=u;
            return true;
        }
    }
    return false;
}

int main()
{
    scanf("%d%d",&n,&m);
    vector<ll> vec;
    for (int i=1;i<=n;i++) {
        scanf("%d",a+i);
        fac(a[i],10,fc[i]);
    }

    // build graph
    memset(head,-1,sizeof(head));
    for (int i=1;i<=m;i++) {
        int p,q;
        scanf("%d%d",&p,&q);
        for (auto entry:fc[p]) {
            for (int u:entry.second) {
                for (int v:fc[q][entry.first]) {
                    add_edge(u,v);
                }
            }
        }
    }

    int ans=0;
    for (int i=1;i<idx;i++) {
        if (!match[i]) {
            memset(vis,0,sizeof(vis));
            if (dfs(i)) ans++;
        }
    }
    printf("%d\n",ans);
}


#include <algorithm>
#include <iostream>
#include <string.h>
#include <vector>
#include <map>

using namespace std;

#define pb push_back
#define mp make_pair
#define ll long long
#define ull unsigned ll
#define db double
#define lb long double
#define INF 0x3f3f3f3f
#define MOD 1000000007
#define PII pair<int, int>

ll gcd(ll a,ll b) {
    return b==0?a:gcd(b,a%b);
}

ll mul(ll a,ll b,ll mod) {
    ll ret=0;
    while (b) {
        if (b&1) ret=(ret+a)%mod;
        a=(a+a)%mod;
        b>>=1;
    }
    return ret;
}

ll qp(ll a,ll b,ll mod) {
    ll ret=1;
    while (b) {
        if (b&1) ret=mul(ret,a,mod);
        a=mul(a,a,mod);
        b>>=1;
    }
    return ret;
}

bool check(ll n,ll p) {
    ll m=n-1;
    while (m%2==0) m/=2;
    ll val=qp(p,m,n);
    while (m<n) {
        ll tmp=mul(val,val,n);
        if (tmp==1&&val!=1&&val!=n-1) return false;
        val=tmp;
        m<<=1;
    }
    return val==1;
}

bool miller_rabin(ll n) {
    if (n==2) return true;
    if (n<2||n%2==0) return false;
    for (int i=0;i<3;i++) {
        if (!check(n,rand()%(n-1)+1)) return false;
    }
    return true;
}

ll pollard_rho(ll n,ll c) {
    ll x=rand()%n,fixed=x,i=1,k=2;
    while (true) {
        i++;
        x=(mul(x,x,n)+c)%n;
        ll tmp=gcd(x-fixed,n);
        if (1<tmp&&tmp<n) return tmp;
        if (x==fixed) return n;
        if (i==k) {
            fixed=x;
            k+=k;
        }
    }
    return n;
}

static int idx=1;
void fac(ll n,ll c,map<ll,vector<int>>& out) {
    if (n==1) return;
    if (miller_rabin(n)) {
        out[n].pb(idx++);
        return;
    }
    ll m=n;
    while (m==n) m=pollard_rho(n,c--);
    fac(m,c,out),fac(n/m,c,out);
}

const int N=100,M=2010;
int n,m,a[N];
map<ll,vector<int>> fc[N];

struct edge {
    int to,next;
} e[M];
int head[N*5],tot;
void add_edge(int u,int v) {
    e[tot].to=v;
    e[tot].next=head[u];
    head[u]=tot++;
}
bool vis[N*5];
int match[N*5];
bool dfs(int u) {
    vis[u]=true;
    for (int i=head[u];i!=-1;i=e[i].next) {
        int to=e[i].to;
        int w=match[to];
        if (!w||!vis[w]&&dfs(w)) {
            match[u]=to;
            match[to]=u;
            return true;
        }
    }
    return false;
}

int main()
{
    scanf("%d%d",&n,&m);
    vector<ll> vec;
    for (int i=1;i<=n;i++) {
        scanf("%d",a+i);
        fac(a[i],41041,fc[i]);
    }

    // build graph
    memset(head,-1,sizeof(head));
    for (int i=1;i<=m;i++) {
        int p,q;
        scanf("%d%d",&p,&q);
        for (auto entry:fc[p]) {
            for (int u:entry.second) {
                for (int v:fc[q][entry.first]) {
                    add_edge(u,v);
                }
            }
        }
    }

    int ans=0;
    for (int i=1;i<idx;i++) {
        if (!match[i]) {
            memset(vis,0,sizeof(vis));
            if (dfs(i)) ans++;
        }
    }
    printf("%d\n",ans);
}


#include <algorithm>
#include <iostream>
#include <string.h>
#include <vector>
#include <map>

using namespace std;

#define pb push_back
#define mp make_pair
#define ll long long
#define ull unsigned ll
#define db double
#define lb long double
#define INF 0x3f3f3f3f
#define MOD 1000000007
#define PII pair<int, int>

ll gcd(ll a,ll b) {
    return b==0?a:gcd(b,a%b);
}

ll mul(ll a,ll b,ll mod) {
    ll ret=0;
    while (b) {
        if (b&1) ret=(ret+a)%mod;
        a=(a+a)%mod;
        b>>=1;
    }
    return ret;
}

ll qp(ll a,ll b,ll mod) {
    ll ret=1;
    while (b) {
        if (b&1) ret=mul(ret,a,mod);
        a=mul(a,a,mod);
        b>>=1;
    }
    return ret;
}

bool check(ll n,ll p) {
    ll m=n-1;
    while (m%2==0) m/=2;
    ll val=qp(p,m,n);
    while (m<n) {
        ll tmp=mul(val,val,n);
        if (tmp==1&&val!=1&&val!=n-1) return false;
        val=tmp;
        m<<=1;
    }
    return val==1;
}

bool miller_rabin(ll n) {
    if (n==2) return true;
    if (n<2||n%2==0) return false;
    for (int i=0;i<3;i++) {
        if (!check(n,rand()%(n-1)+1)) return false;
    }
    return true;
}

ll pollard_rho(ll n,ll c) {
    ll x=rand()%n,fixed=x,i=1,k=2;
    while (true) {
        i++;
        x=(mul(x,x,n)+c)%n;
        ll tmp=gcd(x-fixed,n);
        if (1<tmp&&tmp<n) return tmp;
        if (x==fixed) return n;
        if (i==k) {
            fixed=x;
            k+=k;
        }
    }
    return n;
}

static int idx=1;
void fac(ll n,ll c,map<ll,vector<int>>& out) {
    if (n==1) return;
    if (miller_rabin(n)) {
        out[n].pb(idx++);
        return;
    }
    ll m=n;
    while (m==n) m=pollard_rho(n,c--);
    fac(m,c,out),fac(n/m,c,out);
}

const int N=2000,M=200000;
int n,m,a[N];
map<ll,vector<int>> fc[N];

struct edge {
    int to,next;
} e[M];
int head[N*5],tot;
void add_edge(int u,int v) {
    e[tot].to=v;
    e[tot].next=head[u];
    head[u]=tot++;
}
bool vis[N];
int match[N];
bool dfs(int u) {
    vis[u]=true;
    for (int i=head[u];i!=-1;i=e[i].next) {
        int to=e[i].to;
        int w=match[to];
        if (!w||!vis[w]&&dfs(w)) {
            match[u]=to;
            match[to]=u;
            return true;
        }
    }
    return false;
}

int main()
{
    scanf("%d%d",&n,&m);
    vector<ll> vec;
    for (int i=1;i<=n;i++) {
        scanf("%d",a+i);
        fac(a[i],41041,fc[i]);
    }

    // build graph
    memset(head,-1,sizeof(head));
    for (int i=1;i<=m;i++) {
        int p,q;
        scanf("%d%d",&p,&q);
        for (auto entry:fc[p]) {
            for (int u:entry.second) {
                for (int v:fc[q][entry.first]) {
                    add_edge(u,v);
                    add_edge(v,u);
                }
            }
        }
    }
    int ans=0;
    for (int i=1;i<idx;i++) {
        if (!match[i]) {
            memset(vis,0,sizeof(vis));
            if (dfs(i)) ans++;
        }
    }
    printf("%d\n",ans);
}


#include <algorithm>
#include <iostream>
#include <string.h>
#include <vector>
#include <map>

using namespace std;

#define pb push_back
#define mp make_pair
#define ll long long
#define ull unsigned ll
#define db double
#define lb long double
#define INF 0x3f3f3f3f
#define MOD 1000000007
#define PII pair<int, int>

ll gcd(ll a,ll b) {
    return b==0?a:gcd(b,a%b);
}

ll mul(ll a,ll b,ll mod) {
    ll ret=0;
    while (b) {
        if (b&1) ret=(ret+a)%mod;
        a=(a+a)%mod;
        b>>=1;
    }
    return ret;
}

ll qp(ll a,ll b,ll mod) {
    ll ret=1;
    while (b) {
        if (b&1) ret=mul(ret,a,mod);
        a=mul(a,a,mod);
        b>>=1;
    }
    return ret;
}

bool check(ll n,ll p) {
    ll m=n-1;
    while (m%2==0) m/=2;
    ll val=qp(p,m,n);
    while (m<n) {
        ll tmp=mul(val,val,n);
        if (tmp==1&&val!=1&&val!=n-1) return false;
        val=tmp;
        m<<=1;
    }
    return val==1;
}

bool miller_rabin(ll n) {
    if (n==2) return true;
    if (n<2||n%2==0) return false;
    for (int i=0;i<3;i++) {
        if (!check(n,rand()%(n-1)+1)) return false;
    }
    return true;
}

ll pollard_rho(ll n,ll c) {
    ll x=rand()%n,fixed=x,i=1,k=2;
    while (true) {
        i++;
        x=(mul(x,x,n)+c)%n;
        ll tmp=gcd(x-fixed,n);
        if (1<tmp&&tmp<n) return tmp;
        if (x==fixed) return n;
        if (i==k) {
            fixed=x;
            k+=k;
        }
    }
    return n;
}

static int idx=1;
void fac(ll n,ll c,map<ll,vector<int>>& out) {
    if (n==1) return;
    if (miller_rabin(n)) {
        out[n].pb(idx++);
        return;
    }
    ll m=n;
    while (m==n) m=pollard_rho(n,c--);
    fac(m,c,out),fac(n/m,c,out);
}

const int N=3000,M=200000;
int n,m,a[N];
map<ll,vector<int>> fc[N];

struct edge {
    int to,next;
} e[M];
int head[N*5],tot;
void add_edge(int u,int v) {
    e[tot].to=v;
    e[tot].next=head[u];
    head[u]=tot++;
}
bool vis[N];
int match[N];
bool dfs(int u) {
    vis[u]=true;
    for (int i=head[u];i!=-1;i=e[i].next) {
        int to=e[i].to;
        int w=match[to];
        if (!w||!vis[w]&&dfs(w)) {
            match[u]=to;
            match[to]=u;
            return true;
        }
    }
    return false;
}

int main()
{
    scanf("%d%d",&n,&m);
    vector<ll> vec;
    for (int i=1;i<=n;i++) {
        scanf("%d",a+i);
        fac(a[i],41041,fc[i]);
    }

    // build graph
    memset(head,-1,sizeof(head));
    for (int i=1;i<=m;i++) {
        int p,q;
        scanf("%d%d",&p,&q);
        for (auto entry:fc[p]) {
            for (int u:entry.second) {
                for (int v:fc[q][entry.first]) {
                    add_edge(u,v);
                    add_edge(v,u);
                }
            }
        }
    }
    int ans=0;
    for (int i=1;i<idx;i++) {
        if (!match[i]) {
            memset(vis,0,sizeof(vis));
            if (dfs(i)) ans++;
        }
    }
    printf("%d\n",ans);
}


#include<stdio.h>
#include<iostream>
#include<string.h>
#include<ctype.h>
#include<math.h>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<functional>
#include<string>
#include<algorithm>
#include<time.h>
#include<bitset>
void fre(){freopen("c://test//input.in","r",stdin);freopen("c://test//output.out","w",stdout);}
#define MS(x,y) memset(x,y,sizeof(x))
#define MC(x,y) memcpy(x,y,sizeof(x))
#define MP(x,y) make_pair(x,y)
#define ls o<<1
#define rs o<<1|1
typedef long long LL;
typedef unsigned long long UL;
typedef unsigned int UI;
template <class T> inline void gmax(T &a,T b){if(b>a)a=b;}
template <class T> inline void gmin(T &a,T b){if(b<a)a=b;}
using namespace std;
const int N=105,M=6000,Z=1e9+7,maxint=2147483647,ms31=522133279,ms63=1061109567,ms127=2139062143;const double eps=1e-8,PI=acos(-1.0);//.0
//最大边数为：（50*50+50+50）*2=5200
set<int>sot;
int id,ST,ED;
int n,m,g;
bool e[40000];
int p[10000],pnum;
int a[N],b[N],c[N],d[N],v[808];
int first[N];
int w[M],cap[M],nxt[M];
void prime()
{
	int top=sqrt(1e9+1e6);
	for(int i=2;i<=top;i++)if(e[i]==0)
	{
		p[++pnum]=i;
		for(int j=i+i;j<=top;j+=i)e[j]=1;
	}
}
void split1(int x)
{
	for(int i=1;p[i]*p[i]<=x;i++)
	{
		if(x%p[i]==0)
		{
			while(x%p[i]==0)x/=p[i];//%
			sot.insert(p[i]);
		}
	}
	if(x>1)sot.insert(x);
}
void split0(int x)
{
	for(int i=1;p[i]*p[i]<=x;i++)
	{
		if(x%p[i]==0)
		{
			while(x%p[i]==0)x/=p[i];
			if(sot.find(p[i])!=sot.end())
			{
				sot.erase(p[i]);
				v[++g]=p[i];
			}
		}
	}
	if(x>1)
	{
		if(sot.find(x)!=sot.end())
		{
			sot.erase(x);
			v[++g]=x;
		}
	}
}
void ins(int x,int y,int cap_)
{
	id++;
	w[id]=y;
	cap[id]=cap_;
	nxt[id]=first[x];
	first[x]=id;

	id++;
	w[id]=x;
	cap[id]=0;
	nxt[id]=first[y];
	first[y]=id;
}
int dep[N];
bool bfs()
{
	MS(dep,-1);dep[ST]=0;
	queue<int>q;q.push(ST);
	while(!q.empty())
	{
		int x=q.front();q.pop();
		for(int z=first[x];z;z=nxt[z])if(cap[z])
		{
			int y=w[z];
			if(dep[y]==-1)
			{
				dep[y]=dep[x]+1;
				if(y==ED)return 1;
				q.push(y);
			}
		}
	}
	return 0;
}
int dfs(int x,int all)
{
	if(x==ED)return all;
	int use=0;
	for(int z=first[x];z;z=nxt[z])if(cap[z])
	{
		int y=w[z];
		if(dep[y]==dep[x]+1)
		{
			int tmp=dfs(y,min(all-use,cap[z]));
			cap[z]-=tmp;
			cap[z^1]+=tmp;
			use+=tmp;
			if(use==all)break;
		}
	}
	if(use==0)dep[x]=-1;
	return use;
}
int dinic()
{
	int tmp=0;
	while(bfs())tmp+=dfs(ST,10000);//inf=30*50
	return tmp;
}
int main()
{
	prime();
	while(~scanf("%d%d",&n,&m))
	{
		for(int i=1;i<=n;i++)scanf("%d",&a[i]);
		for(int i=1;i<=m;i++)
		{
			scanf("%d%d",&b[i],&c[i]);
			if(c[i]&1)swap(b[i],c[i]);
		}
		sot.clear();
		g=0;
		for(int i=1;i<=n;i+=2)split1(a[i]);
		for(int i=2;i<=n;i+=2)split0(a[i]);
		int ans=0;
		ST=0;
		ED=n+1;
		for(int i=1;i<=g;i++)//枚举素数
		{
			MS(first,0);id=1;
			for(int j=1;j<=n;j++)if(a[j]%v[i]==0)//v[i]是a[j]的因子
			{
				d[j]=0;//d[j]表示a[j]里有几个v[i]
				while(a[j]%v[i]==0)
				{
					d[j]++;
					a[j]/=v[i];
				}
				if(j&1)
				{
					ins(ST,j,d[j]);
				}
				else
				{
					ins(j,ED,d[j]);
				}
			}
			for(int j=1;j<=m;j++)
			{
				int x=b[j];
				int y=c[j];
				int num=min(d[x],d[y]);
				if(num)ins(x,y,num);
			}
			ans+=dinic();
		}
		printf("%d\n",ans);
	}
	return 0;
}
/*
【题意】
题目说，有n个数从a[1]到a[n].
有m个pair，对于k∈[1,m]，每个pair(ik,jk)都有——
1<=ik<jk<=n且ik+jk为奇数（也就是ik和jk为一奇一偶）

每次操作可以取一个k和一个v（v>1），对应pair(ik,jk)，
然后我们得到a[ik],a[jk]，在v是a[ik]是a[jk]的因子的时候，我们使得a[ik]/=v,a[jk]/=v，并判定这个操作是成功的，

我们希望做尽可能多的成功操作，并输出这个操作次数。

题目保证所有的pair内的(x,y)都有x！=y

【类型】
网络流

【分析】
首先，这道题设计到奇偶性质，我们很自然就想到了网络流。
然后，我们发现v必然一定取素数。

所有pair中的数非奇便偶，于是我们可以把点分成两类，奇点和偶点。
然后因为存在奇偶点间的匹配关系。

思考了一会，依然发现从简化问题的方式入手比较好思考。
如果v没得选，只能是某个素数。
我们可以这样——
1，对于每个奇数，数中含有几个v，就从超级源点向其建立容量为几的边
2，对于每个偶数，数中含有几个v，就从其向超级汇点建立容量为几的边
3，对于一个（奇数，偶数）pair，建一条边，容量为它们共有的v的数量。

然后开始跑最大流，我们发现，这个最大流，就是关于素数v，能实现的最多的匹配数。

这样，我们枚举所有的素数v，建图，跑最大流，求和。和便是最后的答案。

然而1e9范围的素数要爆炸啊。
只是这50个奇数内的素数的总数并不会太多。
我们可以先预处理出sqrt(1e9)范围内的所有素数。
然后对于每一个奇数，拆素数，得到的素数放set里
对于每一个偶数，再拆素数，得到的素数如果set中有，就作为一种被枚举的v
因为n和m并不大，所以感觉可以AC

【时间复杂度&&优化】
2*3*5*7*11*13*17*19*23=2e9

【trick】

【数据】
100 50
999999937 999999937 999999929 999999893 999999893 999999893 999999883 999999883 999999883 999999883 999999883 999999883 999999883 999999883 999999883

*/


#include<stdio.h>
#include<iostream>
#include<string.h>
#include<ctype.h>
#include<math.h>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<functional>
#include<string>
#include<algorithm>
#include<time.h>
#include<bitset>
void fre(){freopen("c://test//input.in","r",stdin);freopen("c://test//output.out","w",stdout);}
#define MS(x,y) memset(x,y,sizeof(x))
#define MC(x,y) memcpy(x,y,sizeof(x))
#define MP(x,y) make_pair(x,y)
#define ls o<<1
#define rs o<<1|1
typedef long long LL;
typedef unsigned long long UL;
typedef unsigned int UI;
template <class T> inline void gmax(T &a,T b){if(b>a)a=b;}
template <class T> inline void gmin(T &a,T b){if(b<a)a=b;}
using namespace std;
const int N=105,M=6000,Z=1e9+7,maxint=2147483647,ms31=522133279,ms63=1061109567,ms127=2139062143;const double eps=1e-8,PI=acos(-1.0);//.0
//最大边数为：（50*50+50+50）*2=5200
set<int>sot;
int id,ST,ED;
int n,m,g;
bool e[40000];
int p[10000],pnum;
int a[N],b[N],c[N],d[N],v[808];
int first[N];
int w[M],cap[M],nxt[M];
void prime()
{
	int top=sqrt(1e9+1e6);
	for(int i=2;i<=top;i++)if(e[i]==0)
	{
		p[++pnum]=i;
		for(int j=i+i;j<=top;j+=i)e[j]=1;
	}
}
void split1(int x)
{
	for(int i=1;p[i]*p[i]<=x;i++)
	{
		if(x%p[i]==0)
		{
			while(x%p[i]==0)x/=p[i];
			sot.insert(p[i]);
		}
	}
	if(x>1)sot.insert(x);
}
void split0(int x)
{
	for(int i=1;p[i]*p[i]<=x;i++)
	{
		if(x%p[i]==0)
		{
			while(x%p[i]==0)x/=p[i];
			if(sot.find(p[i])!=sot.end())
			{
				sot.erase(p[i]);
				v[++g]=p[i];
			}
		}
	}
	if(x>1)
	{
		if(sot.find(x)!=sot.end())
		{
			sot.erase(x);
			v[++g]=x;
		}
	}
}
void ins(int x,int y,int cap_)
{
	id++;
	w[id]=y;
	cap[id]=cap_;
	nxt[id]=first[x];
	first[x]=id;

	id++;
	w[id]=x;
	cap[id]=0;
	nxt[id]=first[y];
	first[y]=id;
}
int dep[N];
bool bfs()
{
	MS(dep,-1);dep[ST]=0;
	queue<int>q;q.push(ST);
	while(!q.empty())
	{
		int x=q.front();q.pop();
		for(int z=first[x];z;z=nxt[z])if(cap[z])
		{
			int y=w[z];
			if(dep[y]==-1)
			{
				dep[y]=dep[x]+1;
				if(y==ED)return 1;
				q.push(y);
			}
		}
	}
	return 0;
}
int dfs(int x,int all)
{
	if(x==ED)return all;
	int use=0;
	for(int z=first[x];z;z=nxt[z])if(cap[z])
	{
		int y=w[z];
		if(dep[y]==dep[x]+1)
		{
			int tmp=dfs(y,min(all-use,cap[z]));
			cap[z]-=tmp;
			cap[z^1]+=tmp;
			use+=tmp;
			if(use==all)break;
		}
	}
	if(use==0)dep[x]=-1;
	return use;
}
int dinic()
{
	int tmp=0;
	while(bfs())tmp+=dfs(ST,1500);//inf=30*50
	return tmp;
}
int main()
{
	prime();
	while(~scanf("%d%d",&n,&m))
	{
		for(int i=1;i<=n;i++)scanf("%d",&a[i]);
		for(int i=1;i<=m;i++)
		{
			scanf("%d%d",&b[i],&c[i]);
			if(c[i]&1)swap(b[i],c[i]);
		}
		sot.clear();
		g=0;
		for(int i=1;i<=n;i+=2)split1(a[i]);
		for(int i=2;i<=n;i+=2)split0(a[i]);
		int ans=0;
		ST=0;
		ED=n+1;
		for(int i=1;i<=g;i++)//枚举素数
		{
			MS(first,0);id=1;
			for(int j=1;j<=n;j++)if(a[j]%v[i]==0)//v[i]是a[j]的因子
			{
				d[j]=0;//d[j]表示a[j]里有几个v[i]
				while(a[j]%v[i]==0)
				{
					d[j]++;
					a[j]/=v[i];
				}
				if(j&1)ins(ST,j,d[j]);
				else ins(j,ED,d[j]);
			}
			for(int j=1;j<=m;j++)
			{
				int x=b[j];
				int y=c[j];
				int num=min(d[x],d[y]);
				if(num)ins(x,y,num);
			}
			ans+=dinic();
		}
		printf("%d\n",ans);
	}
	return 0;
}
/*
【题意】
题目说，有n个数从a[1]到a[n].
有m个pair，对于k∈[1,m]，每个pair(ik,jk)都有——
1<=ik<jk<=n且ik+jk为奇数（也就是ik和jk为一奇一偶）

每次操作可以取一个k和一个v（v>1），对应pair(ik,jk)，
然后我们得到a[ik],a[jk]，在v是a[ik]因子，也是a[jk]的因子的时候，我们使得a[ik]/=v,a[jk]/=v，并判定这个操作是成功的，

我们希望做尽可能多的成功操作，并输出这个操作次数。

题目保证所有的任意两个pair不同

【类型】
网络流

【分析】
首先，这道题设计到奇偶性质，我们很自然就想到了网络流。
然后，基于贪心原则，我们发现v必然一定取素数。

所有pair中的数非奇便偶，于是我们可以把点，根据下标，分成两类，奇点和偶点。
然后因为存在奇偶点间的匹配关系，所以考虑网络流解决。

思考了一会，依然发现是，先简化问题，再展开思考比较好。
如果v没得选，只能是某个素数。
我们可以这样——
1，对于每个奇数，数中含有几个v，就从超级源点向其建立容量为几的边
2，对于每个偶数，数中含有几个v，就从其向超级汇点建立容量为几的边
3，对于一个（奇数，偶数）pair，建一条边，容量为它们共有的v的数量。

然后开始跑最大流，我们发现，这个最大流，就是关于素数v，能实现的最多的匹配数。

这样，我们枚举所有的素数v，建图，跑最大流，求和。和便是最后的答案。

然而1e9范围的素数要爆炸啊。
只是这50个奇数内的素数的总数并不会太多。
我们可以先预处理出sqrt(1e9)范围内的所有素数。
然后对于每一个奇数，拆素数，得到的素数放set里
对于每一个偶数，再拆素数，得到的素数如果set中有，就作为一种被枚举的v
因为n和m并不大，所以感觉可以AC

实际15ms，帅爆了！网络流赛高！

【时间复杂度&&优化】
2*3*5*7*11*13*17*19*23=2e9

【trick】
这道题还是犯了很多愚蠢的错误
1，数组小心同名
2，如果我们要处理1e9内的素数并实现上封顶操作（就是for(int i=1;p[i]*p[i]<=x;i++），
	要有预处理素数的top=sqrt（1e9+1e6）。
3，细节！while(x%p[i]==0)x/=p[i];让我写成了while(x/p[i]==0)x/=p[i];我真是蠢炸天！

【数据】
Input
3 2
8 3 8
1 2
2 3
Output
0

Input
3 2
8 12 8
1 2
2 3
Output
2

*/


#include<stdio.h>
#include<iostream>
#include<string.h>
#include<ctype.h>
#include<math.h>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<functional>
#include<string>
#include<algorithm>
#include<time.h>
#include<bitset>
void fre(){freopen("c://test//input.in","r",stdin);freopen("c://test//output.out","w",stdout);}
#define MS(x,y) memset(x,y,sizeof(x))
#define MC(x,y) memcpy(x,y,sizeof(x))
#define MP(x,y) make_pair(x,y)
#define ls o<<1
#define rs o<<1|1
typedef long long LL;
typedef unsigned long long UL;
typedef unsigned int UI;
template <class T> inline void gmax(T &a,T b){if(b>a)a=b;}
template <class T> inline void gmin(T &a,T b){if(b<a)a=b;}
using namespace std;
const int N=105,M=6000,Z=1e9+7,maxint=2147483647,ms31=522133279,ms63=1061109567,ms127=2139062143;const double eps=1e-8,PI=acos(-1.0);//.0
//最大边数为：（50*50+50+50）*2=5200
set<int>sot;
int id,ST,ED;
int n,m,g;
bool e[40000];
int p[10000],pnum;
int a[105],b[105],c[105],d[105],v[808];
int first[N];
int w[M],cap[M],nxt[M];
void prime()
{
	int top=sqrt(1e9+1000);
	for(int i=2;i<=top;i++)if(e[i]==0)
	{
		p[++pnum]=i;
		for(int j=i+i;j<=top;j+=i)e[j]=1;
	}
}
void split1(int x)
{
	for(int i=1;p[i]*p[i]<=x;i++)
	{
		if(x%p[i]==0)
		{
			while(x/p[i]==0)x/=p[i];
			sot.insert(p[i]);
		}
	}
	if(x>1)sot.insert(x);
}
void split0(int x)
{
	for(int i=1;p[i]*p[i]<=x;i++)
	{
		if(x%p[i]==0)
		{
			while(x/p[i]==0)x/=p[i];
			if(sot.find(p[i])!=sot.end())
			{
				sot.erase(p[i]);
				v[++g]=p[i];
			}
		}
	}
	if(x>1)
	{
		if(sot.find(x)!=sot.end())
		{
			sot.erase(x);
			v[++g]=x;
		}
	}
}
void ins(int x,int y,int cap_)
{
	id++;
	w[id]=y;
	cap[id]=cap_;
	nxt[id]=first[x];
	first[x]=id;

	id++;
	w[id]=x;
	cap[id]=0;
	nxt[id]=first[y];
	first[y]=id;
}
int dep[105];
bool bfs()
{
	MS(dep,-1);dep[ST]=0;
	queue<int>q;q.push(ST);
	while(!q.empty())
	{
		int x=q.front();q.pop();
		for(int z=first[x];z;z=nxt[z])if(cap[z])
		{
			int y=w[z];
			if(dep[y]==-1)
			{
				dep[y]=dep[x]+1;
				if(y==ED)return 1;
				q.push(y);
			}
		}
	}
	return 0;
}
int dfs(int x,int all)
{
	if(x==ED)return all;
	int use=0;
	for(int z=first[x];z;z=nxt[z])if(cap[z])
	{
		int y=w[z];
		if(dep[y]==dep[x]+1)
		{
			int tmp=dfs(y,min(all-use,cap[z]));
			cap[z]-=tmp;
			cap[z^1]+=tmp;
			use+=tmp;
			if(use==all)break;
		}
	}
	if(use==0)dep[x]=-1;
	return use;
}
int dinic()
{
	int tmp=0;
	while(bfs())tmp+=dfs(ST,10000);//inf=30*50
	return tmp;
}
int main()
{
	prime();
	while(~scanf("%d%d",&n,&m))
	{
		for(int i=1;i<=n;i++)scanf("%d",&a[i]);
		for(int i=1;i<=m;i++)
		{
			scanf("%d%d",&b[i],&c[i]);
			if(c[i]&1)swap(b[i],c[i]);
		}
		sot.clear();
		g=0;
		for(int i=1;i<=n;i+=2)split1(a[i]);
		for(int i=2;i<=n;i+=2)split0(a[i]);
		int ans=0;
		ST=0;
		ED=n+1;
		for(int i=1;i<=g;i++)//枚举素数
		{
			MS(first,0);id=1;
			for(int j=1;j<=n;j++)if(a[j]%v[i]==0)//v[i]是a[j]的因子
			{
				d[j]=0;//d[j]表示a[j]里有几个v[i]
				while(a[j]%v[i]==0)
				{
					d[j]++;
					a[j]/=v[i];
				}
				if(j&1)
				{
					ins(ST,j,d[j]);
				}
				else
				{
					ins(j,ED,d[j]);
				}
			}
			for(int j=1;j<=m;j++)
			{
				int x=b[j];
				int y=c[j];
				int num=min(d[x],d[y]);
				if(num)ins(x,y,num);
			}
			ans+=dinic();
		}
		printf("%d\n",ans);
	}
	return 0;
}
/*
【题意】
题目说，有n个数从a[1]到a[n].
有m个pair，对于k∈[1,m]，每个pair(ik,jk)都有——
1<=ik<jk<=n且ik+jk为奇数（也就是ik和jk为一奇一偶）

每次操作可以取一个k和一个v（v>1），对应pair(ik,jk)，
然后我们得到a[ik],a[jk]，在v是a[ik]是a[jk]的因子的时候，我们使得a[ik]/=v,a[jk]/=v，并判定这个操作是成功的，

我们希望做尽可能多的成功操作，并输出这个操作次数。

题目保证所有的pair内的(x,y)都有x！=y

【类型】
网络流

【分析】
首先，这道题设计到奇偶性质，我们很自然就想到了网络流。
然后，我们发现v必然一定取素数。

所有pair中的数非奇便偶，于是我们可以把点分成两类，奇点和偶点。
然后因为存在奇偶点间的匹配关系。

思考了一会，依然发现从简化问题的方式入手比较好思考。
如果v没得选，只能是某个素数。
我们可以这样——
1，对于每个奇数，数中含有几个v，就从超级源点向其建立容量为几的边
2，对于每个偶数，数中含有几个v，就从其向超级汇点建立容量为几的边
3，对于一个（奇数，偶数）pair，建一条边，容量为它们共有的v的数量。

然后开始跑最大流，我们发现，这个最大流，就是关于素数v，能实现的最多的匹配数。

这样，我们枚举所有的素数v，建图，跑最大流，求和。和便是最后的答案。

然而1e9范围的素数要爆炸啊。
只是这50个奇数内的素数的总数并不会太多。
我们可以先预处理出sqrt(1e9)范围内的所有素数。
然后对于每一个奇数，拆素数，得到的素数放set里
对于每一个偶数，再拆素数，得到的素数如果set中有，就作为一种被枚举的v
因为n和m并不大，所以感觉可以AC

【时间复杂度&&优化】
2*3*5*7*11*13*17*19*23=2e9

【trick】

【数据】

*/


#include<stdio.h>
#include<iostream>
#include<string.h>
#include<ctype.h>
#include<math.h>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<functional>
#include<string>
#include<algorithm>
#include<time.h>
#include<bitset>
void fre(){freopen("c://test//input.in","r",stdin);freopen("c://test//output.out","w",stdout);}
#define MS(x,y) memset(x,y,sizeof(x))
#define MC(x,y) memcpy(x,y,sizeof(x))
#define MP(x,y) make_pair(x,y)
#define ls o<<1
#define rs o<<1|1
typedef long long LL;
typedef unsigned long long UL;
typedef unsigned int UI;
template <class T> inline void gmax(T &a,T b){if(b>a)a=b;}
template <class T> inline void gmin(T &a,T b){if(b<a)a=b;}
using namespace std;
const int N=105,M=12000,Z=1e9+7,maxint=2147483647,ms31=522133279,ms63=1061109567,ms127=2139062143;const double eps=1e-8,PI=acos(-1.0);//.0
//最大边数为：（50*50+50+50）*2=5200
set<int>sot;
int id,ST,ED;
int n,m,g;
bool e[40000];
int p[10000],pnum;
int a[105],b[105],c[105],d[105],v[808];
int first[N];
int w[M],cap[M],nxt[M];
void prime()
{
	int top=sqrt(1e9+1000);
	for(int i=2;i<=top;i++)if(e[i]==0)
	{
		p[++pnum]=i;
		for(int j=i+i;j<=top;j+=i)e[j]=1;
	}
}
void split1(int x)
{
	for(int i=1;p[i]*p[i]<=x;i++)
	{
		if(x%p[i]==0)
		{
			while(x/p[i]==0)x/=p[i];
			sot.insert(p[i]);
		}
	}
	if(x>1)sot.insert(x);
}
void split0(int x)
{
	for(int i=1;p[i]*p[i]<=x;i++)
	{
		if(x%p[i]==0)
		{
			while(x/p[i]==0)x/=p[i];
			if(sot.find(p[i])!=sot.end())
			{
				sot.erase(p[i]);
				v[++g]=p[i];
			}
		}
	}
	if(x>1)
	{
		if(sot.find(x)!=sot.end())
		{
			sot.erase(x);
			v[++g]=x;
		}
	}
}
void ins(int x,int y,int cap_)
{
	id++;
	w[id]=y;
	cap[id]=cap_;
	nxt[id]=first[x];
	first[x]=id;

	id++;
	w[id]=x;
	cap[id]=0;
	nxt[id]=first[y];
	first[y]=id;
}
int dep[105];
bool bfs()
{
	MS(dep,-1);dep[ST]=0;
	queue<int>q;q.push(ST);
	while(!q.empty())
	{
		int x=q.front();q.pop();
		for(int z=first[x];z;z=nxt[z])if(cap[z])
		{
			int y=w[z];
			if(dep[y]==-1)
			{
				dep[y]=dep[x]+1;
				if(y==ED)return 1;
				q.push(y);
			}
		}
	}
	return 0;
}
int dfs(int x,int all)
{
	if(x==ED)return all;
	int use=0;
	for(int z=first[x];z;z=nxt[z])if(cap[z])
	{
		int y=w[z];
		if(dep[y]==dep[x]+1)
		{
			int tmp=dfs(y,min(all-use,cap[z]));
			cap[z]-=tmp;
			cap[z^1]+=tmp;
			use+=tmp;
			if(use==all)break;
		}
	}
	if(use==0)dep[x]=-1;
	return use;
}
int dinic()
{
	int tmp=0;
	while(bfs())tmp+=dfs(ST,10000);//inf=30*50
	return tmp;
}
int main()
{
	prime();
	while(~scanf("%d%d",&n,&m))
	{
		for(int i=1;i<=n;i++)scanf("%d",&a[i]);
		for(int i=1;i<=m;i++)
		{
			scanf("%d%d",&b[i],&c[i]);
			if(c[i]&1)swap(b[i],c[i]);
		}
		sot.clear();
		g=0;
		for(int i=1;i<=n;i+=2)split1(a[i]);
		for(int i=2;i<=n;i+=2)split0(a[i]);
		int ans=0;
		ST=0;
		ED=n+1;
		for(int i=1;i<=g;i++)//枚举素数
		{
			MS(first,0);id=1;
			for(int j=1;j<=n;j++)if(a[j]%v[i]==0)//v[i]是a[j]的因子
			{
				d[j]=0;//d[j]表示a[j]里有几个v[i]
				while(a[j]%v[i]==0)
				{
					d[j]++;
					a[j]/=v[i];
				}
				if(j&1)
				{
					ins(ST,j,d[j]);
				}
				else
				{
					ins(j,ED,d[j]);
				}
			}
			for(int j=1;j<=m;j++)
			{
				int x=b[j];
				int y=c[j];
				int num=min(d[x],d[y]);
				if(num)ins(x,y,num);
			}
			ans+=dinic();
		}
		printf("%d\n",ans);
	}
	return 0;
}
/*
【题意】
题目说，有n个数从a[1]到a[n].
有m个pair，对于k∈[1,m]，每个pair(ik,jk)都有——
1<=ik<jk<=n且ik+jk为奇数（也就是ik和jk为一奇一偶）

每次操作可以取一个k和一个v（v>1），对应pair(ik,jk)，
然后我们得到a[ik],a[jk]，在v是a[ik]是a[jk]的因子的时候，我们使得a[ik]/=v,a[jk]/=v，并判定这个操作是成功的，

我们希望做尽可能多的成功操作，并输出这个操作次数。

题目保证所有的pair内的(x,y)都有x！=y

【类型】
网络流

【分析】
首先，这道题设计到奇偶性质，我们很自然就想到了网络流。
然后，我们发现v必然一定取素数。

所有pair中的数非奇便偶，于是我们可以把点分成两类，奇点和偶点。
然后因为存在奇偶点间的匹配关系。

思考了一会，依然发现从简化问题的方式入手比较好思考。
如果v没得选，只能是某个素数。
我们可以这样——
1，对于每个奇数，数中含有几个v，就从超级源点向其建立容量为几的边
2，对于每个偶数，数中含有几个v，就从其向超级汇点建立容量为几的边
3，对于一个（奇数，偶数）pair，建一条边，容量为它们共有的v的数量。

然后开始跑最大流，我们发现，这个最大流，就是关于素数v，能实现的最多的匹配数。

这样，我们枚举所有的素数v，建图，跑最大流，求和。和便是最后的答案。

然而1e9范围的素数要爆炸啊。
只是这50个奇数内的素数的总数并不会太多。
我们可以先预处理出sqrt(1e9)范围内的所有素数。
然后对于每一个奇数，拆素数，得到的素数放set里
对于每一个偶数，再拆素数，得到的素数如果set中有，就作为一种被枚举的v
因为n和m并不大，所以感觉可以AC

【时间复杂度&&优化】
2*3*5*7*11*13*17*19*23=2e9

【trick】

【数据】

*/


#include <cstdio>
#include <iostream>
#include <set>
#include <vector>
#include <algorithm>
#include <queue>
#include <cmath>
#define pii pair<int,int>
using namespace std;
const int maxn = 3e5+5;
typedef long long LL;
#define lowbit(x) (x&(-x))
int readint(){
    int x=0,f=1;char s=getchar();
    #define sc (s=getchar())
    while(s<'0'||s>'9'){
        if(s=='-')
            f=-1;
        sc;
    }
    while(s>='0'&&s<='9'){
        x=(x<<3)+(x<<1)+(s^48);
        sc;
    }
    #undef sc
    return x*f;
}
struct zz{
    int val,pos;
    zz(){};
    zz(int V,int P){
        val=V;
        pos=P;
    }
}a[maxn];
int b[maxn];
bool cmp(const zz &x,const zz &y){
    return x.val<y.val;
}
struct node{
    int a,b,d;
    node(){}
    node(int A,int B,int D){
        a=A;
        b=B;
        d=D;
    }
};
vector<node> ans;
int delta[maxn];
signed main (){
    int n=readint();
    for(int i=1;i<=n;i++){
        a[i].val=readint();
        a[i].pos=i;
    }
    sort(a+1,a+n+1,cmp);
    for(int i=1;i<=n;i++){
        b[i]=readint();
    }
    sort(b+1,b+n+1);
    LL res=0;
    for(int i=1;i<=n;i++){
        res+=(delta[i]=(a[i].val-b[i]));
        if(res>0){
            puts("NO");
            return 0;
        }
    }
    if(res!=0){
        puts("NO");
        return 0;
    }
    puts("YES");
    for(int i=1,j=1;i<=n;i++){
        while(delta[i]<0){
            while(delta[j]<=0)
                j++;
            if(delta[j]>=-delta[i]){
                ans.push_back(node(a[i].pos,a[j].pos,-delta[i]));
                delta[j]+=delta[i];
                delta[i]=0;
            }
            else if(delta[j]<-delta[i]){
                ans.push_back(node(a[i].pos,a[j].pos,delta[j]));
                delta[i]+=delta[j];
                delta[j]=0;
            }
        }
    }
    printf("%d\n",ans.size());
    for(int i=0;i<ans.size();i++){
        printf("%d %d %d\n",ans[i].a,ans[i].b,ans[i].d);
    }
    return 0;
}


#include <cstdio>
#include <iostream>
#include <set>
#include <vector>
#include <algorithm>
#include <queue>
#include <cmath>
#define pii pair<int,int>
using namespace std;
const int maxn = 3e5+5;
typedef long long LL;
#define lowbit(x) (x&(-x))
int readint(){
    int x=0,f=1;char s=getchar();
    #define sc (s=getchar())
    while(s<'0'||s>'9'){
        if(s=='-')
            f=-1;
        sc;
    }
    while(s>='0'&&s<='9'){
        x=(x<<3)+(x<<1)+(s^48);
        sc;
    }
    #undef sc
    return x*f;
}
struct zz{
    int val,pos;
    zz(){};
    zz(int V,int P){
        val=V;
        pos=P;
    }
}a[maxn];
int b[maxn];
bool cmp(const zz &x,const zz &y){
    return x.val<y.val;
}
queue<zz> q1,q2;
struct node{
    int a,b,d;
    node(){}
    node(int A,int B,int D){
        a=A;
        b=B;
        d=D;
    }
};
vector<node> ans;
signed main (){
    int n=readint();
    for(int i=1;i<=n;i++){
        a[i].val=readint();
        a[i].pos=i;
    }
    sort(a+1,a+n+1,cmp);
    for(int i=1;i<=n;i++){
        b[i]=readint();
    }
    sort(b+1,b+n+1);
    int res=0;
    for(int i=1;i<=n;i++){
        res+=a[i].val-b[i];
        if(a[i].val<b[i])
            q1.push(zz(b[i]-a[i].val,a[i].pos));
        else if(a[i].val>b[i])
            q2.push(zz(a[i].val-b[i],a[i].pos));
    }
    if(res!=0)
        return !printf("NO");
    while(!q1.empty()&&!q2.empty()){
        zz t=q1.front();
        q1.pop();
        while(!q2.empty()){
            zz t2=q2.front();
            q2.pop();
            if(t2.val>t.val&&t.val){
                q2.push(zz(t2.val-t.val,t2.pos));
                ans.push_back(node(t.pos,t2.pos,t.val));
                t.val=0;
                break;
            }
            if(t2.val==t.val){
                ans.push_back(node(t.pos,t2.pos,t.val));
                t.val=0;
                break;
            }
            if(t2.val<t.val){
                ans.push_back(node(t.pos,t2.pos,t2.val));
                t.val-=t2.val;
            }
        }
    }
    puts("YES");
    cout<<ans.size()<<endl;
    for(int i=0;i<ans.size();i++){
        printf("%d %d %d",ans[i].a,ans[i].b,ans[i].d);
        puts("");
    }
    return 0;
}


#include <cstdio>
#include <iostream>
#include <set>
#include <vector>
#include <algorithm>
#include <queue>
#include <cmath>
#define pii pair<int,int>
using namespace std;
const int maxn = 3e5+5;
typedef long long LL;
#define lowbit(x) (x&(-x))
int readint(){
    int x=0,f=1;char s=getchar();
    #define sc (s=getchar())
    while(s<'0'||s>'9'){
        if(s=='-')
            f=-1;
        sc;
    }
    while(s>='0'&&s<='9'){
        x=(x<<3)+(x<<1)+(s^48);
        sc;
    }
    #undef sc
    return x*f;
}
struct zz{
    int val,pos;
    zz(){};
    zz(int V,int P){
        val=V;
        pos=P;
    }
}a[maxn];
int b[maxn];
bool cmp(const zz &x,const zz &y){
    return x.val<y.val;
}
struct node{
    int a,b,d;
    node(){}
    node(int A,int B,int D){
        a=A;
        b=B;
        d=D;
    }
};
vector<node> ans;
int delta[maxn];
signed main (){
    int n=readint();
    for(int i=1;i<=n;i++){
        a[i].val=readint();
        a[i].pos=i;
    }
    sort(a+1,a+n+1,cmp);
    for(int i=1;i<=n;i++){
        b[i]=readint();
    }
    sort(b+1,b+n+1);
    int res=0;
    for(int i=1;i<=n;i++){
        res+=(delta[i]=(a[i].val-b[i]));
        if(res>0){
            puts("NO");
            return 0;
        }
    }
    if(res!=0){
        puts("NO");
        return 0;
    }
    puts("YES");
    for(int i=1,j=1;i<=n;i++){
        while(delta[i]<0){
            while(delta[j]<=0)
                j++;
            if(delta[j]>=-delta[i]){
                ans.push_back(node(a[i].pos,a[j].pos,-delta[i]));
                delta[j]+=delta[i];
                delta[i]=0;
            }
            else if(delta[j]<-delta[i]){
                ans.push_back(node(a[i].pos,a[j].pos,delta[j]));
                delta[i]+=delta[j];
                delta[j]=0;
            }
        }
    }
    printf("%d\n",ans.size());
    for(int i=0;i<ans.size();i++){
        printf("%d %d %d\n",ans[i].a,ans[i].b,ans[i].d);
    }
    return 0;
}


#include <cstdio>
#include <iostream>
#include <set>
#include <vector>
#include <algorithm>
#include <queue>
#include <cmath>
#define pii pair<int,int>
using namespace std;
const int maxn = 3e5+5;
typedef long long LL;
#define lowbit(x) (x&(-x))
int readint(){
    int x=0,f=1;char s=getchar();
    #define sc (s=getchar())
    while(s<'0'||s>'9'){
        if(s=='-')
            f=-1;
        sc;
    }
    while(s>='0'&&s<='9'){
        x=(x<<3)+(x<<1)+(s^48);
        sc;
    }
    #undef sc
    return x*f;
}
struct zz{
    int val,pos;
    zz(){};
    zz(int V,int P){
        val=V;
        pos=P;
    }
}a[maxn];
int b[maxn];
bool cmp(const zz &x,const zz &y){
    return x.val<y.val;
}
struct node{
    int a,b,d;
    node(){}
    node(int A,int B,int D){
        a=A;
        b=B;
        d=D;
    }
};
vector<node> ans;
int delta[maxn];
signed main (){
    int n=readint();
    for(int i=1;i<=n;i++){
        a[i].val=readint();
        a[i].pos=i;
    }
    sort(a+1,a+n+1,cmp);
    for(int i=1;i<=n;i++){
        b[i]=readint();
    }
    sort(b+1,b+n+1);
    LL res=0;
    for(int i=1;i<=n;i++){
        delta[i]=(a[i].val-b[i]);
        res+=delta[i];
        if(res>0){
            puts("NO");
            return 0;
        }
    }
    if(res!=0){
        puts("NO");
        return 0;
    }
    puts("YES");
    for(int i=1,j=1;i<=n;i++){
        while(delta[i]<0){
            while(delta[j]<=0)
                j++;
            int t=min(delta[j],-delta[i]);
            ans.push_back(node(a[i].pos,a[j].pos,t));
            delta[j]-=t;
            delta[i]+=t;
        }
    }
    printf("%d\n",ans.size());
    for(int i=0;i<ans.size();i++){
        printf("%d %d %d\n",ans[i].a,ans[i].b,ans[i].d);
    }
    return 0;
}


#include <cstdio>
#include <iostream>
#include <set>/////
#include <vector>
#include <algorithm>
#include <queue>
#include <cmath>
#define pii pair<int,int>
using namespace std;
const int maxn = 3e5+5;
typedef long long LL;
#define int LL
#define lowbit(x) (x&(-x))
int readint(){
    int x=0,f=1;char s=getchar();
    #define sc (s=getchar())
    while(s<'0'||s>'9'){
        if(s=='-')
            f=-1;
        sc;
    }
    while(s>='0'&&s<='9'){
        x=(x<<3)+(x<<1)+(s^48);
        sc;
    }
    #undef sc
    return x*f;
}
struct zz{
    int val,pos;
    zz(){};
    zz(int V,int P){
        val=V;
        pos=P;
    }
}a[maxn];
int b[maxn];
bool cmp(const zz &x,const zz &y){
    return x.val<y.val;
}
queue<zz> q1,q2;
struct node{
    int a,b,d;
    node(){}
    node(int A,int B,int D){
        a=A;
        b=B;
        d=D;
    }
};
vector<node> ans;
signed main (){
    int n=readint();
    for(int i=1;i<=n;i++){
        a[i].val=readint();
        a[i].pos=i;
    }
    sort(a+1,a+n+1,cmp);
    for(int i=1;i<=n;i++){
        b[i]=readint();
    }
    sort(b+1,b+n+1);
    int res=0;
    for(int i=1;i<=n;i++){
        res+=(a[i].val-b[i]);
        if(a[i].val<b[i])
            q1.push(zz(b[i]-a[i].val,a[i].pos));
        else if(a[i].val>b[i])
            q2.push(zz(a[i].val-b[i],a[i].pos));
    }
    if(res!=0)
        return !printf("NO");
    while(!q1.empty()&&!q2.empty()){
        zz t=q1.front();
        q1.pop();
        while(!q2.empty()){
            zz t2=q2.front();
            q2.pop();
            if(t2.val>t.val){
                q2.push(zz(t2.val-t.val,t2.pos));
                ans.push_back(node(t.pos,t2.pos,t.val));
                t.val=0;
                break;
            }
            if(t2.val==t.val){
                ans.push_back(node(t.pos,t2.pos,t.val));
                t.val=0;
                break;
            }
            if(t2.val<t.val){
                ans.push_back(node(t.pos,t2.pos,t2.val));
                t.val-=t2.val;
            }
        }
    }
    puts("YES");
    cout<<ans.size()<<endl;
    for(int i=0;i<ans.size();i++){
        printf("%d %d %d",ans[i].a,ans[i].b,ans[i].d);
        puts("");
    }
    return 0;
}


#include <cstdio>
#include <iostream>
#include <set>
#include <vector>
#include <algorithm>
#include <queue>
#include <cmath>
#define pii pair<int,int>
using namespace std;
const int maxn = 3e5+5;
typedef long long LL;
#define lowbit(x) (x&(-x))
int readint(){
    int x=0,f=1;char s=getchar();
    #define sc (s=getchar())
    while(s<'0'||s>'9'){
        if(s=='-')
            f=-1;
        sc;
    }
    while(s>='0'&&s<='9'){
        x=(x<<3)+(x<<1)+(s^48);
        sc;
    }
    #undef sc
    return x*f;
}
struct zz{
    int val,pos;
    zz(){};
    zz(int V,int P){
        val=V;
        pos=P;
    }
}a[maxn];
int b[maxn];
bool cmp(const zz &x,const zz &y){
    return x.val<y.val;
}
struct node{
    int a,b,d;
    node(){}
    node(int A,int B,int D){
        a=A;
        b=B;
        d=D;
    }
};
vector<node> ans;
int delta[maxn];
signed main (){
    int n=readint();
    for(int i=1;i<=n;i++){
        a[i].val=readint();
        a[i].pos=i;
    }
    sort(a+1,a+n+1,cmp);
    for(int i=1;i<=n;i++){
        b[i]=readint();
    }
    sort(b+1,b+n+1);
    int res=0;
    for(int i=1;i<=n;i++){
        delta[i]=(a[i].val-b[i]);
        res+=delta[i];
        if(res>0){
            puts("NO");
            return 0;
        }
    }
    if(res!=0){
        puts("NO");
        return 0;
    }
    puts("YES");
    for(int i=1,j=1;i<=n;i++){
        while(delta[i]<0){
            while(delta[j]<=0)
                j++;
            int t=min(delta[j],-delta[i]);
            ans.push_back(node(a[i].pos,a[j].pos,t));
            delta[j]-=t;
            delta[i]+=t;
        }
    }
    printf("%d\n",ans.size());
    for(int i=0;i<ans.size();i++){
        printf("%d %d %d\n",ans[i].a,ans[i].b,ans[i].d);
    }
    return 0;
}


#include <cstdio>
#include <iostream>
#include <set>
#include <vector>
#include <algorithm>
#include <queue>
#include <cmath>
#define pii pair<int,int>
using namespace std;
const int maxn = 3e5+5;
typedef long long LL;
#define int LL
#define lowbit(x) (x&(-x))
int readint(){
    int x=0,f=1;char s=getchar();
    #define sc (s=getchar())
    while(s<'0'||s>'9'){
        if(s=='-')
            f=-1;
        sc;
    }
    while(s>='0'&&s<='9'){
        x=(x<<3)+(x<<1)+(s^48);
        sc;
    }
    #undef sc
    return x*f;
}
struct zz{
    int val,pos;
    zz(){};
    zz(int V,int P){
        val=V;
        pos=P;
    }
}a[maxn];
int b[maxn];
bool cmp(const zz &x,const zz &y){
    return x.val<y.val;
}
queue<zz> q1,q2;
struct node{
    int a,b,d;
    node(){}
    node(int A,int B,int D){
        a=A;
        b=B;
        d=D;
    }
};
vector<node> ans;
signed main (){
    int n=readint();
    for(int i=1;i<=n;i++){
        a[i].val=readint();
        a[i].pos=i;
    }
    sort(a+1,a+n+1,cmp);
    for(int i=1;i<=n;i++){
        b[i]=readint();
    }
    sort(b+1,b+n+1);
    int res=0;
    for(int i=1;i<=n;i++){
        res+=(a[i].val-b[i]);
        if(a[i].val<b[i])
            q1.push(zz(b[i]-a[i].val,a[i].pos));
        else if(a[i].val>b[i])
            q2.push(zz(a[i].val-b[i],a[i].pos));
    }
    if(res!=0)
        return !printf("NO");
    while(!q1.empty()&&!q2.empty()){
        zz t=q1.front();
        q1.pop();
        while(!q2.empty()){
            zz t2=q2.front();
            q2.pop();
            if(t2.val>t.val){
                q2.push(zz(t2.val-t.val,t2.pos));
                ans.push_back(node(t.pos,t2.pos,t.val));
                t.val=0;
                break;
            }
            if(t2.val==t.val){
                ans.push_back(node(t.pos,t2.pos,t.val));
                t.val=0;
                break;
            }
            if(t2.val<t.val){
                ans.push_back(node(t.pos,t2.pos,t2.val));
                t.val-=t2.val;
            }
        }
    }
    puts("YES");
    cout<<ans.size()<<endl;
    for(int i=0;i<ans.size();i++){
        printf("%d %d %d",ans[i].a,ans[i].b,ans[i].d);
        puts("");
    }
    return 0;
}


#include <cstdio>
#include <iostream>
#include <set>
#include <vector>
#include <algorithm>
#include <queue>
#include <cmath>
#define pii pair<int,int>
using namespace std;
const int maxn = 3e5+5;
typedef long long LL;
#define lowbit(x) (x&(-x))
int readint(){
    int x=0,f=1;char s=getchar();
    #define sc (s=getchar())
    while(s<'0'||s>'9'){
        if(s=='-')
            f=-1;
        sc;
    }
    while(s>='0'&&s<='9'){
        x=(x<<3)+(x<<1)+(s^48);
        sc;
    }
    #undef sc
    return x*f;
}
struct zz{
    int val,pos;
    zz(){};
    zz(int V,int P){
        val=V;
        pos=P;
    }
}a[maxn];
int b[maxn];
bool cmp(const zz &x,const zz &y){
    return x.val<y.val;
}
struct node{
    int a,b,d;
    node(){}
    node(int A,int B,int D){
        a=A;
        b=B;
        d=D;
    }
};
vector<node> ans;
int delta[maxn];
signed main (){
    int n=readint();
    for(int i=1;i<=n;i++){
        a[i].val=readint();
        a[i].pos=i;
    }
    sort(a+1,a+n+1,cmp);
    for(int i=1;i<=n;i++){
        b[i]=readint();
    }
    sort(b+1,b+n+1);
    int res=0;
    for(int i=1;i<=n;i++){
        res+=(delta[i]=(a[i].val-b[i]));
        if(res>0){
            puts("NO");
            return 0;
        }
    }
    if(res!=0){
        puts("NO");
        return 0;
    }
    puts("YES");
    for(int i=1,j=1;i<=n;i++){
        while(delta[i]<0){
            while(delta[j]<=0)
                j++;
            if(delta[j]>=delta[i]){
                ans.push_back(node(a[i].pos,a[j].pos,-delta[i]));
                delta[j]+=delta[i];
                delta[i]=0;
            }
            else
            {
                ans.push_back(node(a[i].pos,a[j].pos,delta[j]));
                delta[i]+=delta[j];
                delta[j]=0;
            }
        }
    }
    printf("%d\n",ans.size());
    for(int i=0;i<ans.size();i++){
        printf("%d %d %d\n",ans[i].a,ans[i].b,ans[i].d);
    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;

#define int int64_t

vector<int> readVector(int n) {
  vector<int> ans(n);
  for(int i=0;i<n;i++)cin>>ans[i];
  return ans;
}

struct Swap {
  int i,j,d;
  Swap(int i_, int j_, int d_) :i(i_), j(j_), d(d_){}
};

main() {
  // freopen("input.txt", "r", stdin);
  // freopen("output.txt", "w", stdout);

  ios_base::sync_with_stdio(false);
  cin.tie(NULL);

  int n;
  cin>>n;
  vector<pair<int, int> > s(n); // (pos, stone_id)
  for(int i=0;i<n;i++) {
    int pos;
    cin>>pos;
    s[i] = make_pair(pos, i+1);
  }
  vector<int> t = readVector(n);
  sort(s.begin(), s.end());
  sort(t.begin(), t.end());

  vector<Swap> swaps;
  stack<pair<int, int> > stck; // (delta, stone_id)
  for(int i=0;i<n;i++) {
    int stone_id = s[i].second;
    int delta = t[i]-s[i].first;
    if (delta > 0) {
      stck.push(make_pair(delta, stone_id));
    } else if(delta < 0) {
      while(delta<0 && !stck.empty()) {
        int mov = min(-delta, stck.top().first);
        swaps.push_back(Swap(stck.top().second, stone_id, mov));
        delta += mov;
        stck.top().first -= mov;
        if (stck.top().first==0){
          stck.pop();
        }
      }
      if (delta<0 && stck.empty()) {
        cout << "NO\n";
        return 0;
      }
    }
  }

  if(!stck.empty()) {
    cout << "NO\n";
    return 0;
  }

  cout <<"YES\n";
  cout << swaps.size() << "\n";
  for(auto sw:swaps)cout<<sw.i<<" "<<sw.j<<" "<<sw.d<<"\n";

  return 0;
}


#include<bits/stdc++.h>
using namespace std;

#define int int64_t

vector<int> readVector(int n) {
  vector<int> ans(n);
  for(int i=0;i<n;i++)cin>>ans[i];
  return ans;
}

struct Swap {
  int i,j,d;
};

main() {
  //freopen("input.txt", "r", stdin);
  //freopen("output.txt", "w", stdout);

  ios_base::sync_with_stdio(false);
  cin.tie(NULL);

  int n;
  cin>>n;
  vector<pair<int, int> > s(n);
  for(int i=0;i<n;i++) {
    int pos;
    cin>>pos;
    s[i] = make_pair(pos, i+1);
  }
  vector<int> t = readVector(n);
  sort(s.begin(), s.end());
  sort(t.begin(), t.end());

  int sum=0;
  for(int i=0;i<n;i++)sum+=s[i].first - t[i];
  if(sum!=0) {
    cout <<"NO\n";
    return 0;
  }

  int p1 = 0;
  int p2 = n-1;

  vector<Swap> swaps;

  while(true) {
    while(s[p1].first==t[p1] && p1<p2)p1++;
    while(s[p2].first==t[p2] && p1<p2)p2--;
    if(p1>=p2) break;

    int d1 = t[p1]-s[p1].first;
    int d2 = s[p2].first - t[p2];
    if(d1<0 || d2<0) {cout<<"NO\n"; return 0;}
    int d = min(d1, d2);

    Swap sw = {s[p1].second, s[p2].second, d};
    s[p1].first+=d;
    s[p2].first-=d;
    swaps.push_back(sw);
  }

  cout <<"YES\n";
  cout << swaps.size() << "\n";
  for(auto sw:swaps)cout<<sw.i<<" "<<sw.j<<" "<<sw.d<<"\n";

  return 0;
}


#include<bits/stdc++.h>
using namespace std;

#define int int64_t

vector<int> readVector(int n) {
  vector<int> ans(n);
  for(int i=0;i<n;i++)cin>>ans[i];
  return ans;
}

struct Swap {
  int i,j,d;
  Swap(int i_, int j_, int d_) :i(i_), j(j_), d(d_){}
};

main() {
  freopen("input.txt", "r", stdin);
  //freopen("output.txt", "w", stdout);

  ios_base::sync_with_stdio(false);
  cin.tie(NULL);

  int n;
  cin>>n;
  vector<pair<int, int> > s(n); // (pos, stone_id)
  for(int i=0;i<n;i++) {
    int pos;
    cin>>pos;
    s[i] = make_pair(pos, i+1);
  }
  vector<int> t = readVector(n);
  sort(s.begin(), s.end());
  sort(t.begin(), t.end());

  vector<Swap> swaps;
  stack<pair<int, int> > stck; // (delta, stone_id)
  for(int i=0;i<n;i++) {
    int stone_id = s[i].second;
    int delta = t[i]-s[i].first;
    if (delta > 0) {
      stck.push(make_pair(delta, stone_id));
    } else if(delta < 0) {
      while(delta<0 && !stck.empty()) {
        int mov = min(-delta, stck.top().first);
        swaps.push_back(Swap(stck.top().second, stone_id, mov));
        delta += mov;
        stck.top().first -= mov;
        if (stck.top().first==0){
          stck.pop();
        }
      }
      if (delta<0 && stck.empty()) {
        cout << "NO\n";
        return 0;
      }
    }
  }

  if(!stck.empty()) {
    cout << "NO\n";
    return 0;
  }

  cout <<"YES\n";
  cout << swaps.size() << "\n";
  for(auto sw:swaps)cout<<sw.i<<" "<<sw.j<<" "<<sw.d<<"\n";

  return 0;
}


#include<bits/stdc++.h>
using namespace std;

#define int int64_t

vector<int> readVector(int n) {
  vector<int> ans(n);
  for(int i=0;i<n;i++)cin>>ans[i];
  return ans;
}

struct Swap {
  int i,j,d;
};

main() {
  //freopen("input.txt", "r", stdin);
  //freopen("output.txt", "w", stdout);

  ios_base::sync_with_stdio(false);
  cin.tie(NULL);

  int n;
  cin>>n;
  vector<pair<int, int> > s(n);
  for(int i=0;i<n;i++) {
    int pos;
    cin>>pos;
    s[i] = make_pair(pos, i+1);
  }
  vector<int> t = readVector(n);
  sort(s.begin(), s.end());
  sort(t.begin(), t.end());

  int sum=0;
  for(int i=0;i<n;i++)sum+=s[i].first - t[i];
  if(sum!=0) {
    cout <<"NO\n";
    return 0;
  }

  int p1 = 0;
  int p2 = n-1;

  vector<Swap> swaps;

  while(true) {
    while(s[p1].first==t[p1] && p1<p2)p1++;
    while(s[p2].first==t[p2] && p1<p2)p2--;
    if(p1>=p2) break;

    int d1 = t[p1]-s[p1].first;
    int d2 = s[p2].first - t[p2];
    if(d1<0 || d2<0) {cout<<"NO\n"; return 0;}
    int d = min(d1, d2);

    Swap sw = {s[p1].second, s[p2].second, d};
    s[p1].first+=d;
    s[p2].first-=d;

    int z1 = p1;
    while(z1!=n-1 && s[z1].first>s[z1+1].first){swap(s[z1], s[z1+1]); z1++;}
    int z2 = p2;
    while(z2!=0 && s[z2].first<s[z2-1].first){swap(s[z2], s[z2-1]); z2--;}

    swaps.push_back(sw);
  }

  cout <<"YES\n";
  cout << swaps.size() << "\n";
  for(auto sw:swaps)cout<<sw.i<<" "<<sw.j<<" "<<sw.d<<"\n";

  return 0;
}


#include<iostream>
#include<cstdio>
#include<queue>
#include<stack>
#include<cstring>
#include<algorithm>
#include<vector>
#include<cmath>
using namespace std;
int n;
long long sum;
struct node
{
	int a,id,at;
}p[3000001],t1[3000001],t2[3000001];
struct answer
{
	int x,y,d;
}ans[3000001];
int tot;
bool cmp1(node a1,node a2)
{
	return a1.a<a2.a;
}
int b[3000001];
signed main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
		scanf("%d",&p[i].a),p[i].id=i,sum=(long long)sum+p[i].a;
	for(int i=1;i<=n;i++)
		scanf("%d",&b[i]),sum=(long long)sum-b[i];
	sort(p+1,p+n+1,cmp1);
	sort(b+1,b+n+1);
	if(sum!=0)
	{
		printf("NO");
		return 0;
	}

	int cnt1=0,cnt2=0;
	for(int i=1;i<=n;i++)
		if(p[i].a<b[i])
		{
			t1[++cnt1]=p[i];
			t1[cnt1].at=i;
		}
		else
		{
			t2[++cnt2]=p[i];
			t2[cnt2].at=i;
		}

	int r=1;
	for(int i=1;i<=cnt1;i++)
	{
		while(t1[i].a!=b[t1[i].at])
		{
			int d=min(b[t1[i].at]-t1[i].a,t2[r].a-b[t2[r].at]);

			ans[++tot].x=t1[i].id,ans[tot].y=t2[r].id,ans[tot].d=d;

			t2[r].a-=d;
			t1[i].a+=d;

			if(t2[r].a==b[t2[r].at]) r++;
		}
	}
	printf("YES\n");
	printf("%d\n",tot);
	for(int i=1;i<=tot;i++)
		printf("%d %d %d\n",ans[i].x,ans[i].y,ans[i].d);
    return 0;
}


#include<iostream>
#include<cstdio>
#include<queue>
#include<stack>
#include<cstring>
#include<algorithm>
#include<vector>
#include<cmath>
using namespace std;
int n;
long long sum;
struct node
{
	int a,id,at;
}p[3000001],t1[3000001],t2[3000001];
struct answer
{
	int x,y,d;
}ans[3000001];
int tot;
bool cmp1(node a1,node a2)
{
	return a1.a<a2.a;
}
int b[3000001];
signed main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
		scanf("%d",&p[i].a),p[i].id=i,sum=(long long)sum+p[i].a;
	for(int i=1;i<=n;i++)
		scanf("%d",&b[i]),sum=(long long)sum-b[i];
	sort(p+1,p+n+1,cmp1);
	sort(b+1,b+n+1);
	if(sum!=0)
	{
		printf("NO");
		return 0;
	}

	int cnt1=0,cnt2=0;
	for(int i=1;i<=n;i++)
		if(p[i].a<b[i])
		{
			t1[++cnt1]=p[i];
			t1[cnt1].at=i;
		}
		else
		{
			t2[++cnt2]=p[i];
			t2[cnt2].at=i;
		}

	int r=cnt2;
	for(int i=cnt1;i>=1;i--)
	{
		while(t1[i].a!=b[t1[i].at])
		{
			if(t1[i].a>t2[r].a)
			{
				printf("NO");
				return 0;
			}
			int d=min(b[t1[i].at]-t1[i].a,t2[r].a-b[t2[r].at]);

			ans[++tot].x=t1[i].id,ans[tot].y=t2[r].id,ans[tot].d=d;

			t2[r].a-=d;
			t1[i].a+=d;

			if(t2[r].a==b[t2[r].at]) r--;
		}
	}
	printf("YES\n");
	printf("%d\n",tot);
	for(int i=1;i<=tot;i++)
		printf("%d %d %d\n",ans[i].x,ans[i].y,ans[i].d);
    return 0;
}


#include<iostream>
#include<cstdio>
#include<queue>
#include<stack>
#include<cstring>
#include<algorithm>
#include<vector>
#include<cmath>
using namespace std;
int n;
long long sum;
struct node
{
	int a,id,at;
}p[3000001],t1[3000001],t2[3000001];
struct answer
{
	int x,y,d;
}ans[3000001];
int tot;
bool cmp1(node a1,node a2)
{
	return a1.a<a2.a;
}
int b[3000001];
signed main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
		scanf("%d",&p[i].a),p[i].id=i,sum=(long long)sum+p[i].a;
	for(int i=1;i<=n;i++)
		scanf("%d",&b[i]),sum=(long long)sum-b[i];
	sort(p+1,p+n+1,cmp1);
	sort(b+1,b+n+1);
	if(sum!=0)
	{
		printf("NO");
		return 0;
	}

	int cnt1=0,cnt2=0;
	for(int i=1;i<=n;i++)
		if(p[i].a<b[i])
		{
			t1[++cnt1]=p[i];
			t1[cnt1].at=i;
		}
		else
		{
			t2[++cnt2]=p[i];
			t2[cnt2].at=i;
		}

	int r=cnt2;
	for(int i=cnt1;i>=1;i--)
	{
		while(t1[i].a!=b[t1[i].at])
		{
			if(t1[i].a>t2[r].at)
			{
				printf("NO");
				return 0;
			}
			int d=min(b[t1[i].at]-t1[i].a,t2[r].a-b[t2[r].at]);

			ans[++tot].x=t1[i].id,ans[tot].y=t2[r].id,ans[tot].d=d;

			t2[r].a-=d;
			t1[i].a+=d;

			if(t2[r].a==b[t2[r].at]) r--;
		}
	}
	printf("YES\n");
	printf("%d\n",tot);
	for(int i=1;i<=tot;i++)
		printf("%d %d %d\n",ans[i].x,ans[i].y,ans[i].d);
    return 0;
}


#include<iostream>
#include<cstdio>
#include<queue>
#include<stack>
#include<cstring>
#include<algorithm>
#include<vector>
#include<cmath>
using namespace std;
int n;
long long sum;
struct node
{
	int a,id,at;
}p[3000001],t1[3000001],t2[3000001];
struct answer
{
	int x,y,d;
}ans[4000001];
int tot;
bool cmp1(node a1,node a2)
{
	return a1.a<a2.a;
}
int b[3000001];
signed main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
		scanf("%d",&p[i].a),p[i].id=i,sum=(long long)sum+p[i].a;
	for(int i=1;i<=n;i++)
		scanf("%d",&b[i]),sum=(long long)sum-b[i];
	sort(p+1,p+n+1,cmp1);
	sort(b+1,b+n+1);
	if(sum!=0)
	{
		printf("NO");
		return 0;
	}

	int cnt1=0,cnt2=0;
	for(int i=1;i<=n;i++)
		if(p[i].a<b[i])
		{
			t1[++cnt1]=p[i];
			t1[cnt1].at=i;
		}
		else
		{
			t2[++cnt2]=p[i];
			t2[cnt2].at=i;
		}

	int r=cnt2;
	for(int i=cnt1;i>=1;i--)
	{
		while(t1[i].a!=b[t1[i].at])
		{
			if(t1[i].a>t2[r].a)
			{
				printf("NO");
				return 0;
			}
			int d=min(b[t1[i].at]-t1[i].a,t2[r].a-b[t2[r].at]);

			ans[++tot].x=t1[i].id,ans[tot].y=t2[r].id,ans[tot].d=d;

			t2[r].a-=d;
			t1[i].a+=d;

			if(t2[r].a==b[t2[r].at]) r--;
		}
	}
	printf("YES\n");
	printf("%d\n",tot);
	for(int i=1;i<=tot;i++)
		printf("%d %d %d\n",ans[i].x,ans[i].y,ans[i].d);
    return 0;
}


#include<iostream>
#include<cstdio>
#include<queue>
#include<stack>
#include<cstring>
#include<algorithm>
#include<vector>
#include<cmath>
using namespace std;
int n;
long long sum;
struct node
{
	int a,id,at;
}p[3000001],t1[3000001],t2[3000001];
struct answer
{
	int x,y,d;
}ans[3000001];
int tot;
bool cmp1(node a1,node a2)
{
	return a1.a<a2.a;
}
int b[3000001];
signed main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
		scanf("%d",&p[i].a),p[i].id=i,sum=(long long)sum+p[i].a;
	for(int i=1;i<=n;i++)
		scanf("%d",&b[i]),sum=(long long)sum-b[i];
	sort(p+1,p+n+1,cmp1);
	sort(b+1,b+n+1);
	if(sum!=0)
	{
		printf("NO");
		return 0;
	}

	int cnt1=0,cnt2=0;
	for(int i=1;i<=n;i++)
		if(p[i].a<b[i])
		{
			t1[++cnt1]=p[i];
			t1[cnt1].at=i;
		}
		else
		{
			t2[++cnt2]=p[i];
			t2[cnt2].at=i;
		}

	int r=1;
	for(int i=1;i<=cnt1;i++)
	{
		while(t1[i].a!=b[t1[i].at])
		{
			if(t2[r].a<t1[i].a)
			{
				printf("NO");
				return 0;
			}
			int d=min(b[t1[i].at]-t1[i].a,t2[r].a-b[t2[r].at]);

			ans[++tot].x=t1[i].id,ans[tot].y=t2[r].id,ans[tot].d=d;

			t2[r].a-=d;
			t1[i].a+=d;

			if(t2[r].a==b[t2[r].at]) r++;
		}
	}
	printf("YES\n");
	printf("%d\n",tot);
	for(int i=1;i<=tot;i++)
		printf("%d %d %d\n",ans[i].x,ans[i].y,ans[i].d);
    return 0;
}
/*
5
9 4 7 2 2
5 4 5 5 5

*/


#include<iostream>
#include<cstdio>
#include<queue>
#include<stack>
#include<cstring>
#include<algorithm>
#include<vector>
#include<cmath>
using namespace std;
int n;
long long sum;
struct node
{
	int a,id;
}p[3000001];
struct answer
{
	int x,y,d;
}ans[3000001];
int tot;
bool cmp1(node a1,node a2)
{
	return a1.a<a2.a;
}
int b[3000001];
signed main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
		scanf("%d",&p[i].a),p[i].id=i,sum=(long long)sum+p[i].a;
	for(int i=1;i<=n;i++)
		scanf("%d",&b[i]),sum=(long long)sum-b[i];
	sort(p+1,p+n+1,cmp1);
	sort(b+1,b+n+1);
	if(sum==0)
	{
		printf("YES\n");
	}
	else
	{
		printf("NO");
		return 0;
	}
	int r=n;
	for(int i=1;i<r;i++)
		while(p[i].a!=b[i])
		{
			int d=min(b[i]-p[i].a,p[r].a-b[r]);
			ans[++tot].x=p[i].id,ans[tot].y=p[r].id,ans[tot].d=d;
			p[r].a-=d;
			p[i].a+=d;
			if(p[r].a==b[r]) r--;
		}
	printf("%d\n",tot);
	for(int i=1;i<=tot;i++)
		printf("%d %d %d\n",ans[i].x,ans[i].y,ans[i].d);
    return 0;
}
/*
10
1 8 7 6 3 4 9 10 5 2
*/


#include<bits/stdc++.h>
clock_t t=clock();
namespace my_std{
	using namespace std;
	#define pii pair<int,int>
	#define fir first
	#define sec second
	#define MP make_pair
	#define rep(i,x,y) for (int i=(x);i<=(y);i++)
	#define drep(i,x,y) for (int i=(x);i>=(y);i--)
	#define go(x) for (int i=head[x];i;i=edge[i].nxt)
	#define templ template<typename T>
	#define sz 303030
	typedef long long ll;
	typedef double db;
	mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
	templ inline T rnd(T l,T r) {return uniform_int_distribution<T>(l,r)(rng);}
	templ inline bool chkmax(T &x,T y){return x<y?x=y,1:0;}
	templ inline bool chkmin(T &x,T y){return x>y?x=y,1:0;}
	templ inline void read(T& t)
	{
		t=0;char f=0,ch=getchar();double d=0.1;
		while(ch>'9'||ch<'0') f|=(ch=='-'),ch=getchar();
		while(ch<='9'&&ch>='0') t=t*10+ch-48,ch=getchar();
		if(ch=='.'){ch=getchar();while(ch<='9'&&ch>='0') t+=d*(ch^48),d*=0.1,ch=getchar();}
		t=(f?-t:t);
	}
	template<typename T,typename... Args>inline void read(T& t,Args&... args){read(t); read(args...);}
	char __sr[1<<21],__z[20];int __C=-1,__zz=0;
	inline void Ot(){fwrite(__sr,1,__C+1,stdout),__C=-1;}
	inline void print(register int x)
	{
		if(__C>1<<20)Ot();if(x<0)__sr[++__C]='-',x=-x;
		while(__z[++__zz]=x%10+48,x/=10);
		while(__sr[++__C]=__z[__zz],--__zz);__sr[++__C]='\n';
	}
	void file()
	{
		#ifdef NTFOrz
		freopen("a.in","r",stdin);
		#endif
	}
	inline void chktime()
	{
		#ifndef ONLINE_JUDGE
		cout<<(clock()-t)/1000.0<<'\n';
		#endif
	}
	#ifdef mod
	ll ksm(ll x,int y){ll ret=1;for (;y;y>>=1,x=x*x%mod) if (y&1) ret=ret*x%mod;return ret;}
	ll inv(ll x){return ksm(x,mod-2);}
	#else
	ll ksm(ll x,int y){ll ret=1;for (;y;y>>=1,x=x*x) if (y&1) ret=ret*x;return ret;}
	#endif
//	inline ll mul(ll a,ll b){ll d=(ll)(a*(double)b/mod+0.5);ll ret=a*b-d*mod;if (ret<0) ret+=mod;return ret;}
}
using namespace my_std;

int n;
ll sum1,sum2;
int a[sz],b[sz];
multiset<pii>s1,s2;
struct hh{int i,j,d;}ans[sz];
int m;

int main()
{
	file();
	read(n);
	rep(i,1,n) read(a[i]),sum1+=a[i],s1.insert(MP(a[i],i));
	rep(i,1,n) read(b[i]),sum2+=b[i],s2.insert(MP(b[i],i));
	#define END return puts("NO"),0
	if (sum1!=sum2) END;
	while (s1.size())
	{
		auto p1=s1.end(),p2=s1.begin(),q1=s2.end(),q2=s2.begin();
		--p1,--q1;
		pii x1=*p1,x2=*p2,y1=*q1,y2=*q2;
		if (x1.fir!=y1.fir)
		{
			int d=min(x1.fir-y1.fir,(x1.fir-x2.fir)>>1);
			if (d<=0) END;
			++m;ans[m]=(hh){x2.sec,x1.sec,d};
			s1.erase(p1),s1.erase(p2);
			x1.fir-=d,x2.fir+=d;
			s1.insert(x1),s1.insert(x2);
		}
		p1=s1.end(),p2=s1.begin(),q1=s2.end(),q2=s2.begin();
		--p1,--q1;
		x1=*p1,x2=*p2,y1=*q1,y2=*q2;
		if (x1.fir==y1.fir) s1.erase(p1),s2.erase(q1);
	}
	puts("Yes");
	printf("%d\n",m);
	rep(i,1,m) printf("%d %d %d\n",ans[i].i,ans[i].j,ans[i].d);
	return 0;
}


#include<bits/stdc++.h>
clock_t t=clock();
namespace my_std{
	using namespace std;
	#define pii pair<int,int>
	#define fir first
	#define sec second
	#define MP make_pair
	#define rep(i,x,y) for (int i=(x);i<=(y);i++)
	#define drep(i,x,y) for (int i=(x);i>=(y);i--)
	#define go(x) for (int i=head[x];i;i=edge[i].nxt)
	#define templ template<typename T>
	#define sz 303030
	typedef long long ll;
	typedef double db;
	mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
	templ inline T rnd(T l,T r) {return uniform_int_distribution<T>(l,r)(rng);}
	templ inline bool chkmax(T &x,T y){return x<y?x=y,1:0;}
	templ inline bool chkmin(T &x,T y){return x>y?x=y,1:0;}
	templ inline void read(T& t)
	{
		t=0;char f=0,ch=getchar();double d=0.1;
		while(ch>'9'||ch<'0') f|=(ch=='-'),ch=getchar();
		while(ch<='9'&&ch>='0') t=t*10+ch-48,ch=getchar();
		if(ch=='.'){ch=getchar();while(ch<='9'&&ch>='0') t+=d*(ch^48),d*=0.1,ch=getchar();}
		t=(f?-t:t);
	}
	template<typename T,typename... Args>inline void read(T& t,Args&... args){read(t); read(args...);}
	char __sr[1<<21],__z[20];int __C=-1,__zz=0;
	inline void Ot(){fwrite(__sr,1,__C+1,stdout),__C=-1;}
	inline void print(register int x)
	{
		if(__C>1<<20)Ot();if(x<0)__sr[++__C]='-',x=-x;
		while(__z[++__zz]=x%10+48,x/=10);
		while(__sr[++__C]=__z[__zz],--__zz);__sr[++__C]='\n';
	}
	void file()
	{
		#ifdef NTFOrz
		freopen("a.in","r",stdin);
		#endif
	}
	inline void chktime()
	{
		#ifndef ONLINE_JUDGE
		cout<<(clock()-t)/1000.0<<'\n';
		#endif
	}
	#ifdef mod
	ll ksm(ll x,int y){ll ret=1;for (;y;y>>=1,x=x*x%mod) if (y&1) ret=ret*x%mod;return ret;}
	ll inv(ll x){return ksm(x,mod-2);}
	#else
	ll ksm(ll x,int y){ll ret=1;for (;y;y>>=1,x=x*x) if (y&1) ret=ret*x;return ret;}
	#endif
//	inline ll mul(ll a,ll b){ll d=(ll)(a*(double)b/mod+0.5);ll ret=a*b-d*mod;if (ret<0) ret+=mod;return ret;}
}
using namespace my_std;

int n;
ll sum1,sum2;
int a[sz],b[sz];
multiset<pii>s1,s2;
struct hh{int i,j,d;}ans[sz];
int m;

int main()
{
	file();
	read(n);
	rep(i,1,n) read(a[i]),sum1+=a[i],s1.insert(MP(a[i],i));
	rep(i,1,n) read(b[i]),sum2+=b[i],s2.insert(MP(b[i],i));
	#define END return puts("NO"),0
	if (sum1!=sum2) END;
	while (s1.size())
	{
		auto p1=s1.end(),p2=s1.begin(),q1=s2.end(),q2=s2.begin();
		--p1,--q1;
		pii x1=*p1,x2=*p2,y1=*q1,y2=*q2;
		if (x1.fir!=y1.fir)
		{
			int d=min(x1.fir-y1.fir,(x1.fir-x2.fir)>>1);
			if (d<=0) END;
			++m;ans[m]=(hh){x2.sec,x1.sec,d};
			s1.erase(p1),s1.erase(p2);
			x1.fir-=d,x2.fir+=d;
			s1.insert(x1),s1.insert(x2);
		}
		p1=s1.end(),p2=s1.begin(),q1=s2.end(),q2=s2.begin();
		--p1,--q1;
		x1=*p1,x2=*p2,y1=*q1,y2=*q2;
		if (x1.fir==y1.fir) s1.erase(p1),s2.erase(q1);
	}
	puts("YES");
	printf("%d\n",m);
	rep(i,1,m) printf("%d %d %d\n",ans[i].i,ans[i].j,ans[i].d);
	return 0;
}


#include<bits/stdc++.h>
clock_t t=clock();
namespace my_std{
	using namespace std;
	#define pii pair<int,int>
	#define fir first
	#define sec second
	#define MP make_pair
	#define rep(i,x,y) for (int i=(x);i<=(y);i++)
	#define drep(i,x,y) for (int i=(x);i>=(y);i--)
	#define go(x) for (int i=head[x];i;i=edge[i].nxt)
	#define templ template<typename T>
	#define sz 303030
	typedef long long ll;
	typedef double db;
	mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
	templ inline T rnd(T l,T r) {return uniform_int_distribution<T>(l,r)(rng);}
	templ inline bool chkmax(T &x,T y){return x<y?x=y,1:0;}
	templ inline bool chkmin(T &x,T y){return x>y?x=y,1:0;}
	templ inline void read(T& t)
	{
		t=0;char f=0,ch=getchar();double d=0.1;
		while(ch>'9'||ch<'0') f|=(ch=='-'),ch=getchar();
		while(ch<='9'&&ch>='0') t=t*10+ch-48,ch=getchar();
		if(ch=='.'){ch=getchar();while(ch<='9'&&ch>='0') t+=d*(ch^48),d*=0.1,ch=getchar();}
		t=(f?-t:t);
	}
	template<typename T,typename... Args>inline void read(T& t,Args&... args){read(t); read(args...);}
	char __sr[1<<21],__z[20];int __C=-1,__zz=0;
	inline void Ot(){fwrite(__sr,1,__C+1,stdout),__C=-1;}
	inline void print(register int x)
	{
		if(__C>1<<20)Ot();if(x<0)__sr[++__C]='-',x=-x;
		while(__z[++__zz]=x%10+48,x/=10);
		while(__sr[++__C]=__z[__zz],--__zz);__sr[++__C]='\n';
	}
	void file()
	{
		#ifdef NTFOrz
		freopen("a.in","r",stdin);
		#endif
	}
	inline void chktime()
	{
		#ifndef ONLINE_JUDGE
		cout<<(clock()-t)/1000.0<<'\n';
		#endif
	}
	#ifdef mod
	ll ksm(ll x,int y){ll ret=1;for (;y;y>>=1,x=x*x%mod) if (y&1) ret=ret*x%mod;return ret;}
	ll inv(ll x){return ksm(x,mod-2);}
	#else
	ll ksm(ll x,int y){ll ret=1;for (;y;y>>=1,x=x*x) if (y&1) ret=ret*x;return ret;}
	#endif
//	inline ll mul(ll a,ll b){ll d=(ll)(a*(double)b/mod+0.5);ll ret=a*b-d*mod;if (ret<0) ret+=mod;return ret;}
}
using namespace my_std;

int n;
pii a[sz],b[sz];

struct hh{int i,j,d;}ans[sz];
int m;

int main()
{
	file();
	read(n);
	rep(i,1,n) read(a[i].fir),a[i].sec=i;
	rep(i,1,n) read(b[i].fir),b[i].sec=i;
	sort(a+1,a+n+1);sort(b+1,b+n+1);
	#define END return puts("NO"),0
	int sum=0;
	rep(i,1,n) sum+=a[i].fir-b[i].fir;
	if (sum!=0) END;
	queue<pii>q;
	int x=1,y=1;
	while (y<=n)
	{
		while (x<=n&&y<=n&&a[x].fir==b[y].fir) ++x,++y;
		while (x<=n&&a[x].fir<b[y].fir) q.push(a[x]),++x;
		if (x>n) break;
		if (q.empty()) END;
		pii w=q.front();q.pop();
		ans[++m]=(hh){w.sec,a[x].sec,0};
		if (w.fir+a[x].fir>b[y].fir*2)
		{
			int d=b[y].fir-w.fir;
			ans[m].d=d;
			a[x].fir-=d;
		}
		else
		{
			int d=a[x].fir-b[y].fir;
			ans[m].d=d;
			a[x].fir-=d;w.fir+=d;
			q.push(w);
		}
		++y;
	}
	puts("YES");
	printf("%d\n",m);
	rep(i,1,m) printf("%d %d %d\n",ans[i].i,ans[i].j,ans[i].d);
	return 0;
}


#include<bits/stdc++.h>
clock_t t=clock();
namespace my_std{
	using namespace std;
	#define pii pair<int,int>
	#define fir first
	#define sec second
	#define MP make_pair
	#define rep(i,x,y) for (int i=(x);i<=(y);i++)
	#define drep(i,x,y) for (int i=(x);i>=(y);i--)
	#define go(x) for (int i=head[x];i;i=edge[i].nxt)
	#define templ template<typename T>
	#define sz 303030
	typedef long long ll;
	typedef double db;
	mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
	templ inline T rnd(T l,T r) {return uniform_int_distribution<T>(l,r)(rng);}
	templ inline bool chkmax(T &x,T y){return x<y?x=y,1:0;}
	templ inline bool chkmin(T &x,T y){return x>y?x=y,1:0;}
	templ inline void read(T& t)
	{
		t=0;char f=0,ch=getchar();double d=0.1;
		while(ch>'9'||ch<'0') f|=(ch=='-'),ch=getchar();
		while(ch<='9'&&ch>='0') t=t*10+ch-48,ch=getchar();
		if(ch=='.'){ch=getchar();while(ch<='9'&&ch>='0') t+=d*(ch^48),d*=0.1,ch=getchar();}
		t=(f?-t:t);
	}
	template<typename T,typename... Args>inline void read(T& t,Args&... args){read(t); read(args...);}
	char __sr[1<<21],__z[20];int __C=-1,__zz=0;
	inline void Ot(){fwrite(__sr,1,__C+1,stdout),__C=-1;}
	inline void print(register int x)
	{
		if(__C>1<<20)Ot();if(x<0)__sr[++__C]='-',x=-x;
		while(__z[++__zz]=x%10+48,x/=10);
		while(__sr[++__C]=__z[__zz],--__zz);__sr[++__C]='\n';
	}
	void file()
	{
		#ifdef NTFOrz
		freopen("a.in","r",stdin);
		#endif
	}
	inline void chktime()
	{
		#ifndef ONLINE_JUDGE
		cout<<(clock()-t)/1000.0<<'\n';
		#endif
	}
	#ifdef mod
	ll ksm(ll x,int y){ll ret=1;for (;y;y>>=1,x=x*x%mod) if (y&1) ret=ret*x%mod;return ret;}
	ll inv(ll x){return ksm(x,mod-2);}
	#else
	ll ksm(ll x,int y){ll ret=1;for (;y;y>>=1,x=x*x) if (y&1) ret=ret*x;return ret;}
	#endif
//	inline ll mul(ll a,ll b){ll d=(ll)(a*(double)b/mod+0.5);ll ret=a*b-d*mod;if (ret<0) ret+=mod;return ret;}
}
using namespace my_std;

int n;
pii a[sz],b[sz];

struct hh{int i,j,d;}ans[sz];
int m;

int main()
{
	file();
	read(n);
	rep(i,1,n) read(a[i].fir),a[i].sec=i;
	rep(i,1,n) read(b[i].fir),b[i].sec=i;
	sort(a+1,a+n+1);sort(b+1,b+n+1);
	#define END return puts("NO"),0
	int sum=0;
	rep(i,1,n) sum+=a[i].fir-b[i].fir;
	if (sum!=0) END;
	queue<pii>q;
	int x=1,y=1;
	while (x<n)
	{
		while (x<=n&&a[x].fir==b[y].fir) ++x,++y;
		while (x<=n&&a[x].fir<b[y].fir) q.push(a[x]),++x;
		while (x<=n&&a[x].fir==b[y].fir) ++x,++y;
		if (x>n) break;
		if (q.empty()) END;
		pii w=q.front();q.pop();
		ans[++m]=(hh){w.sec,a[x].sec,0};
		if (w.fir+a[x].fir>b[y].fir*2)
		{
			int d=b[y].fir-w.fir;
			ans[m].d=d;
			a[x].fir-=d;
		}
		else
		{
			int d=a[x].fir-b[y].fir;
			ans[m].d=d;
			a[x].fir-=d;w.fir+=d;
			q.push(w);
		}
		++y;
	}
	puts("YES");
	printf("%d\n",m);
	rep(i,1,m) printf("%d %d %d\n",ans[i].i,ans[i].j,ans[i].d);
	return 0;
}


#include<bits/stdc++.h>
clock_t t=clock();
namespace my_std{
	using namespace std;
	#define pii pair<int,int>
	#define fir first
	#define sec second
	#define MP make_pair
	#define rep(i,x,y) for (int i=(x);i<=(y);i++)
	#define drep(i,x,y) for (int i=(x);i>=(y);i--)
	#define go(x) for (int i=head[x];i;i=edge[i].nxt)
	#define templ template<typename T>
	#define sz 303030
	typedef long long ll;
	typedef double db;
	mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
	templ inline T rnd(T l,T r) {return uniform_int_distribution<T>(l,r)(rng);}
	templ inline bool chkmax(T &x,T y){return x<y?x=y,1:0;}
	templ inline bool chkmin(T &x,T y){return x>y?x=y,1:0;}
	templ inline void read(T& t)
	{
		t=0;char f=0,ch=getchar();double d=0.1;
		while(ch>'9'||ch<'0') f|=(ch=='-'),ch=getchar();
		while(ch<='9'&&ch>='0') t=t*10+ch-48,ch=getchar();
		if(ch=='.'){ch=getchar();while(ch<='9'&&ch>='0') t+=d*(ch^48),d*=0.1,ch=getchar();}
		t=(f?-t:t);
	}
	template<typename T,typename... Args>inline void read(T& t,Args&... args){read(t); read(args...);}
	char __sr[1<<21],__z[20];int __C=-1,__zz=0;
	inline void Ot(){fwrite(__sr,1,__C+1,stdout),__C=-1;}
	inline void print(register int x)
	{
		if(__C>1<<20)Ot();if(x<0)__sr[++__C]='-',x=-x;
		while(__z[++__zz]=x%10+48,x/=10);
		while(__sr[++__C]=__z[__zz],--__zz);__sr[++__C]='\n';
	}
	void file()
	{
		#ifdef NTFOrz
		freopen("a.in","r",stdin);
		#endif
	}
	inline void chktime()
	{
		#ifndef ONLINE_JUDGE
		cout<<(clock()-t)/1000.0<<'\n';
		#endif
	}
	#ifdef mod
	ll ksm(ll x,int y){ll ret=1;for (;y;y>>=1,x=x*x%mod) if (y&1) ret=ret*x%mod;return ret;}
	ll inv(ll x){return ksm(x,mod-2);}
	#else
	ll ksm(ll x,int y){ll ret=1;for (;y;y>>=1,x=x*x) if (y&1) ret=ret*x;return ret;}
	#endif
//	inline ll mul(ll a,ll b){ll d=(ll)(a*(double)b/mod+0.5);ll ret=a*b-d*mod;if (ret<0) ret+=mod;return ret;}
}
using namespace my_std;

int n;
ll sum1,sum2;
pii a[sz],b[sz];
multiset<pii>s1,s2;
struct hh{int i,j,d;}ans[sz];
int m;

void work(int l,int r)
{
	s1.clear(),s2.clear();
	rep(i,l,r) s1.insert(a[i]);
	rep(i,l,r) s2.insert(b[i]);
	#define END exit((puts("NO"),0))
	while (s1.size())
	{
		auto p1=s1.end(),p2=s1.begin(),q1=s2.end(),q2=s2.begin();
		--p1,--q1;
		pii x1=*p1,x2=*p2,y1=*q1,y2=*q2;
		if (x2.fir==y2.fir) { s1.erase(p2),s2.erase(q2); continue; }
		if (x1.fir!=y1.fir)
		{
			int d=min(x1.fir-y1.fir,(x1.fir-x2.fir)>>1);
			if (d<=0) END;
			++m;ans[m]=(hh){x2.sec,x1.sec,d};
			s1.erase(p1),s1.erase(p2);
			x1.fir-=d,x2.fir+=d;
			s1.insert(x1),s1.insert(x2);
		}
		p1=s1.end(),p2=s1.begin(),q1=s2.end(),q2=s2.begin();
		--p1,--q1;
		x1=*p1,x2=*p2,y1=*q1,y2=*q2;
		if (x1.fir==y1.fir) s1.erase(p1),s2.erase(q1);
	}
}

int main()
{
	file();
	read(n);
	rep(i,1,n) read(a[i].fir),a[i].sec=i;
	rep(i,1,n) read(b[i].fir),b[i].sec=i;
	sort(a+1,a+n+1);sort(b+1,b+n+1);
	int sum1=0,sum2=0,lst=1;
	rep(i,1,n)
	{
		sum1+=a[i].fir,sum2+=b[i].fir;
		if (sum1==sum2)
		{
			work(lst,i);
			lst=i+1;
		}
	}
	puts("YES");
	printf("%d\n",m);
	rep(i,1,m) printf("%d %d %d\n",ans[i].i,ans[i].j,ans[i].d);
	return 0;
}


#include<bits/stdc++.h>
clock_t t=clock();
namespace my_std{
	using namespace std;
	#define pii pair<int,int>
	#define fir first
	#define sec second
	#define MP make_pair
	#define rep(i,x,y) for (int i=(x);i<=(y);i++)
	#define drep(i,x,y) for (int i=(x);i>=(y);i--)
	#define go(x) for (int i=head[x];i;i=edge[i].nxt)
	#define templ template<typename T>
	#define sz 303030
	typedef long long ll;
	typedef double db;
	mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
	templ inline T rnd(T l,T r) {return uniform_int_distribution<T>(l,r)(rng);}
	templ inline bool chkmax(T &x,T y){return x<y?x=y,1:0;}
	templ inline bool chkmin(T &x,T y){return x>y?x=y,1:0;}
	templ inline void read(T& t)
	{
		t=0;char f=0,ch=getchar();double d=0.1;
		while(ch>'9'||ch<'0') f|=(ch=='-'),ch=getchar();
		while(ch<='9'&&ch>='0') t=t*10+ch-48,ch=getchar();
		if(ch=='.'){ch=getchar();while(ch<='9'&&ch>='0') t+=d*(ch^48),d*=0.1,ch=getchar();}
		t=(f?-t:t);
	}
	template<typename T,typename... Args>inline void read(T& t,Args&... args){read(t); read(args...);}
	char __sr[1<<21],__z[20];int __C=-1,__zz=0;
	inline void Ot(){fwrite(__sr,1,__C+1,stdout),__C=-1;}
	inline void print(register int x)
	{
		if(__C>1<<20)Ot();if(x<0)__sr[++__C]='-',x=-x;
		while(__z[++__zz]=x%10+48,x/=10);
		while(__sr[++__C]=__z[__zz],--__zz);__sr[++__C]='\n';
	}
	void file()
	{
		#ifdef NTFOrz
		freopen("a.in","r",stdin);
		#endif
	}
	inline void chktime()
	{
		#ifndef ONLINE_JUDGE
		cout<<(clock()-t)/1000.0<<'\n';
		#endif
	}
	#ifdef mod
	ll ksm(ll x,int y){ll ret=1;for (;y;y>>=1,x=x*x%mod) if (y&1) ret=ret*x%mod;return ret;}
	ll inv(ll x){return ksm(x,mod-2);}
	#else
	ll ksm(ll x,int y){ll ret=1;for (;y;y>>=1,x=x*x) if (y&1) ret=ret*x;return ret;}
	#endif
//	inline ll mul(ll a,ll b){ll d=(ll)(a*(double)b/mod+0.5);ll ret=a*b-d*mod;if (ret<0) ret+=mod;return ret;}
}
using namespace my_std;

int n;
ll sum1,sum2;
pii a[sz],b[sz];
multiset<pii>s1,s2;
struct hh{int i,j,d;}ans[sz];
int m;

void work(int l,int r)
{
	s1.clear(),s2.clear();
	rep(i,l,r) s1.insert(a[i]);
	rep(i,l,r) s2.insert(b[i]);
	#define END exit((puts("NO"),0))
	while (s1.size())
	{
		auto p1=s1.end(),p2=s1.begin(),q1=s2.end(),q2=s2.begin();
		--p1,--q1;
		pii x1=*p1,x2=*p2,y1=*q1,y2=*q2;
		if (x2.fir==y2.fir) { s1.erase(p2),s2.erase(q2); continue; }
		if (x1.fir!=y1.fir)
		{
			int d=min(min(x1.fir-y1.fir,y2.fir-x2.fir),(x1.fir-x2.fir)>>1);
			if (d<=0) END;
			++m;ans[m]=(hh){x2.sec,x1.sec,d};
			s1.erase(p1),s1.erase(p2);
			x1.fir-=d,x2.fir+=d;
			s1.insert(x1),s1.insert(x2);
		}
		p1=s1.end(),p2=s1.begin(),q1=s2.end(),q2=s2.begin();
		--p1,--q1;
		x1=*p1,x2=*p2,y1=*q1,y2=*q2;
		if (x1.fir==y1.fir) s1.erase(p1),s2.erase(q1);
	}
}

int main()
{
	file();
	read(n);
	rep(i,1,n) read(a[i].fir),a[i].sec=i;
	rep(i,1,n) read(b[i].fir),b[i].sec=i;
	sort(a+1,a+n+1);sort(b+1,b+n+1);
	int sum1=0,sum2=0,lst=1;
	rep(i,1,n)
	{
		sum1+=a[i].fir,sum2+=b[i].fir;
		if (sum1==sum2)
		{
			work(lst,i);
			lst=i+1;
		}
	}
	puts("YES");
	printf("%d\n",m);
	rep(i,1,m) printf("%d %d %d\n",ans[i].i,ans[i].j,ans[i].d);
	return 0;
}


#include<bits/stdc++.h>
clock_t t=clock();
namespace my_std{
	using namespace std;
	#define pii pair<int,int>
	#define fir first
	#define sec second
	#define MP make_pair
	#define rep(i,x,y) for (int i=(x);i<=(y);i++)
	#define drep(i,x,y) for (int i=(x);i>=(y);i--)
	#define go(x) for (int i=head[x];i;i=edge[i].nxt)
	#define templ template<typename T>
	#define sz 303030
	typedef long long ll;
	typedef double db;
	mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
	templ inline T rnd(T l,T r) {return uniform_int_distribution<T>(l,r)(rng);}
	templ inline bool chkmax(T &x,T y){return x<y?x=y,1:0;}
	templ inline bool chkmin(T &x,T y){return x>y?x=y,1:0;}
	templ inline void read(T& t)
	{
		t=0;char f=0,ch=getchar();double d=0.1;
		while(ch>'9'||ch<'0') f|=(ch=='-'),ch=getchar();
		while(ch<='9'&&ch>='0') t=t*10+ch-48,ch=getchar();
		if(ch=='.'){ch=getchar();while(ch<='9'&&ch>='0') t+=d*(ch^48),d*=0.1,ch=getchar();}
		t=(f?-t:t);
	}
	template<typename T,typename... Args>inline void read(T& t,Args&... args){read(t); read(args...);}
	char __sr[1<<21],__z[20];int __C=-1,__zz=0;
	inline void Ot(){fwrite(__sr,1,__C+1,stdout),__C=-1;}
	inline void print(register int x)
	{
		if(__C>1<<20)Ot();if(x<0)__sr[++__C]='-',x=-x;
		while(__z[++__zz]=x%10+48,x/=10);
		while(__sr[++__C]=__z[__zz],--__zz);__sr[++__C]='\n';
	}
	void file()
	{
		#ifdef NTFOrz
		freopen("a.in","r",stdin);
		#endif
	}
	inline void chktime()
	{
		#ifndef ONLINE_JUDGE
		cout<<(clock()-t)/1000.0<<'\n';
		#endif
	}
	#ifdef mod
	ll ksm(ll x,int y){ll ret=1;for (;y;y>>=1,x=x*x%mod) if (y&1) ret=ret*x%mod;return ret;}
	ll inv(ll x){return ksm(x,mod-2);}
	#else
	ll ksm(ll x,int y){ll ret=1;for (;y;y>>=1,x=x*x) if (y&1) ret=ret*x;return ret;}
	#endif
//	inline ll mul(ll a,ll b){ll d=(ll)(a*(double)b/mod+0.5);ll ret=a*b-d*mod;if (ret<0) ret+=mod;return ret;}
}
using namespace my_std;

int n;
pii a[sz],b[sz];

struct hh{int i,j,d;}ans[sz];
int m;

int main()
{
	file();
	read(n);
	rep(i,1,n) read(a[i].fir),a[i].sec=i;
	rep(i,1,n) read(b[i].fir),b[i].sec=i;
	sort(a+1,a+n+1);sort(b+1,b+n+1);
	#define END return puts("NO"),0
	ll sum=0;
	rep(i,1,n) sum+=a[i].fir-b[i].fir;
	if (sum!=0) END;
	queue<pii>q;
	int x=1,y=1;
	while (y<=n)
	{
		while (x<=n&&y<=n&&a[x].fir==b[y].fir) ++x,++y;
		while (x<=n&&a[x].fir<b[y].fir) q.push(a[x]),++x;
		if (x>n||y>n) break;
		if (q.empty()) END;
		pii w=q.front();q.pop();
		ans[++m]=(hh){w.sec,a[x].sec,0};
		if (w.fir+a[x].fir>b[y].fir*2)
		{
			int d=b[y].fir-w.fir;
			ans[m].d=d;
			a[x].fir-=d;
		}
		else
		{
			int d=a[x].fir-b[y].fir;
			ans[m].d=d;
			a[x].fir-=d;w.fir+=d;
			q.push(w);++x;
		}
		++y;
	}
	puts("YES");
	printf("%d\n",m);
	rep(i,1,m) printf("%d %d %d\n",ans[i].i,ans[i].j,ans[i].d);
	return 0;
}


#include <bits/stdc++.h>
#define ll long long
#define ld long double
#define pii pair<int, int>
#define pll pair<ll, ll>
#define str string
#define fi first
#define se second
#define pb push_back
#define SET(a, b) memset(a, b, sizeof(a))
#define eps 1e-6
#define pi atan(1) * 4
#define mod 1000000007
#define inf 1000000000
#define llinf 1000000000000000000
#define FOR(i, a, b) for (int i = (a); i <= (b); i++)
#define FORD(i, a, b) for (int i = (a); i >= (b); i--)
#define FORl(i, a, b) for (ll i = (a); i <= (b); i++)
#define FORDl(i, a, b) for (ll i = (a); i >= (b); i--)
using namespace std;
int ini[300005], fin[300005];
struct hk {
	int u, v, i;
};
hk up[300005], down[300005];
bool cmp2 (hk &a, hk &b) {
	if (a.u != b.u) return (a.u < b.u);
	return (a.v < b.v);
}
bool cmp (hk &a, hk &b) {
	if (a.v != b.v) return (a.v < b.v);
	return (a.u < b.u);
}
vector<hk> ans, tmp;
int main () {
	int n;
	scanf("%d", &n);
	ll sum = 0;
	FOR(i, 1, n) {
		scanf("%d", &ini[i]);
		sum += ini[i];
	}
	FOR(i, 1, n) {
		scanf("%d", &fin[i]);
		sum -= fin[i];
	}
	if (sum != 0) {
		printf("NO\n"); return 0;
	}

	int us = 0, ds = 0;
	FOR(i, 1, n) {
		if (ini[i] < fin[i]) {
			up[++us] = {ini[i], fin[i], i};
		} else if (ini[i] > fin[i]) {
			down[++ds] = {ini[i], fin[i], i};
		}
	}
	sort(up + 1, up + us + 1, cmp2);
	sort(down + 1, down + ds + 1, cmp);
	/* FOR(i, 1, us) cout << up[i].u << ' ' << up[i].v << ' ' << up[i].i << endl;
	cout << endl;
	FOR(i, 1, ds) cout << down[i].u << ' ' << down[i].v << ' ' << down[i].i << endl; */

	/* int i = us;
	FORD(j, ds, 1) {
		while (i >= 1 && up[i].v <= down[j].v) {
			int d1 = up[i].v - up[i].u;
			if (!d1) {
				--i; continue;
			}
			int d2 = down[j].u - down[j].v;
			int d = min(d1, d2);
			up[i].u += d; down[j].u -= d;
			ans.pb({up[i].i, down[j].i, d});
			if (down[j].v == down[j].u) break;
			--i;
		}
		if (!i) {
			printf("NO\n"); return 0;
		}
	}
	printf("YES\n\%d\n", (int)ans.size());
	for (auto o : ans) {
		printf("%d %d %d\n", o.u, o.v, o.i);
	} */

	int i = 1, j = 1;
	while (i <= us && j <= ds) {
		while (i <= us && up[i].u == up[i].v) ++i;
		if (i > us) {
			printf("NO\n"); return 0;
		}
		int ti = i;
		while (ti <= us && up[ti].u <= down[j].u) {
			int mxd = (down[j].u - up[ti].u) >> 1;
			int d1 = up[ti].v - up[ti].u;
			int d2 = down[j].u - down[j].v;
			int d = min(min(d1, d2), mxd);
			up[ti].u += d; down[j].v += d;
			if (d) tmp.pb({up[ti].i, down[j].i, d});
			if (down[j].v == down[j].u) break;
			++ti;
		}
		if (down[j].v < down[j].u) {
			printf("NO\n"); return 0;
		}
		++j;
		reverse(tmp.begin(), tmp.end());
		for (auto o : tmp) ans.pb(o);
		tmp.clear();
	}
	while (i <= us && up[i].u == up[i].v) ++i;
	while (j <= ds && down[j].u == down[j].v) ++j;
	if (i <= us || j <= ds) {
		printf("NO\n"); return 0;
	}
	printf("YES\n\%d\n", (int)ans.size());
	for (auto o : ans) {
		printf("%d %d %d\n", o.u, o.v, o.i);
	}
	return 0;
}


#include <bits/stdc++.h>
#define ll long long
#define ld long double
#define pii pair<int, int>
#define pll pair<ll, ll>
#define str string
#define fi first
#define se second
#define pb push_back
#define SET(a, b) memset(a, b, sizeof(a))
#define eps 1e-6
#define pi atan(1) * 4
#define mod 1000000007
#define inf 1000000000
#define llinf 1000000000000000000
#define FOR(i, a, b) for (int i = (a); i <= (b); i++)
#define FORD(i, a, b) for (int i = (a); i >= (b); i--)
#define FORl(i, a, b) for (ll i = (a); i <= (b); i++)
#define FORDl(i, a, b) for (ll i = (a); i >= (b); i--)
using namespace std;
pii ini[300005], fin[300005];
bool cmp (pii a, pii b) {
	if (a.fi < b.fi) return (a.fi < b.fi);
	return (a.se < b.se);
}
struct hk {
	int u, v, i, j;
};
hk up[300005], down[300005];
vector<hk> ans;
int main () {
	int n;
	scanf("%d", &n);
	ll sum = 0;
	FOR(i, 1, n) {
		scanf("%d", &ini[i].fi);
		sum += ini[i].fi; ini[i].se = i;
	}
	FOR(i, 1, n) {
		scanf("%d", &fin[i].fi);
		sum -= fin[i].fi; fin[i].se = i;
	}
	if (sum != 0) {
		printf("NO\n"); return 0;
	}
	sort(ini + 1, ini + n + 1, cmp);
	sort(fin + 1, fin + n + 1, cmp);

	int us = 0, ds = 0;
	FOR(i, 1, n) {
		if (ini[i] < fin[i]) {
			up[++us] = {ini[i].fi, fin[i].fi, ini[i].se};
		} else if (ini[i] > fin[i]) {
			down[++ds] = {ini[i].fi, fin[i].fi, ini[i].se};
		}
	}
	int i = 1;
	FOR(j, 1, ds) {
		while (i <= us && up[i].v <= down[j].v) {
			int d1 = up[i].v - up[i].u;
			int d2 = down[j].u - down[j].v;
			int d = min(d1, d2);
			up[i].u += d; down[j].u -= d;
			if (d) ans.pb({up[i].i, down[j].i, d});
			if (down[j].v == down[j].u) break;
			++i;
		}
		if (down[j].v < down[j].u) {
			printf("NO\n"); return 0;
		}
	}
	printf("YES\n\%d\n", (int)ans.size());
	for (auto o : ans) {
		printf("%d %d %d\n", o.u, o.v, o.i);
	}
	return 0;
}


#include <bits/stdc++.h>
#define ll long long
#define ld long double
#define pii pair<int, int>
#define pll pair<ll, ll>
#define str string
#define fi first
#define se second
#define pb push_back
#define SET(a, b) memset(a, b, sizeof(a))
#define eps 1e-6
#define pi atan(1) * 4
#define mod 1000000007
#define inf 1000000000
#define llinf 1000000000000000000
#define FOR(i, a, b) for (int i = (a); i <= (b); i++)
#define FORD(i, a, b) for (int i = (a); i >= (b); i--)
#define FORl(i, a, b) for (ll i = (a); i <= (b); i++)
#define FORDl(i, a, b) for (ll i = (a); i >= (b); i--)
using namespace std;
int ini[300005], fin[300005];
struct hk {
	int u, v, i;
};
hk up[300005], down[300005];
bool cmp (hk &a, hk &b) {
	if (a.v != b.v) return (a.v < b.v);
	return (a.u < b.u);
}
vector<hk> ans, tmp;
int main () {
	int n;
	scanf("%d", &n);
	ll sum = 0;
	FOR(i, 1, n) {
		scanf("%d", &ini[i]);
		sum += ini[i];
	}
	FOR(i, 1, n) {
		scanf("%d", &fin[i]);
		sum -= fin[i];
	}
	if (sum != 0) {
		printf("NO\n"); return 0;
	}

	int us = 0, ds = 0;
	FOR(i, 1, n) {
		if (ini[i] < fin[i]) {
			up[++us] = {ini[i], fin[i], i};
		} else if (ini[i] > fin[i]) {
			down[++ds] = {ini[i], fin[i], i};
		}
	}
	sort(up + 1, up + us + 1, cmp);
	sort(down + 1, down + ds + 1, cmp);
	/* FOR(i, 1, us) cout << up[i].u << ' ' << up[i].v << ' ' << up[i].i << endl;
	cout << endl;
	FOR(i, 1, ds) cout << down[i].u << ' ' << down[i].v << ' ' << down[i].i << endl; */

	int i = 1, j = 1;
	while (i <= us && j <= ds) {
		while (i <= us && up[i].u == up[i].v) ++i;
		if (i > us) {
			printf("NO\n"); return 0;
		}
		int ti = i;
		while (ti <= us) {
			int mxd = (down[j].u - up[ti].u) >> 1;
			int d1 = up[ti].v - up[ti].u;
			int d2 = down[j].u - down[j].v;
			int d = min(min(d1, d2), mxd);
			up[ti].u += d; down[j].v += d;
			if (d) tmp.pb({up[ti].i, down[j].i, d});
			if (down[j].v == down[j].u) break;
			++ti;
		}
		if (down[j].v < down[j].u) {
			printf("NO\n"); return 0;
		}
		++j;
		reverse(tmp.begin(), tmp.end());
		for (auto o : tmp) ans.pb(o);
		tmp.clear();
	}
	while (i <= us && up[i].u == up[i].v) ++i;
	while (j <= ds && down[j].u == down[j].v) ++j;
	if (i <= us || j <= ds) {
		printf("NO\n"); return 0;
	}
	printf("YES\n\%d\n", (int)ans.size());
	for (auto o : ans) {
		printf("%d %d %d\n", o.u, o.v, o.i);
	}
	return 0;
}


#include <bits/stdc++.h>
#define ll long long
#define ld long double
#define pii pair<int, int>
#define pll pair<ll, ll>
#define str string
#define fi first
#define se second
#define pb push_back
#define SET(a, b) memset(a, b, sizeof(a))
#define eps 1e-6
#define pi atan(1) * 4
#define mod 1000000007
#define inf 1000000000
#define llinf 1000000000000000000
#define FOR(i, a, b) for (int i = (a); i <= (b); i++)
#define FORD(i, a, b) for (int i = (a); i >= (b); i--)
#define FORl(i, a, b) for (ll i = (a); i <= (b); i++)
#define FORDl(i, a, b) for (ll i = (a); i >= (b); i--)
using namespace std;
int ini[300005], fin[300005];
struct hk {
	int u, v, i;
};
hk up[300005], down[300005];
bool cmp (hk &a, hk &b) {
	if (a.v != b.v) return (a.v < b.v);
	return (a.u < b.u);
}
vector<hk> ans, tmp;
int main () {
	int n;
	scanf("%d", &n);
	ll sum = 0;
	FOR(i, 1, n) {
		scanf("%d", &ini[i]);
		sum += ini[i];
	}
	FOR(i, 1, n) {
		scanf("%d", &fin[i]);
		sum -= fin[i];
	}
	if (sum != 0) {
		printf("NO\n"); return 0;
	}

	int us = 0, ds = 0;
	FOR(i, 1, n) {
		if (ini[i] < fin[i]) {
			up[++us] = {ini[i], fin[i], i};
		} else if (ini[i] > fin[i]) {
			down[++ds] = {ini[i], fin[i], i};
		}
	}
	sort(up + 1, up + us + 1, cmp);
	sort(down + 1, down + ds + 1, cmp);
	/* FOR(i, 1, us) cout << up[i].u << ' ' << up[i].v << ' ' << up[i].i << endl;
	cout << endl;
	FOR(i, 1, ds) cout << down[i].u << ' ' << down[i].v << ' ' << down[i].i << endl; */

	/* int i = us;
	FORD(j, ds, 1) {
		while (i >= 1 && up[i].v <= down[j].v) {
			int d1 = up[i].v - up[i].u;
			if (!d1) {
				--i; continue;
			}
			int d2 = down[j].u - down[j].v;
			int d = min(d1, d2);
			up[i].u += d; down[j].u -= d;
			ans.pb({up[i].i, down[j].i, d});
			if (down[j].v == down[j].u) break;
			--i;
		}
		if (!i) {
			printf("NO\n"); return 0;
		}
	}
	printf("YES\n\%d\n", (int)ans.size());
	for (auto o : ans) {
		printf("%d %d %d\n", o.u, o.v, o.i);
	} */

	int i = 1, j = 1;
	while (i <= us && j <= ds) {
		while (i <= us && up[i].u == up[i].v) ++i;
		if (i > us) {
			printf("NO\n"); return 0;
		}
		int ti = i;
		while (ti <= us && up[ti].u <= down[j].u) {
			int mxd = (down[j].u - up[ti].u) >> 1;
			int d1 = up[ti].v - up[ti].u;
			int d2 = down[j].u - down[j].v;
			int d = min(min(d1, d2), mxd);
			up[ti].u += d; down[j].v += d;
			if (d) tmp.pb({up[ti].i, down[j].i, d});
			if (down[j].v == down[j].u) break;
			++ti;
		}
		if (down[j].v < down[j].u) {
			printf("NO\n"); return 0;
		}
		++j;
		reverse(tmp.begin(), tmp.end());
		for (auto o : tmp) ans.pb(o);
		tmp.clear();
	}
	while (i <= us && up[i].u == up[i].v) ++i;
	while (j <= ds && down[j].u == down[j].v) ++j;
	if (i <= us || j <= ds) {
		printf("NO\n"); return 0;
	}
	printf("YES\n\%d\n", (int)ans.size());
	for (auto o : ans) {
		printf("%d %d %d\n", o.u, o.v, o.i);
	}
	return 0;
}


#include <bits/stdc++.h>
#define ll long long
#define ld long double
#define pii pair<int, int>
#define pll pair<ll, ll>
#define str string
#define fi first
#define se second
#define pb push_back
#define SET(a, b) memset(a, b, sizeof(a))
#define eps 1e-6
#define pi atan(1) * 4
#define mod 1000000007
#define inf 1000000000
#define llinf 1000000000000000000
#define FOR(i, a, b) for (int i = (a); i <= (b); i++)
#define FORD(i, a, b) for (int i = (a); i >= (b); i--)
#define FORl(i, a, b) for (ll i = (a); i <= (b); i++)
#define FORDl(i, a, b) for (ll i = (a); i >= (b); i--)
using namespace std;
pii ini[300005], fin[300005];
bool cmp (pii a, pii b) {
	if (a.fi != b.fi) return (a.fi < b.fi);
	return (a.se < b.se);
}
struct hk {
	int u, v, i, j;
};
hk up[300005], down[300005];
vector<hk> ans;
int main () {
	int n;
	scanf("%d", &n);
	ll sum = 0;
	FOR(i, 1, n) {
		scanf("%d", &ini[i].fi);
		sum += ini[i].fi; ini[i].se = i;
	}
	FOR(i, 1, n) {
		scanf("%d", &fin[i].fi);
		sum -= fin[i].fi; fin[i].se = i;
	}
	if (sum != 0) {
		printf("NO\n"); return 0;
	}
	sort(ini + 1, ini + n + 1, cmp);
	sort(fin + 1, fin + n + 1, cmp);

	int us = 0, ds = 0;
	FOR(i, 1, n) {
		if (ini[i] < fin[i]) {
			up[++us] = {ini[i].fi, fin[i].fi, ini[i].se};
		} else if (ini[i] > fin[i]) {
			down[++ds] = {ini[i].fi, fin[i].fi, ini[i].se};
		}
	}
	int i = 1;
	FOR(j, 1, ds) {
		while (i <= us && up[i].v <= down[j].v) {
			int d1 = up[i].v - up[i].u;
			int d2 = down[j].u - down[j].v;
			int d = min(d1, d2);
			up[i].u += d; down[j].u -= d;
			if (d) ans.pb({up[i].i, down[j].i, d});
			if (down[j].v == down[j].u) break;
			++i;
		}
		if (down[j].v < down[j].u) {
			printf("NO\n"); return 0;
		}
	}
	printf("YES\n\%d\n", (int)ans.size());
	for (auto o : ans) {
		printf("%d %d %d\n", o.u, o.v, o.i);
	}
	return 0;
}


#include <bits/stdc++.h>
#include <cassert>

using namespace std;

typedef long long ll;

const int maxn = 4*131072;
const ll INF = 1e9 + 7;

struct Stone {
    int start, end, delta, id;
    bool operator<(Stone& rhs) {
        return start<rhs.start;
    }
};

void solve() {
    int n;
    cin >> n;
    vector<pair<int,int>> s(n);
    vector<int> t(n);
    for (int i=0;i<n;i++) {
      cin >> s[i].first;
      s[i].second = i;
    }
    for (int i=0;i<n;i++) {
        cin >> t[i];
    }
    sort(s.begin(), s.end());
    sort(t.begin(), t.end());
    vector<pair<int,int>> deltas(n);
    for (int i=0;i<n;i++) {
        deltas[i].first = t[i] - s[i].first;
        deltas[i].second=  s[i].second;
    }

    stack<pair<int,int>> stack;
    vector<pair<pair<int,int>,int>> actions;
    for (int i=0;i<n;i++) {
        if (deltas[i].first==0) continue;
        if (deltas[i].first>0) {
            stack.push(deltas[i]);
        } else {
            while (!stack.empty() && deltas[i].first<0) {
                int delta = min(-deltas[i].first, stack.top().first);
                deltas[i].first += delta;
                stack.top().first -= delta;
                actions.push_back({{stack.top().second, deltas[i].second}, delta});
                if (stack.top().first==0) stack.pop();
            }
            if (stack.empty() && deltas[i].first!=0) {
                cout << "NO";
                return;
            }
        }
    }
    if (!stack.empty()) {
        cout << "NO";
        return;
    }
    cout << actions.size() << endl;
    for (int i=0;i<actions.size();i++) {
        cout << actions[i].first.first+1 << " " << actions[i].first.second+1 << " " << actions[i].second << endl;
    }
}
int main()
{
    cin.tie(0);
    cout.tie(0);
    ios_base::sync_with_stdio(false);
   // freopen("input.txt","r",stdin);
    solve();
    return 0;
}


#include <bits/stdc++.h>
#include <cassert>

using namespace std;

typedef long long ll;

const int maxn = 4*131072;
const ll INF = 1e9 + 7;

struct Stone {
    int start, end, delta, id;
    bool operator<(Stone& rhs) {
        return start<rhs.start;
    }
};

void solve() {
    int n;
    cin >> n;
    vector<int> s(n), t(n);
    for (int i=0;i<n;i++) {
      cin >> s[i];
    }
    for (int i=0;i<n;i++) {
        cin >> t[i];
    }
    vector<Stone> stones(n);
    for (int i=0;i<n;i++) {
      stones[i].start = s[i];
      stones[i].end = t[i];
      stones[i].delta =  stones[i].end - stones[i].start;
      stones[i].id = i + 1;
    }
    sort(stones.begin(), stones.end());

    stack<Stone> shifted;
    vector<pair<pair<int,int>,int>> actions;
    for (int i=0;i<n;i++) {
        if (stones[i].delta==0) continue;
        if (stones[i].delta>0) {
            shifted.push(stones[i]);
        } else {
            while(!shifted.empty() && stones[i].delta<0) {
                int shift = min(shifted.top().delta, -stones[i].delta);
                stones[i].delta+=shift;
                shifted.top().delta-=shift;
                actions.push_back({{shifted.top().id, stones[i].id}, shift});
                if (shifted.top().delta==0) shifted.pop();
            }
            if (shifted.empty() && stones[i].delta!=0) {
                cout << "NO";
                return;
            }
        }
    }
    if (!shifted.empty()) {
        cout << "NO";
        return;
    }
    cout << "YES" << endl;
    cout << actions.size() << endl;
    for (int i=0;i<actions.size();i++) {
        cout << actions[i].first.first << " " << actions[i].first.second << " " << actions[i].second << endl;
    }
}
int main()
{
    cin.tie(0);
    cout.tie(0);
    ios_base::sync_with_stdio(false);
   // freopen("input.txt","r",stdin);
    solve();
    return 0;
}


#include <bits/stdc++.h>
#include <cassert>

using namespace std;

typedef long long ll;

const int maxn = 4*131072;
const ll INF = 1e9 + 7;

struct Stone {
    int start, end, delta, id;
    bool operator<(Stone& rhs) {
        return start<rhs.start;
    }
};

void solve() {
    int n;
    cin >> n;
    vector<int> s(n), t(n);
    for (int i=0;i<n;i++) {
      cin >> s[i];
    }
    for (int i=0;i<n;i++) {
        cin >> t[i];
    }
    vector<Stone> stones(n);
    for (int i=0;i<n;i++) {
      stones[i].start = s[i];
      stones[i].end = t[i];
      stones[i].delta =  stones[i].end - stones[i].start;
      stones[i].id = i + 1;
    }
    sort(stones.begin(), stones.end());

    stack<Stone> shifted;
    vector<pair<pair<int,int>,int>> actions;
    for (int i=0;i<n;i++) {
        if (stones[i].delta==0) continue;
        if (stones[i].delta>0) {
            shifted.push(stones[i]);
        } else {
            while(!shifted.empty() && stones[i].delta<0) {
                int shift = min(shifted.top().delta, -stones[i].delta);
                stones[i].delta+=shift;
                shifted.top().delta-=shift;
                actions.push_back({{shifted.top().id, stones[i].id}, shift});
                if (shifted.top().delta==0) shifted.pop();
            }
            if (shifted.empty() && stones[i].delta!=0) {
                cout << "NO";
                return;
            }
        }
    }
    if (!shifted.empty()) {
        cout << "NO";
        return;
    }
    cout << actions.size() << endl;
    for (int i=0;i<actions.size();i++) {
        cout << actions[i].first.first << " " << actions[i].first.second << " " << actions[i].second << endl;
    }
}
int main()
{
    cin.tie(0);
    cout.tie(0);
    ios_base::sync_with_stdio(false);
   // freopen("input.txt","r",stdin);
    solve();
    return 0;
}


#include <bits/stdc++.h>
#include <cassert>

using namespace std;

typedef long long ll;

const int maxn = 4*131072;
const ll INF = 1e9 + 7;

struct Stone {
    int start, end, delta, id;
    bool operator<(Stone& rhs) {
        return start<rhs.start;
    }
};

void solve() {
    int n;
    cin >> n;
    vector<pair<int,int>> s(n);
    vector<int> t(n);
    for (int i=0;i<n;i++) {
      cin >> s[i].first;
      s[i].second = i;
    }
    for (int i=0;i<n;i++) {
        cin >> t[i];
    }
    sort(s.begin(), s.end());
    sort(t.begin(), t.end());
    vector<pair<int,int>> deltas(n);
    for (int i=0;i<n;i++) {
        deltas[i].first = t[i] - s[i].first;
        deltas[i].second=  s[i].second;
    }

    stack<pair<int,int>> stack;
    vector<pair<pair<int,int>,int>> actions;
    for (int i=0;i<n;i++) {
        if (deltas[i].first==0) continue;
        if (deltas[i].first>0) {
            stack.push(deltas[i]);
        } else {
            while (!stack.empty() && deltas[i].first<0) {
                int delta = min(-deltas[i].first, stack.top().first);
                deltas[i].first += delta;
                stack.top().first -= delta;
                actions.push_back({{stack.top().second, deltas[i].second}, delta});
                if (stack.top().first==0) stack.pop();
            }
            if (stack.empty() && deltas[i].first!=0) {
                cout << "NO";
                return;
            }
        }
    }
    if (!stack.empty()) {
        cout << "NO";
        return;
    }
    cout << "YES" << endl;
    cout << actions.size() << endl;
    for (int i=0;i<actions.size();i++) {
        cout << actions[i].first.first+1 << " " << actions[i].first.second+1 << " " << actions[i].second << endl;
    }
}
int main()
{
    cin.tie(0);
    cout.tie(0);
    ios_base::sync_with_stdio(false);
    //freopen("input.txt","r",stdin);
    solve();
    return 0;
}