#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <queue>
#include <set>
#include <stack>
#include <map>
#include <iostream>
#include <vector>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define mp make_pair
#define pb push_back
#define MAXN 20000
#define MAXM 20000
const int maxn = 110;
const int mod = 1e9+7;
int now = 2;
int S,T;
int dis[MAXN];//,dl[MAXN];
int Head[MAXN],Next[MAXM],To[MAXM],FB[MAXM],Flow[MAXM],Cnt=0;//MAXM要考虑反边
int cur[MAXN];//当前弧优化

void add(int x,int y,int z)
{
    //printf("%d %d %d\n",x,y,z);
    Cnt++;Next[Cnt]=Head[x];Head[x]=Cnt;To[Cnt]=y;FB[Cnt]=Cnt+1,Flow[Cnt]=z;
    Cnt++;Next[Cnt]=Head[y];Head[y]=Cnt;To[Cnt]=x;FB[Cnt]=Cnt-1,Flow[Cnt]=0;
}
bool BFS(int Begin,int End)
{
    int x,X;
    memset(dis,0xff,sizeof(dis));
    dis[Begin]=0;
    queue <int> q;
    q.push(Begin);
    while(!q.empty())
    {
        x=q.front();
        q.pop();
        for(int i=Head[x];i;i=Next[i])
        {
            X=To[i];
            if(Flow[i]<=0||dis[X]>=0) continue;
            dis[X]=dis[x]+1;
            q.push(X);
        }
    }
    if(dis[End]>0) return true;
    else return false;
}
int Find(int x,int MFLOW,int y)
{
    if(x==y) return MFLOW;
    int X,h;
    for(int i=cur[x];i;i=Next[i])
    {
        cur[x]=i;
        X=To[i];
        if(Flow[i]>0&&dis[x]+1==dis[X]&&(h=Find(X,min(MFLOW,Flow[i]),y)))
        {
            Flow[i]-=h;
            Flow[FB[i]]+=h;
            return h;
        }
    }
    return 0;
}
int Solve(int x,int y)
{
    int X,Ans=0;
    while(1)
    {
        if(!BFS(x,y)) break;
        for(int i=S;i<=now;i++)//初始化全体cur
         cur[i]=Head[i];
        while((X=Find(x,0x7fffffff,y)))
            Ans+=X;
    }
    return Ans;
}

int n,m;
int a[maxn];
vector<pair<int,int> >P[maxn];
int g[maxn];
map<pair<int,int>,int>f;

void solve(){
    cin >> n >> m;
    int S = 1;
    int T = 2;
    for(int i=1;i<=n;i++) cin >> a[i];
    for(int i=1;i<=n;i++){
        int x = a[i];
        for(int j=2;j<=sqrt(x);j++){
            if(x%j==0){
                int s = 0;
                while(x%j==0) {x/=j;s++;}
                P[i].pb(mp(j,s));
                f[mp(i,j)] = ++now;
            }
        }
    }

    for(int i=1;i<=n;i+=2){
        for(int j=0;j<P[i].size();j++){
            add(S,f[mp(i,P[i][j].first)],P[i][j].second);
        }
    }

    for(int i=1;i<=m;i++){
        int u,v;
        cin >> u >> v;
        if(u%2==0) swap(u,v);
        for(int j=0;j<P[u].size();j++){
            int t = P[u][j].first;
            if(a[v]%t==0){
                int A = f[mp(u,t)];
                int B = f[mp(v,t)];
                int x = a[v];
                int s = 0;
                while(x%t==0){
                    x/=t;s++;
                }
                int w = min(s,P[u][j].second);
                add(A,B,w);
            }
        }
    }

    for(int i=2;i<=n;i+=2){
        for(int j=0;j<P[i].size();j++){
            add(f[mp(i,P[i][j].first)],T,P[i][j].second);

        }
    }
    printf("%d",Solve(S,T));
}

int main() {
    //int T;scanf("%d",&T);while(T--)
    solve();
    return 0;
}


#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <queue>
#include <set>
#include <stack>
#include <map>
#include <iostream>
#include <vector>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define mp make_pair
#define pb push_back
#define MAXN 20000
#define MAXM 20000
const int maxn = 110;
const int mod = 1e9+7;
int now = 2;
int S,T;
int dis[MAXN];//,dl[MAXN];
int Head[MAXN],Next[MAXM],To[MAXM],FB[MAXM],Flow[MAXM],Cnt=0;//MAXM要考虑反边
int cur[MAXN];//当前弧优化

void add(int x,int y,int z)
{
    //printf("%d %d %d\n",x,y,z);
    Cnt++;Next[Cnt]=Head[x];Head[x]=Cnt;To[Cnt]=y;FB[Cnt]=Cnt+1,Flow[Cnt]=z;
    Cnt++;Next[Cnt]=Head[y];Head[y]=Cnt;To[Cnt]=x;FB[Cnt]=Cnt-1,Flow[Cnt]=0;
}
bool BFS(int Begin,int End)
{
    int x,X;
    memset(dis,0xff,sizeof(dis));
    dis[Begin]=0;
    queue <int> q;
    q.push(Begin);
    while(!q.empty())
    {
        x=q.front();
        q.pop();
        for(int i=Head[x];i;i=Next[i])
        {
            X=To[i];
            if(Flow[i]<=0||dis[X]>=0) continue;
            dis[X]=dis[x]+1;
            q.push(X);
        }
    }
    if(dis[End]>0) return true;
    else return false;
}
int Find(int x,int MFLOW,int y)
{
    if(x==y) return MFLOW;
    int X,h;
    for(int i=cur[x];i;i=Next[i])
    {
        cur[x]=i;
        X=To[i];
        if(Flow[i]>0&&dis[x]+1==dis[X]&&(h=Find(X,min(MFLOW,Flow[i]),y)))
        {
            Flow[i]-=h;
            Flow[FB[i]]+=h;
            return h;
        }
    }
    return 0;
}
int Solve(int x,int y)
{
    int X,Ans=0;
    while(1)
    {
        if(!BFS(x,y)) break;
        for(int i=S;i<=now;i++)//初始化全体cur
         cur[i]=Head[i];
        while((X=Find(x,0x7fffffff,y)))
            Ans+=X;
    }
    return Ans;
}

int n,m;
int a[maxn];
vector<pair<int,int> >P[maxn];
int g[maxn];
map<pair<int,int>,int>f;

void solve(){
    cin >> n >> m;
    int S = 1;
    int T = 2;
    for(int i=1;i<=n;i++) cin >> a[i];
    for(int i=1;i<=n;i++){
        int x = a[i];
        int t = ceil(sqrt(x));
        for(int j=2;j<=t;j++){
            if(x<j) break;
            if(x%j==0){
                int s = 0;
                while(x%j==0) {x/=j;s++;}
                P[i].pb(mp(j,s));
                f[mp(i,j)] = ++now;
            }
        }
        if(x>1){
            P[i].pb(mp(x,1));
            f[mp(i,x)] = ++now;
        }
    }

    for(int i=1;i<=n;i+=2){
        for(int j=0;j<P[i].size();j++){
            add(S,f[mp(i,P[i][j].first)],P[i][j].second);
        }
    }

    for(int i=1;i<=m;i++){
        int u,v;
        cin >> u >> v;
        if(u%2==0) swap(u,v);
        for(int j=0;j<P[u].size();j++){
            int t = P[u][j].first;
            if(a[v]%t==0){
                int A = f[mp(u,t)];
                int B = f[mp(v,t)];
                int x = a[v];
                int s = 0;
                while(x%t==0){
                    x/=t;s++;
                }
                int w = min(s,P[u][j].second);
                add(A,B,w);
            }
        }
    }

    for(int i=2;i<=n;i+=2){
        for(int j=0;j<P[i].size();j++){
            add(f[mp(i,P[i][j].first)],T,P[i][j].second);

        }
    }
    printf("%d",Solve(S,T));
}

int main() {
    //int T;scanf("%d",&T);while(T--)
    solve();
    return 0;
}


#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <queue>
#include <set>
#include <stack>
#include <map>
#include <iostream>
#include <vector>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define mp make_pair
#define pb push_back
#define MAXN 20000
#define MAXM 20000
const int maxn = 110;
const int mod = 1e9+7;
int now = 2;
int S,T;
int dis[MAXN];//,dl[MAXN];
int Head[MAXN],Next[MAXM],To[MAXM],FB[MAXM],Flow[MAXM],Cnt=0;//MAXM要考虑反边
int cur[MAXN];//当前弧优化

void add(int x,int y,int z)
{
    //printf("%d %d %d\n",x,y,z);
    Cnt++;Next[Cnt]=Head[x];Head[x]=Cnt;To[Cnt]=y;FB[Cnt]=Cnt+1,Flow[Cnt]=z;
    Cnt++;Next[Cnt]=Head[y];Head[y]=Cnt;To[Cnt]=x;FB[Cnt]=Cnt-1,Flow[Cnt]=0;
}
bool BFS(int Begin,int End)
{
    int x,X;
    memset(dis,0xff,sizeof(dis));
    dis[Begin]=0;
    queue <int> q;
    q.push(Begin);
    while(!q.empty())
    {
        x=q.front();
        q.pop();
        for(int i=Head[x];i;i=Next[i])
        {
            X=To[i];
            if(Flow[i]<=0||dis[X]>=0) continue;
            dis[X]=dis[x]+1;
            q.push(X);
        }
    }
    if(dis[End]>0) return true;
    else return false;
}
int Find(int x,int MFLOW,int y)
{
    if(x==y) return MFLOW;
    int X,h;
    for(int i=cur[x];i;i=Next[i])
    {
        cur[x]=i;
        X=To[i];
        if(Flow[i]>0&&dis[x]+1==dis[X]&&(h=Find(X,min(MFLOW,Flow[i]),y)))
        {
            Flow[i]-=h;
            Flow[FB[i]]+=h;
            return h;
        }
    }
    return 0;
}
int Solve(int x,int y)
{
    int X,Ans=0;
    while(1)
    {
        if(!BFS(x,y)) break;
        for(int i=S;i<=now;i++)//初始化全体cur
         cur[i]=Head[i];
        while((X=Find(x,0x7fffffff,y)))
            Ans+=X;
    }
    return Ans;
}

int n,m;
int a[maxn];
vector<pair<int,int> >P[maxn];
int g[maxn];
map<pair<int,int>,int>f;

void solve(){
    cin >> n >> m;
    int S = 1;
    int T = 2;

    for(int i=1;i<=n;i++) cin >> a[i];
    for(int i=1;i<=n;i++){
        int x = a[i];
        for(int j=2;j<=x;j++){
            if(x%j==0){
                int s = 0;
                while(x%j==0) {x/=j;s++;}
                P[i].pb(mp(j,s));
                f[mp(i,j)] = ++now;
            }
        }
    }

    for(int i=1;i<=n;i+=2){
        for(int j=0;j<P[i].size();j++){
            add(S,f[mp(i,P[i][j].first)],P[i][j].second);
        }
    }

    for(int i=1;i<=m;i++){
        int u,v;
        cin >> u >> v;
        if(u%2==0) swap(u,v);
        for(int j=0;j<P[u].size();j++){
            int t = P[u][j].first;
            if(a[v]%t==0){
                int A = f[mp(u,t)];
                int B = f[mp(v,t)];
                int x = a[v];
                int s = 0;
                while(x%t==0){
                    x/=t;s++;
                }
                int w = min(s,P[u][j].second);
                add(A,B,w);
            }
        }
    }

    for(int i=2;i<=n;i+=2){
        for(int j=0;j<P[i].size();j++){
            add(f[mp(i,P[i][j].first)],T,P[i][j].second);

        }
    }
    printf("%d",Solve(S,T));
}

int main() {
    //int T;scanf("%d",&T);while(T--)
    solve();
    return 0;
}


#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <queue>
#include <set>
#include <stack>
#include <map>
#include <iostream>
#include <vector>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define mp make_pair
#define pb push_back
#define MAXN 20000
#define MAXM 20000
const int maxn = 110;
const int mod = 1e9+7;
int now = 2;
int S,T;
int dis[MAXN];//,dl[MAXN];
int Head[MAXN],Next[MAXM],To[MAXM],FB[MAXM],Flow[MAXM],Cnt=0;//MAXM要考虑反边
int cur[MAXN];//当前弧优化

void add(int x,int y,int z)
{
    //printf("%d %d %d\n",x,y,z);
    Cnt++;Next[Cnt]=Head[x];Head[x]=Cnt;To[Cnt]=y;FB[Cnt]=Cnt+1,Flow[Cnt]=z;
    Cnt++;Next[Cnt]=Head[y];Head[y]=Cnt;To[Cnt]=x;FB[Cnt]=Cnt-1,Flow[Cnt]=0;
}
bool BFS(int Begin,int End)
{
    int x,X;
    memset(dis,0xff,sizeof(dis));
    dis[Begin]=0;
    queue <int> q;
    q.push(Begin);
    while(!q.empty())
    {
        x=q.front();
        q.pop();
        for(int i=Head[x];i;i=Next[i])
        {
            X=To[i];
            if(Flow[i]<=0||dis[X]>=0) continue;
            dis[X]=dis[x]+1;
            q.push(X);
        }
    }
    if(dis[End]>0) return true;
    else return false;
}
int Find(int x,int MFLOW,int y)
{
    if(x==y) return MFLOW;
    int X,h;
    for(int i=cur[x];i;i=Next[i])
    {
        cur[x]=i;
        X=To[i];
        if(Flow[i]>0&&dis[x]+1==dis[X]&&(h=Find(X,min(MFLOW,Flow[i]),y)))
        {
            Flow[i]-=h;
            Flow[FB[i]]+=h;
            return h;
        }
    }
    return 0;
}
int Solve(int x,int y)
{
    int X,Ans=0;
    while(1)
    {
        if(!BFS(x,y)) break;
        for(int i=S;i<=now;i++)//初始化全体cur
         cur[i]=Head[i];
        while((X=Find(x,0x7fffffff,y)))
            Ans+=X;
    }
    return Ans;
}

int n,m;
int a[maxn];
vector<pair<int,int> >P[maxn];
int g[maxn];
map<pair<int,int>,int>f;

void solve(){
    cin >> n >> m;
    int S = 1;
    int T = 2;
    for(int i=1;i<=n;i++) cin >> a[i];
    for(int i=1;i<=n;i++){
        int x = a[i];
        int t = ceil(sqrt(x));
        for(int j=2;j<=t;j++){
            if(x<j) break;
            if(x%j==0){
                int s = 0;
                while(x%j==0) {x/=j;s++;}
                P[i].pb(mp(j,s));
                f[mp(i,j)] = ++now;
            }
        }
        if(x>0){
            P[i].pb(mp(x,1));
            f[mp(i,x)] = ++now;
        }
    }

    for(int i=1;i<=n;i+=2){
        for(int j=0;j<P[i].size();j++){
            add(S,f[mp(i,P[i][j].first)],P[i][j].second);
        }
    }

    for(int i=1;i<=m;i++){
        int u,v;
        cin >> u >> v;
        if(u%2==0) swap(u,v);
        for(int j=0;j<P[u].size();j++){
            int t = P[u][j].first;
            if(a[v]%t==0){
                int A = f[mp(u,t)];
                int B = f[mp(v,t)];
                int x = a[v];
                int s = 0;
                while(x%t==0){
                    x/=t;s++;
                }
                int w = min(s,P[u][j].second);
                add(A,B,w);
            }
        }
    }

    for(int i=2;i<=n;i+=2){
        for(int j=0;j<P[i].size();j++){
            add(f[mp(i,P[i][j].first)],T,P[i][j].second);

        }
    }
    printf("%d",Solve(S,T));
}

int main() {
    //int T;scanf("%d",&T);while(T--)
    solve();
    return 0;
}


#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <queue>
#include <set>
#include <stack>
#include <map>
#include <iostream>
#include <vector>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define mp make_pair
#define pb push_back
#define MAXN 20000
#define MAXM 20000
const int maxn = 110;
const int mod = 1e9+7;
int now = 2;
int S,T;
int dis[MAXN];//,dl[MAXN];
int Head[MAXN],Next[MAXM],To[MAXM],FB[MAXM],Flow[MAXM],Cnt=0;//MAXM要考虑反边
int cur[MAXN];//当前弧优化

void add(int x,int y,int z)
{
    //printf("%d %d %d\n",x,y,z);
    Cnt++;Next[Cnt]=Head[x];Head[x]=Cnt;To[Cnt]=y;FB[Cnt]=Cnt+1,Flow[Cnt]=z;
    Cnt++;Next[Cnt]=Head[y];Head[y]=Cnt;To[Cnt]=x;FB[Cnt]=Cnt-1,Flow[Cnt]=0;
}
bool BFS(int Begin,int End)
{
    int x,X;
    memset(dis,0xff,sizeof(dis));
    dis[Begin]=0;
    queue <int> q;
    q.push(Begin);
    while(!q.empty())
    {
        x=q.front();
        q.pop();
        for(int i=Head[x];i;i=Next[i])
        {
            X=To[i];
            if(Flow[i]<=0||dis[X]>=0) continue;
            dis[X]=dis[x]+1;
            q.push(X);
        }
    }
    if(dis[End]>0) return true;
    else return false;
}
int Find(int x,int MFLOW,int y)
{
    if(x==y) return MFLOW;
    int X,h;
    for(int i=cur[x];i;i=Next[i])
    {
        cur[x]=i;
        X=To[i];
        if(Flow[i]>0&&dis[x]+1==dis[X]&&(h=Find(X,min(MFLOW,Flow[i]),y)))
        {
            Flow[i]-=h;
            Flow[FB[i]]+=h;
            return h;
        }
    }
    return 0;
}
int Solve(int x,int y)
{
    int X,Ans=0;
    while(1)
    {
        if(!BFS(x,y)) break;
        for(int i=S;i<=now;i++)//初始化全体cur
         cur[i]=Head[i];
        while((X=Find(x,0x7fffffff,y)))
            Ans+=X;
    }
    return Ans;
}

int n,m;
int a[maxn];
vector<pair<int,int> >P[maxn];
int g[maxn];
map<pair<int,int>,int>f;

void solve(){
    cin >> n >> m;
    int S = 1;
    int T = 2;
    for(int i=1;i<=n;i++) cin >> a[i];
    for(int i=1;i<=n;i++){
        int x = a[i];
        int t = ceil(sqrt(x));
        for(int j=2;j<=t;j++){
            if(x<j) break;
            if(x%j==0){
                int s = 0;
                while(x%j==0) {x/=j;s++;}
                P[i].pb(mp(j,s));
                f[mp(i,j)] = ++now;
            }
        }
    }

    for(int i=1;i<=n;i+=2){
        for(int j=0;j<P[i].size();j++){
            add(S,f[mp(i,P[i][j].first)],P[i][j].second);
        }
    }

    for(int i=1;i<=m;i++){
        int u,v;
        cin >> u >> v;
        if(u%2==0) swap(u,v);
        for(int j=0;j<P[u].size();j++){
            int t = P[u][j].first;
            if(a[v]%t==0){
                int A = f[mp(u,t)];
                int B = f[mp(v,t)];
                int x = a[v];
                int s = 0;
                while(x%t==0){
                    x/=t;s++;
                }
                int w = min(s,P[u][j].second);
                add(A,B,w);
            }
        }
    }

    for(int i=2;i<=n;i+=2){
        for(int j=0;j<P[i].size();j++){
            add(f[mp(i,P[i][j].first)],T,P[i][j].second);

        }
    }
    printf("%d",Solve(S,T));
}

int main() {
    //int T;scanf("%d",&T);while(T--)
    solve();
    return 0;
}


#include<bits/stdc++.h>
//#define pb push_back
#define mp make_pair
#define fst first
#define snd second
using namespace std;

typedef long long ll;
typedef double db;
typedef long double ldb;

template<class T> inline void checkmin(T &a,const T &b){if(b<a) a=b;}
template<class T> inline void checkmax(T &a,const T &b){if(b>a) a=b;}

const int inf=1e9+10;
const int maxn=2e3+10;

struct edge{
	int to,rev,cap;
};

vector <edge> g[maxn];
int n,m,a[maxn];
vector <pair<int,pair<int,int> > > v[maxn];
int s,t,cnt=0;

void add_edge(int a,int b,int flow){
	edge e1; e1.to=b; e1.rev=g[b].size(); e1.cap=flow;
	edge e2; e2.to=a; e2.rev=g[a].size(); e2.cap=0;
	g[a].push_back(e1); g[b].push_back(e2);
}

int level[maxn],iter[maxn];
queue <int> que;

void bfs(int s,int t){
	for(int i=0;i<maxn;i++) level[i]=-1;
	while(!que.empty()) que.pop();
	level[s]=0;
	que.push(s);
	while(!que.empty()){
		int x=que.front(); que.pop();
		for(int i=0;i<g[x].size();i++){
			edge &e=g[x][i];
			if(e.cap>0&&level[e.to]<0){
				level[e.to]=level[x]+1;
				que.push(e.to);
			}
		}
	}
}

int dfs(int x,int t,int flow){
	if(x==t) return flow;
	for(int &i=iter[x];i<g[x].size();i++){
		edge &e=g[x][i];
		if(e.cap>0&&level[e.to]>level[x]){
			int d=dfs(e.to,t,min(flow,e.cap));
			if(d>0){
				e.cap-=d;
				g[e.to][e.rev].cap+=d;
				return d;
			}
		}
	}
	return 0;
}

int max_flow(int s,int t){
	int flow=0;
	for(;;){
		bfs(s,t);
		if(level[t]==-1) return flow;
		for(int i=0;i<maxn;i++) iter[i]=0;
		int f;
		while((f=dfs(s,t,inf))>0) flow+=f;
	}
	return flow;
}

int main(){
	scanf("%d%d",&n,&m);
	for(int i=0;i<n;i++) scanf("%d",&a[i]);
	s=cnt++; t=cnt++;
	for(int i=0;i<n;i++){
		int val=a[i];
		for(int j=2;j*j<=a[i];j++){
			int sum=0;
			while(val%j==0){
				val/=j;
				sum++;
			}
			if(sum>0) v[i].push_back(mp(cnt++,mp(j,sum)));
		}
		if(val>1) v[i].push_back(mp(cnt++,mp(val,1)));
	}
/*	for(int i=0;i<n;i++){
		for(int j=0;j<v[i].size();j++)
			cout<<v[i][j].fst<<":"<<v[i][j].snd.fst<<","<<v[i][j].snd.snd<<" ";
		cout<<endl;
	}
*/
//	cout<<cnt<<endl;
	for(int i=0;i<n;i+=2){
		for(int j=0;j<v[i].size();j++){
			int x=v[i][j].fst,flow=v[i][j].snd.snd;
			add_edge(s,x,flow);
		}
	}
	for(int i=1;i<n;i+=2){
		for(int j=0;j<v[i].size();j++){
			int x=v[i][j].fst,flow=v[i][j].snd.snd;
			add_edge(x,t,flow);
		}
	}
	for(int i=0;i<m;i++){
		int a,b;
		scanf("%d%d",&a,&b);
		a--; b--;
		if(a%2!=0) swap(a,b);
		for(int i=0;i<v[a].size();i++){
			for(int j=0;j<v[b].size();j++){
				if(v[b][j].snd.fst==v[a][i].snd.fst){
					add_edge(v[a][i].fst,v[b][j].fst,inf);
				}
			}
		}
	}
	int ans=max_flow(s,t);
	printf("%d\n",ans);
	return 0;
}


#include<bits/stdc++.h>
//#define pb push_back
#define mp make_pair
#define fst first
#define snd second
using namespace std;

typedef long long ll;
typedef double db;
typedef long double ldb;

template<class T> inline void checkmin(T &a,const T &b){if(b<a) a=b;}
template<class T> inline void checkmax(T &a,const T &b){if(b>a) a=b;}

const int inf=1e9+10;
const int maxn=2e3+10;

struct edge{
	int to,rev,cap;
};

vector <edge> g[maxn];
int n,m,a[maxn];
vector <pair<int,pair<int,int> > > v[maxn];
int s,t,cnt=0;

void add_edge(int a,int b,int flow){
	edge e1; e1.to=b; e1.rev=g[b].size(); e1.cap=flow;
	edge e2; e2.to=a; e2.rev=g[a].size(); e2.cap=0;
	g[a].push_back(e1); g[b].push_back(e2);
}

int level[maxn],iter[maxn];
queue <int> que;

void bfs(int s,int t){
	for(int i=0;i<maxn;i++) level[i]=-1;
	while(!que.empty()) que.pop();
	level[s]=0;
	que.push(s);
	while(!que.empty()){
		int x=que.front(); que.pop();
		for(int i=0;i<g[x].size();i++){
			edge &e=g[x][i];
			if(e.cap>0&&level[e.to]<0){
				level[e.to]=level[x]+1;
				que.push(e.to);
			}
		}
	}
}

int dfs(int x,int t,int flow){
	if(x==t) return flow;
	for(int &i=iter[x];i<g[x].size();i++){
		edge &e=g[x][i];
		if(e.cap>0&&level[e.to]>level[x]){
			int d=dfs(e.to,t,min(flow,e.cap));
			if(d>0){
				e.cap-=d;
				g[e.to][e.rev].cap+=d;
				return d;
			}
		}
	}
	return 0;
}

int max_flow(int s,int t){
	int flow=0;
	for(;;){
		bfs(s,t);
		if(level[t]==-1) return flow;
		for(int i=0;i<maxn;i++) iter[i]=0;
		int f;
		while((f=dfs(s,t,inf))>0) flow+=f;
	}
	return flow;
}

int main(){
	scanf("%d%d",&n,&m);
	for(int i=0;i<n;i++) scanf("%d",&a[i]);
	s=cnt++; t=cnt++;
	for(int i=0;i<n;i++){
		int val=a[i];
		for(int j=2;j*j<=a[i];j++){
			int sum=0;
			while(val%j==0){
				val/=j;
				sum++;
			}
			if(sum>0) v[i].push_back(mp(cnt++,mp(j,sum)));
		}
		if(val>1) v[i].push_back(mp(cnt++,mp(val,1)));
	}
/*	for(int i=0;i<n;i++){
		for(int j=0;j<v[i].size();j++)
			cout<<v[i][j].fst<<":"<<v[i][j].snd.fst<<","<<v[i][j].snd.snd<<" ";
		cout<<endl;
	}
*/
//	cout<<cnt<<endl;
	for(int i=0;i<n;i+=2){
		for(int j=0;j<v[i].size();j++){
			int x=v[i][j].fst,flow=v[i][j].snd.snd;
			add_edge(s,x,flow);
		}
	}
	for(int i=1;i<n;i+=2){
		for(int j=0;j<v[i].size();j++){
			int x=v[i][j].fst,flow=v[i][j].snd.snd;
			add_edge(x,t,flow);
		}
	}
	for(int i=0;i<m;i++){
		int a,b;
		scanf("%d%d",&a,&b);
		if(a%2!=0) swap(a,b);
		for(int i=0;i<v[a].size();i++){
			for(int j=0;j<v[b].size();j++){
				if(v[b][j].snd.fst==v[a][i].snd.fst){
					add_edge(v[a][i].fst,v[b][j].fst,inf);
				}
			}
		}
	}
	int ans=max_flow(s,t);
	printf("%d\n",ans);
	return 0;
}


#include<bits/stdc++.h>
//#define pb push_back
#define mp make_pair
#define fst first
#define snd second
using namespace std;

typedef long long ll;
typedef double db;
typedef long double ldb;

template<class T> inline void checkmin(T &a,const T &b){if(b<a) a=b;}
template<class T> inline void checkmax(T &a,const T &b){if(b>a) a=b;}

const int inf=1e9+10;
const int maxn=1e3+10;

struct edge{
	int to,rev,cap;
};

vector <edge> g[maxn];
int n,m,a[maxn];
vector <pair<int,pair<int,int> > > v[maxn];
int s,t,cnt=0;

void add_edge(int a,int b,int flow){
	edge e1; e1.to=b; e1.rev=g[b].size(); e1.cap=flow;
	edge e2; e2.to=a; e2.rev=g[a].size(); e2.cap=0;
	g[a].push_back(e1); g[b].push_back(e2);
}

int level[maxn],iter[maxn];
queue <int> que;

void bfs(int s,int t){
	for(int i=0;i<maxn;i++) level[i]=-1;
	while(!que.empty()) que.pop();
	level[s]=0;
	que.push(s);
	while(!que.empty()){
		int x=que.front(); que.pop();
		for(int i=0;i<g[x].size();i++){
			edge &e=g[x][i];
			if(e.cap>0&&level[e.to]<0){
				level[e.to]=level[x]+1;
				que.push(e.to);
			}
		}
	}
}

int dfs(int x,int t,int flow){
	if(x==t) return flow;
	for(int &i=iter[x];i<g[x].size();i++){
		edge &e=g[x][i];
		if(e.cap>0&&level[e.to]>level[x]){
			int d=dfs(e.to,t,min(flow,e.cap));
			if(d>0){
				e.cap-=d;
				g[e.to][e.rev].cap+=d;
				return d;
			}
		}
	}
	return 0;
}

int max_flow(int s,int t){
	int flow=0;
	for(;;){
		bfs(s,t);
		if(level[t]==-1) return flow;
		for(int i=0;i<maxn;i++) iter[i]=0;
		int f;
		while((f=dfs(s,t,inf))>0) flow+=f;
	}
	return flow;
}

int main(){
	scanf("%d%d",&n,&m);
	for(int i=0;i<n;i++) scanf("%d",&a[i]);
	s=cnt++; t=cnt++;
	for(int i=0;i<n;i++){
		int val=a[i];
		for(int j=2;j*j<=a[i];j++){
			int sum=0;
			while(val%j==0){
				val/=j;
				sum++;
			}
			v[i].push_back(mp(cnt++,mp(j,sum)));
		}
		if(val>1) v[i].push_back(mp(cnt++,mp(val,1)));
	}
/*	for(int i=0;i<n;i++){
		for(int j=0;j<v[i].size();j++)
			cout<<v[i][j].fst<<":"<<v[i][j].snd.fst<<","<<v[i][j].snd.snd<<" ";
		cout<<endl;
	}
*/
	for(int i=0;i<n;i+=2){
		for(int j=0;j<v[i].size();j++){
			int x=v[i][j].fst,flow=v[i][j].snd.snd;
			add_edge(s,x,flow);
		}
	}
	for(int i=1;i<n;i+=2){
		for(int j=0;j<v[i].size();j++){
			int x=v[i][j].fst,flow=v[i][j].snd.snd;
			add_edge(x,t,flow);
		}
	}
	for(int i=0;i<m;i++){
		int a,b;
		scanf("%d%d",&a,&b);
		if(a%2!=0) swap(a,b);
		for(int i=0;i<v[a].size();i++){
			for(int j=0;j<v[b].size();j++){
				if(v[b][j].snd.fst==v[a][i].snd.fst){
					add_edge(v[a][i].fst,v[b][j].fst,inf);
				}
			}
		}
	}
	int ans=max_flow(s,t);
	printf("%d\n",ans);
	return 0;
}


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

const int MAX_N=1e2+10;
const int INF=1e9+10;
const int MAX_M=1e5+10;

vector <int> g[MAX_N*4],p;
vector <pair<int,int> > v;
pair<pair<int,int>,int> e[MAX_M];
int S,T,N,M,m=0,n=0,a[MAX_N],dist[MAX_N*4];
map <int,int> Map1;
map <pair<int,int>,int> Map2;
bool vis[MAX_N*4];
queue <int> Q;

bool check(int val){
	for(int i=2;i*i<=val;i++) if(val%i==0)
		return false;
	return true;
}

void prepare(){
	for(int i=2;i*i<=INF;i++) if(check(i)) p.push_back(i);
}

int get_val(int val1,int val2,int div){
	int ret=0;
	while(val1%div==0&&val2%div==0){
		val1/=div;
		val2/=div;
		ret++;
	}
	return ret;
}

void add_edge(int u,int v,int cost){
	g[u].push_back(m);
	e[m].first.first=u;
	e[m].first.second=v;
	e[m].second=cost;
	m++;
	g[v].push_back(m);
	e[m].first.first=v;
	e[m].first.second=u;
	e[m].second=cost;
	m++;
}

bool bfs(){
	for(int i=0;i<MAX_N*4;i++) dist[i]=INF;
	while(Q.size()) Q.pop();
	dist[S]=0;
	Q.push(S);
	while(Q.size()){
		int x=Q.front();
		Q.pop();
		for(int i=0;i<g[x].size();i++){
			int Mark=g[x][i];
			int to=e[Mark].first.second;
			int cost=e[Mark].second;
			if(cost>0&&dist[to]==INF){
				dist[to]=dist[x]+1;
				Q.push(to);
			}
		}
	}
	if(dist[T]==INF) return false;
	return true;
}

int dfs(int x,int flow){
	if(x==T||flow==0) return flow;
	int ret=0;
	for(int i=0;i<g[x].size();i++){
		int Mark=g[x][i];
		int to=e[Mark].first.second;
		int cost=e[Mark].second;
		if(vis[to]) continue;
		if(dist[to]!=dist[x]+1) continue;
		if(cost==0) continue;
		vis[to]=1;
		int val=dfs(to,min(flow,cost));
		e[Mark].second-=val;
		e[Mark^1].second+=val;
		ret+=val;
		flow-=val;
		if(flow==0) return ret;
	}
	return ret;
}

int get_flow(){
	int ret=0;
	while(bfs()){
		for(int i=0;i<4*MAX_N;i++) vis[i]=0;
		ret+=dfs(S,INF);
	}
	return ret;
}

int main(){
	prepare();
	scanf("%d%d",&N,&M);
	for(int i=0;i<N;i++) scanf("%d",&a[i]);
	for(int i=0;i<M;i++){
		int x,y;
		scanf("%d%d",&x,&y);
		x--; y--;
		v.push_back(make_pair(x,y));
	}
	for(int i=0;i<p.size();i++){
		for(int j=0;j<v.size();j++){
			int x=v[j].first,y=v[j].second;
			if(a[x]%p[i]==0&&a[y]%p[i]==0) Map1[p[i]]=n++;
		}
	}
	for(int i=0;i<v.size();i++) Map2[make_pair(v[i].first,v[i].second)]=n++;
	S=n++; T=n++;
	for(int i=0;i<p.size();i++){
		bool flag=false;
		for(int j=0;j<v.size();j++){
			int x=v[j].first,y=v[j].second;
			if(a[x]%p[i]==0&&a[y]%p[j]==0){
				if(!flag) add_edge(S,Map1[p[i]],INF);
				flag=true;
				add_edge(Map1[p[i]],Map2[make_pair(x,y)],get_val(a[x],a[y],p[i]));
			}
		}
	}
	for(int i=0;i<v.size();i++)
		add_edge(Map2[make_pair(v[i].first,v[i].second)],T,INF);
	int ans=get_flow();
	printf("%d\n",ans);
	return 0;
}


#include<bits/stdc++.h>
//#define pb push_back
#define mp make_pair
#define fst first
#define snd second
using namespace std;

typedef long long ll;
typedef double db;
typedef long double ldb;

template<class T> inline void checkmin(T &a,const T &b){if(b<a) a=b;}
template<class T> inline void checkmax(T &a,const T &b){if(b>a) a=b;}

const int inf=1e9+10;
const int maxn=2e3+10;

struct edge{
	int to,cap,rev;
};

vector <edge> g[maxn];
int n,m,a[maxn];
vector <pair<int,pair<int,int> > > v[maxn];
int s,t,cnt=0;

void add_edge(int from,int to,int cap){
	g[from].push_back((edge){to,cap,g[to].size()});
	g[to].push_back((edge){from,0,g[from].size()-1});
}

int level[maxn],iter[maxn];
queue <int> que;

void bfs(int s,int t){
	for(int i=0;i<maxn;i++) level[i]=-1;
	while(!que.empty()) que.pop();
	level[s]=0;
	que.push(s);
	while(!que.empty()){
		int x=que.front(); que.pop();
		for(int i=0;i<g[x].size();i++){
			edge &e=g[x][i];
			if(e.cap>0&&level[e.to]<0){
				level[e.to]=level[x]+1;
				que.push(e.to);
			}
		}
	}
}

int dfs(int x,int t,int flow){
	if(x==t) return flow;
	for(int &i=iter[x];i<g[x].size();i++){
		edge &e=g[x][i];
		if(e.cap>0&&level[e.to]>level[x]){
			int d=dfs(e.to,t,min(flow,e.cap));
			if(d>0){
				e.cap-=d;
				g[e.to][e.rev].cap+=d;
				return d;
			}
		}
	}
	return 0;
}

int max_flow(int s,int t){
	int flow=0;
	for(;;){
		bfs(s,t);
		if(level[t]==-1) return flow;
		for(int i=0;i<maxn;i++) iter[i]=0;
		int f;
		while((f=dfs(s,t,inf))>0) flow+=f;
	}
	return flow;
}

int main(){
	scanf("%d%d",&n,&m);
	for(int i=0;i<n;i++) scanf("%d",&a[i]);
	s=cnt++; t=cnt++;
	for(int i=0;i<n;i++){
		int val=a[i];
		for(int j=2;j*j<=a[i];j++){
			int sum=0;
			while(val%j==0){
				val/=j;
				sum++;
			}
			if(sum>0) v[i].push_back(mp(cnt++,mp(j,sum)));
		}
		if(val>1) v[i].push_back(mp(cnt++,mp(val,1)));
	}
/*	for(int i=0;i<n;i++){
		for(int j=0;j<v[i].size();j++)
			cout<<v[i][j].fst<<":"<<v[i][j].snd.fst<<","<<v[i][j].snd.snd<<" ";
		cout<<endl;
	}
*/
//	cout<<cnt<<endl;
	for(int i=0;i<n;i+=2){
		for(int j=0;j<v[i].size();j++){
			int x=v[i][j].fst,flow=v[i][j].snd.snd;
			add_edge(s,x,flow);
		}
	}
	for(int i=1;i<n;i+=2){
		for(int j=0;j<v[i].size();j++){
			int x=v[i][j].fst,flow=v[i][j].snd.snd;
			add_edge(x,t,flow);
		}
	}
	for(int i=0;i<m;i++){
		int a,b;
		scanf("%d%d",&a,&b);
		a--; b--;
		if(a%2!=0) swap(a,b);
		for(int i=0;i<v[a].size();i++){
			for(int j=0;j<v[b].size();j++){
				if(v[b][j].snd.fst==v[a][i].snd.fst){
					add_edge(v[a][i].fst,v[b][j].fst,inf);
				}
			}
		}
	}
	int ans=max_flow(s,t);
	printf("%d\n",ans);
	return 0;
}


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

const int MAX_N=1e2+10;
const int MAX_M=1e2+10;
const int MAX_INT=1e9+10;
const int INF=1e9+10;

vector <int> g[MAX_N],p,v,cans;
pair<pair<int,int>,int> e[4*MAX_M];
pair<int,int> t[MAX_M];
int N,M,m=0,S,T,a[MAX_N],dist[MAX_N];
queue <int> Q;
bool vis[MAX_N],graph1[MAX_N],graph2[MAX_N];

bool is_prime(int val){
	for(int i=2;i*i<=val;i++)
		if(val%i==0) return false;
	return true;
}

void get_prime(){
	for(int i=2;i*i<=MAX_INT;i++)
		if(is_prime(i)) p.push_back(i);
}

void graph_clear(){
	for(int i=0;i<MAX_N;i++) g[i].clear();
	for(int i=0;i<MAX_N;i++) graph1[i]=0;
	for(int i=0;i<MAX_N;i++) graph2[i]=0;
	m=0; S=N; T=N+1;
}

int get1(int val,int x){
	int ret=0;
	while(val%x==0){
		val/=x;
		ret++;
	}
	return ret;
}

int get2(int val1,int val2,int x){
	int ret=0;
	while(val1%x==0&&val2%x==0){
		val1/=x;
		val2/=x;
		ret++;
	}
	return ret;
}

void add_edge(int u,int v,int cost){
	g[u].push_back(m);
	e[m].first.first=u;
	e[m].first.second=v;
	e[m].second=cost;
	m++;
	g[v].push_back(m);
	e[m].first.first=v;
	e[m].first.second=u;
	e[m].second=0;
	m++;
}

bool bfs(){
	for(int i=0;i<MAX_N;i++) dist[i]=INF;
	while(Q.size()) Q.pop();
	dist[S]=0;
	Q.push(S);
	while(Q.size()){
		int x=Q.front();
		Q.pop();
		for(int i=0;i<g[x].size();i++){
		//	printf("%d\n",e[g[x][i]].first.second+1);
			int Mark=g[x][i];
			int to=e[Mark].first.second;
			int cost=e[Mark].second;
			if(dist[to]==INF&&cost>0){
				dist[to]=dist[x]+1;
				Q.push(to);
			}
		}
	}
	if(dist[T]==INF) return false;
	return true;
}

int dfs(int x,int flow){
	if(x==T||flow==0) return flow;
	int ret=0;
	for(int i=0;i<g[x].size();i++){
		int Mark=g[x][i];
		int to=e[Mark].first.second;
		int cost=e[Mark].second;
		if(dist[to]!=dist[x]+1) continue;
		if(vis[to]) continue;
		if(cost==0) continue;
		vis[to]=1;
		int val=dfs(to,min(flow,cost));
		e[Mark].second-=cost;
		e[Mark^1].second+=cost;
		ret+=cost;
		flow-=cost;
		if(flow==0) return ret;
	}
	return ret;
}

int get_flow(){
	int ret=0;
	while(bfs()){
		for(int i=0;i<MAX_N;i++) vis[i]=0;
		ret+=dfs(S,INF);
	}
	return ret;
}

int main(){
	get_prime();
	scanf("%d%d",&N,&M);
	for(int i=0;i<N;i++) scanf("%d",&a[i]);
	for(int i=0;i<M;i++){
		int u,v;
		scanf("%d%d",&u,&v);
		u--; v--;
		if(u%2==0) swap(u,v);
		t[i].first=u; t[i].second=v;
	}
	for(int i=0;i<p.size();i++){
		bool flag=false;
		int np=p[i];
		for(int j=0;j<M;j++){
			int u=t[j].first,v=t[j].second;
			if(a[u]%np==0&&a[v]%np==0) flag=true;
		}
		if(flag) cans.push_back(np);
	}
//	for(int i=0;i<cans.size();i++)
//		printf("%d ",cans[i]);
//	printf("\n");
	int ans=0;
	for(int i=0;i<cans.size();i++){
		graph_clear();
		int np=cans[i];
		for(int j=0;j<M;j++){
			int u=t[j].first,v=t[j].second;
			if(a[u]%np==0&&a[v]%np==0){
			//	printf("%d %d %d\n",a[u],a[v],np);
				if(!graph1[u]){
				//	cout<<"YES"<<endl;
					graph1[u]=1;
					add_edge(S,u,get1(a[u],np));
				//	printf("%d\n",get1(a[u],np));
				}
				add_edge(u,v,get2(a[u],a[v],np));
				if(!graph2[v]){
					graph2[v]=1;
					add_edge(u,T,get1(a[v],np));
				}
			}
		}
	//	printf("%d\n",get_flow());
		ans+=get_flow();
	}
	printf("%d\n",ans);
	return 0;
}


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

const int MAX_N=1e2+10;
const int MAX_M=1e2+10;
const int MAX_INT=1e9+10;
const int INF=1e9+10;

vector <int> g[MAX_N],p,v,cans;
pair<pair<int,int>,int> e[4*MAX_M];
pair<int,int> t[MAX_M];
int N,M,m=0,S,T,a[MAX_N],dist[MAX_N];
queue <int> Q;
bool vis[MAX_N],graph1[MAX_N],graph2[MAX_N];

bool is_prime(int val){
	for(int i=2;i*i<=val;i++)
		if(val%i==0) return false;
	return true;
}

void get_prime(){
	for(int i=2;i*i<=MAX_INT;i++)
		if(is_prime(i)) p.push_back(i);
}

void graph_clear(){
	for(int i=0;i<MAX_N;i++) g[i].clear();
	for(int i=0;i<MAX_N;i++) graph1[i]=0;
	for(int i=0;i<MAX_N;i++) graph2[i]=0;
	m=0; S=N; T=N+1;
}

int get1(int val,int x){
	int ret=0;
	while(val%x==0){
		val/=x;
		ret++;
	}
	return ret;
}

int get2(int val1,int val2,int x){
	int ret=0;
	while(val1%x==0&&val2%x==0){
		val1/=x;
		val2/=x;
		ret++;
	}
	return ret;
}

void add_edge(int u,int v,int cost){
	g[u].push_back(m);
	e[m].first.first=u;
	e[m].first.second=v;
	e[m].second=cost;
	m++;
	g[v].push_back(m);
	e[m].first.first=v;
	e[m].first.second=u;
	e[m].second=0;
	m++;
}

bool bfs(){
	for(int i=0;i<MAX_N;i++) dist[i]=INF;
	while(Q.size()) Q.pop();
	dist[S]=0;
	Q.push(S);
	while(Q.size()){
		int x=Q.front();
		Q.pop();
		for(int i=0;i<g[x].size();i++){
		//	printf("%d\n",e[g[x][i]].first.second+1);
			int Mark=g[x][i];
			int to=e[Mark].first.second;
			int cost=e[Mark].second;
			if(dist[to]==INF&&cost!=0){
				dist[to]=dist[x]+1;
				Q.push(to);
			}
		}
	}
	if(dist[T]==INF) return false;
	return true;
}

int dfs(int x,int flow){
	if(x==T||flow==0) return flow;
	int ret=0;
	for(int i=0;i<g[x].size();i++){
		int Mark=g[x][i];
		int to=e[Mark].first.second;
		int cost=e[Mark].second;
		if(dist[to]!=dist[x]+1) continue;
		if(vis[to]) continue;
		if(cost==0) continue;
		vis[to]=1;
		int val=dfs(to,min(flow,cost));
		e[Mark].second-=val;
		e[Mark^1].second+=val;
		ret+=val;
		flow-=val;
		if(flow==0) return ret;
	}
	return ret;
}

int get_flow(){
	int ret=0;
	while(bfs()){
		for(int i=0;i<MAX_N;i++) vis[i]=0;
		ret+=dfs(S,INF);
	}
	return ret;
}

int main(){
	get_prime();
	scanf("%d%d",&N,&M);
	for(int i=0;i<N;i++) scanf("%d",&a[i]);
	for(int i=0;i<M;i++){
		int u,v;
		scanf("%d%d",&u,&v);
		u--; v--;
		if(u%2==0) swap(u,v);
		t[i].first=u; t[i].second=v;
	}
//	for(int i=0;i<M;i++) printf("%d %d\n",t[i].first,t[i].second);
	for(int i=0;i<p.size();i++){
		bool flag=false;
		int np=p[i];
		for(int j=0;j<M;j++){
			int u=t[j].first,v=t[j].second;
			if(a[u]%np==0&&a[v]%np==0) flag=true;
		}
		if(flag) cans.push_back(np);
	}
//	for(int i=0;i<cans.size();i++)
//		printf("%d ",cans[i]);
//	printf("\n");
	int ans=0;
	for(int i=0;i<cans.size();i++){
		graph_clear();
		int np=cans[i];
		for(int j=0;j<N;j++) if(j%2==1){
		//	printf("%d\n",get1(a[j],np));
			add_edge(S,j,get1(a[j],np));
		}
		for(int j=0;j<N;j++) if(j%2==0){
		//	printf("%d\n",get1(a[j],np));
			add_edge(j,T,get1(a[j],np));
		}
		for(int j=0;j<M;j++){
			int u=t[j].first,v=t[j].second;
			if(a[u]%np==0&&a[v]%np==0){
		//		printf("%d %d %d %d %d %d\n",u+1,v+1,a[u],a[v],np,get2(a[u],a[v],np));
				add_edge(u,v,get2(a[u],a[v],np));
			}
		}
		for(int j=0;j<g[S].size();j++){
			int Mark=g[S][j];
			int to=e[Mark].first.second;
			int cost=e[Mark].second;
	//		printf("%d %d %d\n",to+1,a[to],cost);
		}
	//	printf("%d\n",get_flow());
		ans+=get_flow();
	}
	printf("%d\n",ans);
	return 0;
}


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

const int MAX_N=1e2+10;
const int MAX_M=1e2+10;
const int MAX_INT=1e9+10;
const int INF=1e9+10;

vector <int> g[MAX_N],op,p,v,cans;
pair<pair<int,int>,int> e[4*MAX_M];
pair<int,int> t[MAX_M];
int N,M,m=0,S,T,a[MAX_N],dist[MAX_N];
queue <int> Q;
bool vis[MAX_N],graph1[MAX_N],graph2[MAX_N];
map <int,int> Map;

bool is_prime(int val){
	if(val==1||val==0) return false;
	for(int i=2;i*i<=val;i++)
		if(val%i==0) return false;
	return true;
}

void get_prime(){
	for(int i=2;i*i<=MAX_INT;i++)
		if(is_prime(i)) op.push_back(i);
	for(int i=0;i<N;i++){
		int val=a[i];
		if(is_prime(val)&&Map.find(val)==Map.end()){
			Map[val]=1;
			p.push_back(val);
		}
		for(int j=0;j<op.size();j++){
			if(val%op[j]==0){
				if(Map.find(op[j])==Map.end()){
					Map[op[j]]=1;
					p.push_back(op[j]);
				}
				val/=op[j];
			}
		}
		if(is_prime(val)&&Map.find(val)==Map.end()){
			Map[val]=1;
			p.push_back(val);
		}
	}
}

void graph_clear(){
	for(int i=0;i<MAX_N;i++) g[i].clear();
	for(int i=0;i<MAX_N;i++) graph1[i]=0;
	for(int i=0;i<MAX_N;i++) graph2[i]=0;
	m=0; S=N; T=N+1;
}

int get1(int val,int x){
	int ret=0;
	while(val%x==0){
		val/=x;
		ret++;
	}
	return ret;
}

int get2(int val1,int val2,int x){
	int ret=0;
	while(val1%x==0&&val2%x==0){
		val1/=x;
		val2/=x;
		ret++;
	}
	return ret;
}

void add_edge(int u,int v,int cost){
	g[u].push_back(m);
	e[m].first.first=u;
	e[m].first.second=v;
	e[m].second=cost;
	m++;
	g[v].push_back(m);
	e[m].first.first=v;
	e[m].first.second=u;
	e[m].second=0;
	m++;
}

bool bfs(){
	for(int i=0;i<MAX_N;i++) dist[i]=INF;
	while(Q.size()) Q.pop();
	dist[S]=0;
	Q.push(S);
	while(Q.size()){
		int x=Q.front();
		Q.pop();
		for(int i=0;i<g[x].size();i++){
		//	printf("%d\n",e[g[x][i]].first.second+1);
			int Mark=g[x][i];
			int to=e[Mark].first.second;
			int cost=e[Mark].second;
			if(dist[to]==INF&&cost!=0){
				dist[to]=dist[x]+1;
				Q.push(to);
			}
		}
	}
	if(dist[T]==INF) return false;
	return true;
}

int dfs(int x,int flow){
	if(x==T||flow==0) return flow;
	int ret=0;
	for(int i=0;i<g[x].size();i++){
		int Mark=g[x][i];
		int to=e[Mark].first.second;
		int cost=e[Mark].second;
		if(dist[to]!=dist[x]+1) continue;
		if(vis[to]) continue;
		if(cost==0) continue;
		vis[to]=1;
		int val=dfs(to,min(flow,cost));
		e[Mark].second-=val;
		e[Mark^1].second+=val;
		ret+=val;
		flow-=val;
		if(flow==0) return ret;
	}
	return ret;
}

int get_flow(){
	int ret=0;
	while(bfs()){
		for(int i=0;i<MAX_N;i++) vis[i]=0;
		ret+=dfs(S,INF);
	}
	return ret;
}

int main(){
	scanf("%d%d",&N,&M);
	for(int i=0;i<N;i++) scanf("%d",&a[i]);
	get_prime();
//	for(int i=0;i<p.size();i++)
//		printf("%d ",p[i]);
//	printf("\n");
	for(int i=0;i<M;i++){
		int u,v;
		scanf("%d%d",&u,&v);
		u--; v--;
		if(u%2==0) swap(u,v);
		t[i].first=u; t[i].second=v;
	}
//	for(int i=0;i<M;i++) printf("%d %d\n",t[i].first,t[i].second);
	for(int i=0;i<p.size();i++){
		bool flag=false;
		int np=p[i];
		for(int j=0;j<M;j++){
			int u=t[j].first,v=t[j].second;
			if(a[u]%np==0&&a[v]%np==0) flag=true;
		}
		if(flag) cans.push_back(np);
	}
//	for(int i=0;i<cans.size();i++)
//		printf("%d ",cans[i]);
//	printf("\n");
	int ans=0;
	for(int i=0;i<cans.size();i++){
		graph_clear();
		int np=cans[i];
		for(int j=0;j<N;j++) if(j%2==1){
		//	printf("%d\n",get1(a[j],np));
			add_edge(S,j,get1(a[j],np));
		}
		for(int j=0;j<N;j++) if(j%2==0){
		//	printf("%d\n",get1(a[j],np));
			add_edge(j,T,get1(a[j],np));
		}
		for(int j=0;j<M;j++){
			int u=t[j].first,v=t[j].second;
			if(a[u]%np==0&&a[v]%np==0){
		//		printf("%d %d %d %d %d %d\n",u+1,v+1,a[u],a[v],np,get2(a[u],a[v],np));
				add_edge(u,v,get2(a[u],a[v],np));
			}
		}
		for(int j=0;j<g[S].size();j++){
			int Mark=g[S][j];
			int to=e[Mark].first.second;
			int cost=e[Mark].second;
	//		printf("%d %d %d\n",to+1,a[to],cost);
		}
	//	printf("%d\n",get_flow());
		ans+=get_flow();
	}
	printf("%d\n",ans);
	return 0;
}


//  Copyright © 2018 Diego Garcia Rodriguez del Campo. All rights reserved.
#include<bits/stdc++.h>
#define MAX 505
#define pii pair < i64 , i64 >
#define fi first
#define se second
#define optimiza_io cin.tie(0); ios_base::sync_with_stdio(0);
using namespace std;
typedef long long i64;

i64 N, M, idx, ans, col;
vector < pii > dv[MAX];
vector < i64 > ady[MAX*35];
i64 vis[MAX*35];
i64 match[MAX*35];

bool dfs( i64 x )
{
    if( vis[x] == col )
        return false;
    vis[x] = col;
    for( auto v : ady[x] )
    {
        if( ! match[v] or dfs( match[v] ) )
        {
            match[v] = x;
            return true;
        }
    }
    return false;
}

int main()
{
    optimiza_io
    cin >> N >> M;
    for( i64 i = 1; i <= N; i ++ )
    {
        i64 aux;
        cin >> aux;
        for( i64 j = 2; j <= sqrt( aux ); j ++ )
            while( aux % j == 0 )
            {
                dv[i].push_back( { j , ++idx } );
                aux /= j;
            }

        if( aux > 1 )
            dv[i].push_back( { aux , ++idx } );
    }

    while( M -- )
    {
        i64 a, b;
        cin >> a >> b;
        if( a % 2 != 0 )
            swap( a , b );

        for( int i = 0; i < dv[a].size(); i ++ )
            for( int j = 0; j < dv[b].size(); j ++ )
                if( dv[a][i].fi == dv[b][i].fi )
                    ady[dv[a][i].se].push_back( dv[b][j].se );

        /* i64 id1 = 0, id2 = 0;
         while( id1 < dv[a].size() && id2 < dv[b].size() )
         {
         if( dv[a][id1].fi > dv[b][id2].fi )
         id2++;
         else if( dv[a][id1].fi < dv[b][id2].fi )
         id1++;
         else
         {
         ady[dv[a][id1].se].push_back( dv[b][id2].se );
         id1++;
         id2++;
         }
         }
         */
    }

    for( i64 i = 1; i <= idx; i ++ )
    {
        col++;
        if( dfs( i ) )
            ans++;
    }
    cout << ans;
    return 0;
}


//  Copyright © 2018 Diego Garcia Rodriguez del Campo. All rights reserved.
#include<bits/stdc++.h>
#define MAX 505
#define pii pair < int , int >
#define fi first
#define se second
#define optimiza_io cin.tie(0); ios_base::sync_with_stdio(0);
using namespace std;
typedef long long i64;

int N, M, idx, ans, col;
vector < pii > dv[MAX];
vector < int > ady[MAX*35];
int vis[MAX*35];
int match[MAX*35];

bool dfs( int x )
{
    if( vis[x] == col )
        return false;
    vis[x] = col;
    for( auto v : ady[x] )
    {
        if( ! match[v] or dfs( match[v] ) )
        {
            match[v] = x;
            return true;
        }
    }
    return false;
}

int main()
{
    optimiza_io
    cin >> N >> M;
    for( int i = 1; i <= N; i ++ )
    {
        int aux;
        cin >> aux;
        for( int j = 2; j <= ( int ) sqrt( aux ); j ++ )
            while( aux % j == 0 )
            {
                dv[i].push_back( { j , ++idx } );
                aux /= j;
            }

        if( aux > 1 )
            dv[i].push_back( { aux , ++idx } );
    }

    while( M -- )
    {
        int a, b;
        cin >> a >> b;
        if( a % 2 != 0 )
            swap( a , b );

        for( int i = 0; i < ( int ) dv[a].size(); i ++ )
            for( int j = 0; j < ( int ) dv[b].size(); j ++ )
                if( dv[a][i].fi == dv[b][j].fi )
                    ady[dv[a][i].se].push_back( dv[b][j].se );
    }

    for( int i = 1; i <= idx; i ++ )
    {
        col++;
        if( dfs( i ) )
            ans++;
    }
    cout << ans;
    return 0;
}


//  Copyright © 2018 Diego Garcia Rodriguez del Campo. All rights reserved.
#include<bits/stdc++.h>
#define MAX 105
#define pii pair < i64 , i64 >
#define fi first
#define se second
#define optimiza_io cin.tie(0); ios_base::sync_with_stdio(0);
using namespace std;
typedef long long i64;

i64 N, M, idx, ans, col;
vector < pii > dv[MAX];
vector < i64 > ady[MAX*35];
i64 vis[MAX*35];
i64 match[MAX*35];

bool dfs( i64 x )
{
    if( vis[x] == col )
        return false;
    vis[x] = col;
    for( auto v : ady[x] )
    {
        if( ! match[v] or dfs( match[v] ) )
        {
            match[v] = x;
            return true;
        }
    }
    return false;
}

int main()
{
    optimiza_io
    cin >> N >> M;
    for( i64 i = 1; i <= N; i ++ )
    {
        i64 aux;
        cin >> aux;
        for( i64 j = 2; j <= sqrt( aux ); j ++ )
            while( aux % j == 0 )
            {
                dv[i].push_back( { j , ++idx } );
                aux /= j;
            }

        if( aux > 1 )
            dv[i].push_back( { aux , ++idx } );
    }

    while( M -- )
    {
        i64 a, b;
        cin >> a >> b;
        if( a % 2 != 0 )
            swap( a , b );

        for( int i = 0; i < dv[a].size(); i ++ )
            for( int j = 0; j < dv[b].size(); j ++ )
                if( dv[a][i].fi == dv[b][i].fi )
                    ady[dv[a][i].se].push_back( dv[b][j].se );

        /* i64 id1 = 0, id2 = 0;
        while( id1 < dv[a].size() && id2 < dv[b].size() )
        {
            if( dv[a][id1].fi > dv[b][id2].fi )
                id2++;
            else if( dv[a][id1].fi < dv[b][id2].fi )
                id1++;
            else
            {
                ady[dv[a][id1].se].push_back( dv[b][id2].se );
                id1++;
                id2++;
            }
        }
        */
    }

    for( i64 i = 1; i <= idx; i ++ )
    {
        col++;
        if( dfs( i ) )
            ans++;
    }
    cout << ans;
    return 0;
}


//  Copyright © 2018 Diego Garcia Rodriguez del Campo. All rights reserved.
#include<bits/stdc++.h>
#define MAX 505
#define pii pair < i64 , i64 >
#define fi first
#define se second
#define optimiza_io cin.tie(0); ios_base::sync_with_stdio(0);
using namespace std;
typedef long long i64;

i64 N, M, idx, ans, col;
vector < pii > dv[MAX];
vector < i64 > ady[MAX*35];
i64 vis[MAX*35];
i64 match[MAX*35];

bool dfs( i64 x )
{
    if( vis[x] == col )
        return false;
    vis[x] = col;
    for( auto v : ady[x] )
    {
        if( ! match[v] or dfs( match[v] ) )
        {
            match[v] = x;
            return true;
        }
    }
    return false;
}

int main()
{
    optimiza_io
    cin >> N >> M;
    for( i64 i = 1; i <= N; i ++ )
    {
        i64 aux;
        cin >> aux;
        for( i64 j = 2; j <= ( int ) sqrt( aux ); j ++ )
            while( aux % j == 0 )
            {
                dv[i].push_back( { j , ++idx } );
                aux /= j;
            }

        if( aux > 1 )
            dv[i].push_back( { aux , ++idx } );
    }

    while( M -- )
    {
        i64 a, b;
        cin >> a >> b;
        if( a % 2 != 0 )
            swap( a , b );

        for( int i = 0; i < ( int ) dv[a].size(); i ++ )
            for( int j = 0; j < ( int ) dv[b].size(); j ++ )
                if( dv[a][i].fi == dv[b][i].fi )
                    ady[dv[a][i].se].push_back( dv[b][j].se );

        /* i64 id1 = 0, id2 = 0;
         while( id1 < dv[a].size() && id2 < dv[b].size() )
         {
         if( dv[a][id1].fi > dv[b][id2].fi )
         id2++;
         else if( dv[a][id1].fi < dv[b][id2].fi )
         id1++;
         else
         {
         ady[dv[a][id1].se].push_back( dv[b][id2].se );
         id1++;
         id2++;
         }
         }
         */
    }

    for( i64 i = 1; i <= idx; i ++ )
    {
        col++;
        if( dfs( i ) )
            ans++;
    }
    cout << ans;
    return 0;
}


/***************
		Jennifer Wilson
****************/
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define vi vector <int>
#define IOS  ios::sync_with_stdio(0); cin.tie(0);
#define mp make_pair
#define pb push_back
#define f(i,a,b) for(int i = a; i <= b; i++)
#define r(i,a,b) for(int i = b; i >= a ; i--)
#define fi first
#define se second
#define int ll
vi adj[10000],cnt(10000,0);
int n , m, a[10000], ans = 0;
vector <bool> vs(10000,0),prime(10000,0);
int ucnn(int x, int y) {
	int m = __gcd(x,y);
	f(i,2,sqrt(m) + 1) {
		if(m % i == 0) return i;
	}
	return m;
}
void dfs(int u, int p) {
	vs[u] = 1;
	f(i,0,adj[u].size() - 1) {
        int x = adj[u][i];
        if(!vs[x]) {
        	int m = __gcd(a[u],a[x]);
        	a[u] /= m;
        	a[x] /= m;
        	ans += cnt[m];
		}
	}
	//cout << u;
	f(i,0,adj[u].size() - 1) {
		if(!vs[adj[u][i]]) dfs(adj[u][i],u);
	}

}
signed main() {
    IOS;
    int n,m;
    cin >> n >> m;
    f(i,1,n) {
    	//int a[i];
    	cin >> a[i];
	}
	//cout << __gcd(a[1] , a[2])
    f(i,1,m) {
    	int x,y;
    	cin >> x >> y;
    	adj[x].pb(y);
    	adj[y].pb(x);
	}
	f(i,2,10000) {
		if(!prime[i]) {
			cnt[i]++;
			f(j , 2, 10000/i) {
				prime[j*i] = 1;
				cnt[j*i] = cnt[j] + 1;
			}
		//	cnt[i]++;
		}
	}
//	cout << cnt[8];
	dfs(1,-1);
	cout << ans;
 }


/***************
		Jennifer Wilson
****************/
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define vi vector <int>
#define IOS  ios::sync_with_stdio(0); cin.tie(0);
#define mp make_pair
#define pb push_back
#define f(i,a,b) for(int i = a; i <= b; i++)
#define r(i,a,b) for(int i = b; i >= a ; i--)
#define fi first
#define se second
#define int ll
vi adj[10000];
int n , m, a[10000], ans = 0;
vector <bool> vs(10000,0);
int countt(int m) {
	if(m == 2) return 1;
	f(i,2,sqrt(m) + 1) {
		if(m % i == 0) {
			return countt(m / i ) + 1;
		}
	}

	return 0;
}
void dfs(int u, int p) {
	vs[u] = 1;
	f(i,0,adj[u].size() - 1) {
        int x = adj[u][i];
        if(!vs[x]) {
        	int m = __gcd(a[u],a[x]);
        	a[u] /= m;
        	a[x] /= m;
        	ans += countt(m);
        //	cout << m << " this " << countt(m) ;
		}
	}
	//cout << u;
	f(i,0,adj[u].size() - 1) {
		if(!vs[adj[u][i]]) dfs(adj[u][i],u);
	}

}
signed main() {
    IOS;
    int n,m;
    cin >> n >> m;
    f(i,1,n) {
    	cin >> a[i];
	}
	//cout << __gcd(a[1] , a[2])
    f(i,1,m) {
    	int x,y;
    	cin >> x >> y;
    	adj[x].pb(y);
    	adj[y].pb(x);
	}

//	cout << countt(4) << endl;
	dfs(1,-1);
	cout << ans;
 }


#include<bits/stdc++.h>
using namespace std;
const int maxn=5000;
vector<int>g[maxn];
//#define for(int u : vector <int> a)  for(int i = 0;i < a.size(); i++) int u = a[i];
vector<pair<int,int> >a[maxn];
int mt[maxn];bool used[maxn];
bool kuhn(int v){
    used[v]=1;
    for(int u : g[v]){
	    if(mt[u]==-1||(!used[mt[u]]&&kuhn(mt[u]))){
		    mt[u]=v;return 1;}
	}
	return 0;
}
int main(){
    int n,m;
	cin>>n>>m;
	int k=0;
	for(int i=0;i<n;i++){
	    int t;cin>>t;
		for(int j=2;j*j<=t;j++) {
		   while(t%j==0) a[i].push_back({j,k++}),t/=j;
		}
		if(t>1) a[i].push_back({t,k++});
	}
	while(m--) {
	    int u,v;
		cin>>u>>v;
		u--,v--;
		if(u%2!=0) swap(u,v);
		for(auto x : a[u])for(auto y : a[v])if(x.first==y.first)g[x.second].push_back(y.second);}
	int ans=0;
	memset(mt,-1,sizeof(mt));
	for(int i=0;i<k;i++){
	     memset(used,0,sizeof(used));
		 ans += kuhn(i);
	}
	cout<<ans;return 0;}


/***************
		Jennifer Wilson
****************/
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define vi vector <int>
#define IOS  ios::sync_with_stdio(0); cin.tie(0);
#define mp make_pair
#define pb push_back
#define f(i,a,b) for(int i = a; i <= b; i++)
#define r(i,a,b) for(int i = b; i >= a ; i--)
#define fi first
#define se second
#define int ll
vi adj[10000];
int n , m, a[10000], ans = 0;
vector <bool> vs(10000,0);
vector <bool> mark(10000,0);
int countt(int m) {
	if(m == 2) return 1;
	f(i,2,sqrt(m) + 1) {
		if(m % i == 0) {
			return countt(m / i ) + 1;
		}
	}

	return 0;
}
void dfs(int u, int p) {
	vs[u] = 1;
	f(i,0,adj[u].size() - 1) {
        int x = adj[u][i];
        if(!vs[x]) {
        	int m = __gcd(a[u],a[x]);
        	a[u] /= m;
        	a[x] /= m;
        	ans += countt(m);
        //	cout << m << " this " << countt(m) ;
		}
	}
	//cout << u;
	f(i,0,adj[u].size() - 1) {
		if(!vs[adj[u][i]]) dfs(adj[u][i],u);
	}

}
signed main() {
    IOS;
    int n,m;
    cin >> n >> m;
    f(i,1,n) {
    	cin >> a[i];
	}
	//cout << __gcd(a[1] , a[2])
    f(i,1,m) {
    	int x,y;
    	cin >> x >> y;
    	adj[x].pb(y);
    	adj[y].pb(x);
    	mark[x] = 1;
	}

//	cout << countt(4) << endl;
	f(i,1,n) {
		if(mark[i] && !vs[i]) dfs(i,-1);
	}
	cout << ans;
 }


#include <iostream>
#include <stdio.h>
#include <string>
#include <cassert>
#include <queue>
#include <cstring>
#include <algorithm>
#include <cstdlib>
#include <set>
#include <stack>
#include <map>
#include <list>
#include <memory.h>
#include <bitset>

using namespace std;

int n, m, a[100];
pair<int, int> p[100];
vector<vector<int>> g;
vector<vector<pair<int, int>>> elements;
vector<bool> vis;
vector<int> match;

void read_input()
{
	cin >> n >> m;
	for (int i = 0; i < n; i++)
		cin >> a[i];
	for (int i = 0; i < m; i++)
	{
		cin >> p[i].first >> p[i].second;
		--p[i].first, --p[i].second;
	}
}

vector<int> fact(int x)
{
	vector<int> ans;
	for (int i = 2; i * i <= x; i++)
		while (x % i == 0)
		{
			ans.push_back(i);
			x /= i;
		}
	if (x != 1)
		ans.push_back(x);
	return ans;
}

void make_graph()
{
	elements = vector<vector<pair<int, int>>>(n);
	int num = 0;
	for (int i = 0; i < n; i++)
	{
		vector<int> f = fact(a[i]);
		for (auto it = f.begin(); it != f.end(); it++)
		{
			elements[i].push_back(make_pair(*it, num++));
			g.push_back(vector<int>());
		}
	}
	for (int i = 0; i < m; i++)
	{
		int fst = p[i].first;
		int scd = p[i].second;
		for (auto it1 = elements[fst].begin(); it1 != elements[fst].end(); it1++)
			for (auto it2 = elements[scd].begin(); it2 != elements[scd].end(); it2++)
				if (it1->first == it2->first)
				{
					g[it1->second].push_back(it2->second);
					g[it2->second].push_back(it1->second);
				}
	}
}

bool try_kuhn(int v)
{
	if (vis[v])
		return false;
	vis[v] = true;
	for (auto it = g[v].begin(); it != g[v].end(); it++)
		if (match[*it] == -1 || try_kuhn(match[*it]))
		{
			if (match[v] != -1)
				match[match[v]] = -1;
			match[v] = *it;
			match[*it] = v;
			return true;
		}
	return false;
}

void solve()
{
	read_input();
	make_graph();

	n = g.size();

	match.assign(n, -1);

	for (int go = true; go; )
	{
		go = false;
		vis.assign(n, false);
		for (int i = 0; i < n; i++)
			if (match[i] == -1 && try_kuhn(i))
				go = true;
	}

	vis.assign(n, false);
	int ans = 0;

	for (int i = 0; i < n; i++)
	{
		if (!vis[i] && match[i] != -1)
		{
			vis[match[i]] = true;
			ans++;
		}
	}

	cout << ans;
}

int main()
{
#ifdef _HOME
	freopen("input.txt", "rt", stdin);
	freopen("output.txt", "wt", stdout);
#endif

	solve();

	return 0;
}


#include <iostream>
#include <stdio.h>
#include <string>
#include <cassert>
#include <queue>
#include <cstring>
#include <algorithm>
#include <cstdlib>
#include <set>
#include <stack>
#include <map>
#include <list>
#include <memory.h>
#include <bitset>

using namespace std;

int n, m, a[100];
pair<int, int> p[100];
vector<vector<int>> g;
vector<vector<pair<int, int>>> elements;
vector<bool> vis;
vector<int> match;

void read_input()
{
	cin >> n >> m;
	for (int i = 0; i < n; i++)
		cin >> a[i];
	for (int i = 0; i < m; i++)
	{
		cin >> p[i].first >> p[i].second;
		--p[i].first, --p[i].second;
	}
}

vector<int> fact(int x)
{
	vector<int> ans;
	for (int i = 2; i * i <= x; i++)
		while (x % i == 0)
		{
			ans.push_back(i);
			x /= i;
		}
	if (x != 1)
		ans.push_back(x);
	return ans;
}

void make_graph()
{
	elements = vector<vector<pair<int, int>>>(n);
	int num = 0;
	for (int i = 0; i < n; i++)
	{
		vector<int> f = fact(a[i]);
		for (auto it = f.begin(); it != f.end(); it++)
		{
			elements[i].push_back(make_pair(*it, num++));
			g.push_back(vector<int>());
		}
	}
	for (int i = 0; i < m; i++)
	{
		int fst = p[i].first;
		int scd = p[i].second;
		for (auto it1 = elements[fst].begin(); it1 != elements[fst].end(); it1++)
			for (auto it2 = elements[scd].begin(); it2 != elements[scd].end(); it2++)
				if (it1->first == it2->first)
				{
					g[it1->second].push_back(it2->second);
					g[it2->second].push_back(it1->second);
				}
	}
}

bool try_kuhn(int v)
{
	if (vis[v])
		return false;
	vis[v] = true;
	for (auto it = g[v].begin(); it != g[v].end(); it++)
		if (match[*it] == -1 || try_kuhn(match[*it]))
		{
			match[*it] = v;
			return true;
		}
	return false;
}

void solve()
{
	read_input();
	make_graph();

	n = g.size();

	match.assign(n, -1);
	vis.assign(n, false);

	for (int i = 0; i < n; i++)
	{
		if (try_kuhn(i))
			vis.assign(n, false);
	}

	vis.assign(n, false);
	int ans = 0;

	for (int i = 0; i < n; i++)
	{
		if (!vis[i] && match[i] != -1)
		{
			vis[match[i]] = true;
			ans++;
		}
	}

	cout << ans;
}

int main()
{
#ifdef _HOME
	freopen("input.txt", "rt", stdin);
	freopen("output.txt", "wt", stdout);
#endif

	solve();

	return 0;
}


#include <iostream>
#include <stdio.h>
#include <string>
#include <cassert>
#include <queue>
#include <cstring>
#include <algorithm>
#include <cstdlib>
#include <set>
#include <stack>
#include <map>
#include <list>
#include <memory.h>
#include <bitset>

using namespace std;

int n, m, a[100];
pair<int, int> p[100];
vector<vector<int>> g;
vector<vector<pair<int, int>>> elements;
vector<bool> vis;
vector<int> match;

void read_input()
{
	cin >> n >> m;
	for (int i = 0; i < n; i++)
		cin >> a[i];
	for (int i = 0; i < m; i++)
	{
		cin >> p[i].first >> p[i].second;
		--p[i].first, --p[i].second;
	}
}

vector<int> fact(int x)
{
	vector<int> ans;
	for (int i = 2; i * i <= x; i++)
		while (x % i == 0)
		{
			ans.push_back(i);
			x /= i;
		}
	if (x != 1)
		ans.push_back(x);
	return ans;
}

void make_graph()
{
	elements = vector<vector<pair<int, int>>>(n);
	int num = 0;
	for (int i = 0; i < n; i++)
	{
		vector<int> f = fact(a[i]);
		for (auto it = f.begin(); it != f.end(); it++)
		{
			elements[i].push_back(make_pair(*it, num++));
			g.push_back(vector<int>());
		}
	}
	for (int i = 0; i < m; i++)
	{
		int fst = p[i].first;
		int scd = p[i].second;
		for (auto it1 = elements[fst].begin(); it1 != elements[fst].end(); it1++)
			for (auto it2 = elements[scd].begin(); it2 != elements[scd].end(); it2++)
				if (it1->first == it2->first)
				{
					g[it1->second].push_back(it2->second);
					g[it2->second].push_back(it1->second);
				}
	}
}

bool try_kuhn(int v)
{
	if (vis[v])
		return false;
	vis[v] = true;
	for (auto it = g[v].begin(); it != g[v].end(); it++)
		if (match[*it] == -1 || try_kuhn(match[*it]))
		{
			if (match[v] != -1)
				match[match[v]] = -1;
			match[v] = *it;
			match[*it] = v;
			return true;
		}
	return false;
}

void solve()
{
	read_input();
	make_graph();

	n = g.size();

	match.assign(n, -1);

	for (bool go = true; go; )
	{
		go = false;
		vis.assign(n, false);
		for (int i = 0; i < n; i++)
			if (match[i] == -1 && try_kuhn(i))
				go = true;
	}

	vis.assign(n, false);
	int ans = 0;

	for (int i = 0; i < n; i++)
	{
		if (!vis[i] && match[i] != -1)
		{
			vis[match[i]] = true;
			ans++;
		}
	}

	cout << ans;
}

int main()
{
#ifdef _HOME
	freopen("input.txt", "rt", stdin);
	freopen("output.txt", "wt", stdout);
#endif

	solve();

	return 0;
}


#include <iostream>
#include <stdio.h>
#include <string>
#include <cassert>
#include <queue>
#include <cstring>
#include <algorithm>
#include <cstdlib>
#include <set>
#include <stack>
#include <map>
#include <list>
#include <memory.h>
#include <bitset>

using namespace std;

int n, m, a[100];
pair<int, int> p[100];
vector<vector<int>> g;
vector<vector<pair<int, int>>> elements;
vector<bool> vis;
vector<int> match;

void read_input()
{
	cin >> n >> m;
	for (int i = 0; i < n; i++)
		cin >> a[i];
	for (int i = 0; i < m; i++)
	{
		cin >> p[i].first >> p[i].second;
		--p[i].first, --p[i].second;
	}
}

vector<int> fact(int x)
{
	vector<int> ans;
	for (int i = 2; i * i <= x; i++)
		while (x % i == 0)
		{
			ans.push_back(i);
			x /= i;
		}
	if (x != 1)
		ans.push_back(x);
	return ans;
}

void make_graph()
{
	elements = vector<vector<pair<int, int>>>(n);
	int num = 0;
	for (int i = 0; i < n; i++)
	{
		vector<int> f = fact(a[i]);
		for (auto it = f.begin(); it != f.end(); it++)
		{
			elements[i].push_back(make_pair(*it, num++));
			g.push_back(vector<int>());
		}
	}
	for (int i = 0; i < m; i++)
	{
		int fst = p[i].first;
		int scd = p[i].second;
		for (auto it1 = elements[fst].begin(); it1 != elements[fst].end(); it1++)
			for (auto it2 = elements[scd].begin(); it2 != elements[scd].end(); it2++)
				if (it1->first == it2->first)
				{
					g[it1->second].push_back(it2->second);
					g[it2->second].push_back(it1->second);
				}
	}
}

bool try_kuhn(int v)
{
	if (vis[v])
		return false;
	vis[v] = true;
	for (auto it = g[v].begin(); it != g[v].end(); it++)
		if (match[*it] == -1 || try_kuhn(match[*it]))
		{
			if (match[v] != -1)
				match[match[v]] = -1;
			match[v] = *it;
			match[*it] = v;
			return true;
		}
	return false;
}

void solve()
{
	read_input();
	make_graph();

	n = g.size();

	match.assign(n, -1);
	vis.assign(n, false);

	for (int i = 0; i < n; i++)
	{
		if (match[i] == -1 && try_kuhn(i))
			vis.assign(n, false);
	}

	vis.assign(n, false);
	int ans = 0;

	for (int i = 0; i < n; i++)
	{
		if (!vis[i] && match[i] != -1)
		{
			vis[match[i]] = true;
			ans++;
		}
	}

	cout << ans;
}

int main()
{
#ifdef _HOME
	freopen("input.txt", "rt", stdin);
	freopen("output.txt", "wt", stdout);
#endif

	solve();

	return 0;
}


#include <iostream>
#include <stdio.h>
#include <string>
#include <cassert>
#include <queue>
#include <cstring>
#include <algorithm>
#include <cstdlib>
#include <set>
#include <stack>
#include <map>
#include <list>
#include <memory.h>
#include <bitset>

using namespace std;

int n, m, a[100];
pair<int, int> p[100];
vector<vector<int>> g;
vector<vector<pair<int, int>>> elements;
vector<bool> vis;
vector<int> match;

void read_input()
{
	cin >> n >> m;
	for (int i = 0; i < n; i++)
		cin >> a[i];
	for (int i = 0; i < m; i++)
	{
		cin >> p[i].first >> p[i].second;
		--p[i].first, --p[i].second;
	}
}

vector<int> fact(int x)
{
	vector<int> ans;
	for (int i = 2; i <= x; i++)
		while (x % i == 0)
		{
			ans.push_back(i);
			x /= i;
		}
	if (x != 1)
		ans.push_back(x);
	return ans;
}

void make_graph()
{
	elements = vector<vector<pair<int, int>>>(n);
	int num = 0;
	for (int i = 0; i < n; i++)
	{
		vector<int> f = fact(a[i]);
		for (auto it = f.begin(); it != f.end(); it++)
		{
			elements[i].push_back(make_pair(*it, num++));
			g.push_back(vector<int>());
		}
	}
	for (int i = 0; i < m; i++)
	{
		int fst = p[i].first;
		int scd = p[i].second;
		for (auto it1 = elements[fst].begin(); it1 != elements[fst].end(); it1++)
			for (auto it2 = elements[scd].begin(); it2 != elements[scd].end(); it2++)
				if (it1->first == it2->first)
				{
					g[it1->second].push_back(it2->second);
					g[it2->second].push_back(it1->second);
				}
	}
}

bool try_kuhn(int v)
{
	if (vis[v])
		return false;
	vis[v] = true;
	for (auto it = g[v].begin(); it != g[v].end(); it++)
		if (match[*it] == -1 || try_kuhn(match[*it]))
		{
			if (match[v] != -1)
				match[match[v]] = -1;
			match[v] = *it;
			match[*it] = v;
			return true;
		}
	return false;
}

void solve()
{
	read_input();
	make_graph();

	n = g.size();

	match.assign(n, -1);
	vis.assign(n, false);

	for (int i = 0; i < n; i++)
	{
		if (match[i] == -1 && try_kuhn(i))
			vis.assign(n, false);
	}

	vis.assign(n, false);
	int ans = 0;

	for (int i = 0; i < n; i++)
	{
		if (!vis[i] && match[i] != -1)
		{
			vis[match[i]] = true;
			ans++;
		}
	}

	cout << ans;
}

int main()
{
#ifdef _HOME
	freopen("input.txt", "rt", stdin);
	freopen("output.txt", "wt", stdout);
#endif

	solve();

	return 0;
}


#include <iostream>
#include <stdio.h>
#include <string>
#include <cassert>
#include <queue>
#include <cstring>
#include <algorithm>
#include <cstdlib>
#include <set>
#include <stack>
#include <map>
#include <list>
#include <memory.h>
#include <bitset>

using namespace std;

int n, m, a[100];
pair<int, int> p[100];
vector<vector<int>> g;
vector<vector<pair<int, int>>> elements;
vector<bool> vis;
vector<int> match;

void read_input()
{
	cin >> n >> m;
	for (int i = 0; i < n; i++)
		cin >> a[i];
	for (int i = 0; i < m; i++)
	{
		cin >> p[i].first >> p[i].second;
		--p[i].first, --p[i].second;
	}
}

vector<int> fact(int x)
{
	vector<int> ans;
	for (int i = 2; i * i <= x; i++)
		while (x % i == 0)
		{
			ans.push_back(i);
			x /= i;
		}
	if (x != 1)
		ans.push_back(x);
	return ans;
}

void make_graph()
{
	elements = vector<vector<pair<int, int>>>(n);
	int num = 0;
	for (int i = 0; i < n; i++)
	{
		vector<int> f = fact(a[i]);
		for (auto it = f.begin(); it != f.end(); it++)
		{
			elements[i].push_back(make_pair(*it, num++));
			g.push_back(vector<int>());
		}
	}
	for (int i = 0; i < m; i++)
	{
		int fst = p[i].first;
		int scd = p[i].second;
		for (auto it1 = elements[fst].begin(); it1 != elements[fst].end(); it1++)
			for (auto it2 = elements[scd].begin(); it2 != elements[scd].end(); it2++)
				if (it1->first == it2->first)
				{
					g[it1->second].push_back(it2->second);
					g[it2->second].push_back(it1->second);
				}
	}
}

bool try_kuhn(int v)
{
	if (vis[v])
		return false;
	vis[v] = true;
	for (auto it = g[v].begin(); it != g[v].end(); it++)
		if (match[*it] == -1 || try_kuhn(match[*it]))
		{
			if (match[v] != -1)
				match[match[v]] = -1;
			match[v] = *it;
			match[*it] = v;
			return true;
		}
	return false;
}

void solve()
{
	read_input();
	make_graph();

	n = g.size();

	match.assign(n, -1);
	vis.assign(n, false);

	for (int i = 0; i < n; i++)
	{
		if (try_kuhn(i))
			vis.assign(n, false);
	}

	vis.assign(n, false);
	int ans = 0;

	for (int i = 0; i < n; i++)
	{
		if (!vis[i] && match[i] != -1)
		{
			vis[match[i]] = true;
			ans++;
		}
	}

	cout << ans;
}

int main()
{
#ifdef _HOME
	freopen("input.txt", "rt", stdin);
	freopen("output.txt", "wt", stdout);
#endif

	solve();

	return 0;
}


using namespace std;
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <limits.h>
#include <vector>
#include <map>
#include <bitset>
#include <string>
#include <iterator>
#include <set>
#include <utility>
#include <queue>
#include <numeric>
#include <functional>
#include <ctype.h>
#include <stack>
#include <algorithm>
#include <cstdlib>
#define S(x) scanf("%d",&x)
#define S2(x,y) scanf("%d%d",&x,&y)
#define wl(n) while(n--)
#define ll long long
#define bitcnt(x) __builtin_popcount(x)
#define P(x) printf("%d\n",x)
#define PB push_back
#define MP make_pair
#define fl(i,n) for(i=0;i<n;i++)
#define fil(i,a,n) for(i=a;i<n;i++)
#define rev(i,a,n) for(i=n-1;i>=a;i--)
#define mem(a,i) memset(a,i,sizeof(a))
#define F first
#define S1 second
typedef pair<int,int> P;
vector<int> v2,v4;
std::vector<P> v3;
pair<int,int> p1;
#define MOD 1000000007
#define debug(x)  printf("####%d####\n",x);
#define nl printf("\n");
#define str string
int a[1234567];
string s;
int dp[1001];
ll pow1(ll x,ll y)
{
    if(y==0)
    return 1;
    ll temp= pow1(x,y/2)%MOD;
    if(y%2==0)
    return (temp*temp)%MOD;
    else
    return (((temp*temp)%MOD)*x)%MOD;
}

const int EDGES = 402;
const int VERTICES = 105;
const long long INF = (long long)1e14;

int vertex[EDGES], nxt[EDGES], cnt, ptr[VERTICES], level[VERTICES], bfsTree[VERTICES], temp[VERTICES];
long long capacity[EDGES], flow[EDGES];

void reset ()
{
    cnt = 0;
    memset (ptr, -1, sizeof (ptr));
    memset (nxt, -1, sizeof (nxt));
}

void AddEdge (int u, int v, long long cap)
{
    vertex[cnt] = v;    capacity[cnt] = cap;    flow[cnt] = 0;      nxt[cnt] = ptr[u];      ptr[u] = cnt++;
    vertex[cnt] = u;    capacity[cnt] = 0;  flow[cnt] = 0;      nxt[cnt] = ptr[v];      ptr[v] = cnt++;
}

bool bfs (int s, int t)
{
    memset (level, -1, sizeof (level));
    int head = 0, tail = 0;
    bfsTree[tail++] = s;
    level[s] = 0;
    while (head < tail)
    {
        int v = bfsTree[head++];
        for (int i = ptr[v]; i >= 0; i = nxt[i])
            if (flow[i] < capacity[i] && level[vertex[i]] == -1)
            {
                bfsTree[tail++] = vertex[i];
                level[vertex[i]] = level[v] + 1;
            }
    }
    return (level[t] >= 0);
}

long long dfs (int s, int t, long long Flow)
{
    if (s == t)
        return Flow;
    for (int &i = temp[s]; i >= 0; i = nxt[i])
        if (flow[i] < capacity[i] && level[vertex[i]] == level[s] + 1)
        {
            long long M = dfs (vertex[i], t, min (Flow, capacity[i] - flow[i]));
            if (M)
            {
                flow[i] += M;
                flow[i ^ 1] -= M;
                return M;
            }
        }
    return (long long)0;
}

long long Dinic (int s, int t)
{
    long long MaxFlow = 0;
    while (bfs (s, t))
    {
        memcpy (temp, ptr, sizeof (ptr));
        while (true)
        {
            long long add = dfs (s, t, INF);
            if (add == 0)
                break;
            MaxFlow += add;
        }
    }
    return MaxFlow;
}

int main()
{
    //std::ios_base::sync_with_stdio(false);
    int t;
    int n,i,j,k,m,l;
    S2(n,m);
    fil(i,1,n+1)
    {
        S(a[i]);
        k=a[i];
        for(j=2;j*j<=k;j++)
        {
            if(k%j==0)
            {
                v2.push_back(j);
                while(k%j==0)
                    k/=j;
            }
        }
        if(k>1)
            v2.push_back(k);
    }
    sort(v2.begin(), v2.end());
    v2.erase(unique(v2.begin(), v2.end()),v2.end());

    int ans=0,f;
    fl(i,m)
    {
        S2(j,k);
        v3.push_back(make_pair(j,k));
    }

    fl(i,v2.size())
    {
        int f=0,c1;
        reset();
        fil(j,1,n+1)
        {
            int p=j;
            c1=0;
            while(a[j]%v2[i]==0)
            {
                a[j]/=v2[i];
                c1++;
            }
            if(p%2)
                AddEdge(0,j,c1);
            else
                AddEdge(j,n+1,c1);

        }
        fl(j,m)
        {
            int p=v3[j].first,q=v3[j].second;
            if(p%2)
                AddEdge(p,q,INF);
            else
                AddEdge(q,p,INF);
        }
        ans+=Dinic(0,n+1);
    }
    P(ans);
    return 0;
}


using namespace std;
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <limits.h>
#include <vector>
#include <map>
#include <bitset>
#include <string>
#include <iterator>
#include <set>
#include <utility>
#include <queue>
#include <numeric>
#include <functional>
#include <ctype.h>
#include <stack>
#include <algorithm>
#include <cstdlib>
#define S(x) scanf("%d",&x)
#define S2(x,y) scanf("%d%d",&x,&y)
#define wl(n) while(n--)
#define ll long long
#define bitcnt(x) __builtin_popcount(x)
#define P(x) printf("%d\n",x)
#define PB push_back
#define MP make_pair
#define fl(i,n) for(i=0;i<n;i++)
#define fil(i,a,n) for(i=a;i<n;i++)
#define rev(i,a,n) for(i=n-1;i>=a;i--)
#define mem(a,i) memset(a,i,sizeof(a))
#define F first
#define S1 second
typedef pair<int,int> P;
vector<int> v2,v4;
std::vector<P> v3;
pair<int,int> p1;
#define MOD 1000000007
#define debug(x)  printf("####%d####\n",x);
#define nl printf("\n");
#define str string
int a[1234567];
string s;
int dp[1001];
ll pow1(ll x,ll y)
{
    if(y==0)
    return 1;
    ll temp= pow1(x,y/2)%MOD;
    if(y%2==0)
    return (temp*temp)%MOD;
    else
    return (((temp*temp)%MOD)*x)%MOD;
}

typedef int fType;
typedef long long cType;

const fType INF = (int)1e9;
const cType DEF_OFFSET = (long long)1e6;
const cType NONE_OFFSET = (long long)1e12;

struct edge {
    int u, v;
    fType flow;
    cType cost;
    edge() {}
    edge(int u, int v, fType f, cType c) : u(u), v(v), flow(f), cost(c) {}
};

struct MinCostMaxFlow {
    int N;
    vector < vector <int> > G;
    vector <edge> E;
    int numEdges;
    vector <int> found, dad;
    vector <cType> dist;

    MinCostMaxFlow(int N):
     N(N), G(N), found(N), dist(N), dad(N), numEdges(0) {}

    void addEdge(int from, int to, fType capacity, cType cost) {
        // cerr << "from : " << from << " to : " << to << " capacity : " << capacity << " cost : " << cost << "\n";
        G[from].push_back(numEdges++);
        E.push_back(edge(from, to, capacity, cost));
        G[to].push_back(numEdges++);
        E.push_back(edge(to, from, 0, cType(-1) * cost));
    }

    bool spfa(int s, int t) {
        fill(dad.begin(), dad.end(), -1);
        fill(dist.begin(), dist.end(), (long long)1e18);
        fill(found.begin(), found.end(), 0);
        queue<int> Q;
        dist[s] = 0;
        Q.push(s);
        found[s] = true;

        while(!Q.empty()) {
          int u = Q.front(); Q.pop();
          if(u == t) continue;
          for (int i =0; i < G[u].size(); ++i) {
            edge &pres = E[G[u][i]];
            int v = pres.v;
            if(pres.flow <= 0) continue;
            if(dist[u] + pres.cost < dist[v]){
                dad[v] = G[u][i];
                dist[v] = dist[u] + pres.cost;
                if(!found[v]) Q.push(v), found[v] = true;
            }
          }
          found[u] = false;
        }
        return (dad[t] != -1);
    }

    fType dfs(int s,int t) {
        fType flow = INF;
        for(int i = dad[t]; i != -1; i = dad[E[i].u]) {
            if(E[i].flow < flow) flow = E[i].flow;
        }
        for(int i = dad[t]; i != -1; i = dad[E[i].u]) {
            E[i].flow -= flow;
            E[i^1].flow += flow;
        }
        return flow;
    }

    pair <fType, cType> getMaxFlow(int s, int t) {
        fType totflow = 0;
        cType totcost = 0;
        while(spfa(s,t)) {
            fType amt = dfs(s,t);
            totflow += amt;
            totcost += dist[t] * (cType)amt;
        }
        return make_pair(totflow, totcost);
    }
};
/*
  MinCostMaxFlow mcmf(m+v1.size()+2);

    int src=m+v1.size();
    int sink=src+1;

    fl(i,m)
    mcmf.addEdge(src,i,1,0);

    fl(i,v1.size())
    mcmf.addEdge(m+i,sink,1,0);

    fl(i,m) {
      fl(j,v1.size()) {
        if(ceilstrength[i]>=jirostrength[j])
          mcmf.addEdge(i,m+j,1,-(ceilstrength[i]-jirostrength[j]));
      }
      mcmf.addEdge(i,sink,1,0);
    }

    pair<fType,cType> flow=mcmf.getMaxFlow(src,sink);

    if(flow.first==m)
      return -flow.second;
    return 0;

*/

int main()
{
    //std::ios_base::sync_with_stdio(false);
    int t;
    int n,i,j,k,m,l;
    S2(n,m);
    fil(i,1,n+1)
    {
        S(a[i]);
        k=a[i];
        for(j=2;j*j<=k;j++)
        {
            if(k%j==0)
            {
                v2.push_back(j);
                while(k%j==0)
                    k/=j;
            }
        }
        if(k>1)
            v2.push_back(k);
    }
    sort(v2.begin(), v2.end());
    v2.erase(unique(v2.begin(), v2.end()),v2.end());

    int ans=0,f;
    fl(i,m)
    {
        S2(j,k);
        v3.push_back(make_pair(j,k));
    }

    int src=n+1;
    int sink=src+1;
    fl(i,v2.size())
    {
        int f=0,c1;
        MinCostMaxFlow mcmf(2*n+2);

        fil(j,1,n+1)
        {
            int p=j,p1=a[j];
            c1=0;
            while(p1%v2[i]==0)
            {
                p1/=v2[i];
                c1++;
            }
            if(p%2)
                mcmf.addEdge(src,j,c1,0);
            else
                mcmf.addEdge(j,sink,c1,0);

        }
        fl(j,m)
        {
            int p=v3[j].first,q=v3[j].second;
            int gcd=__gcd(a[p],a[q]);
            c1=0;
            while(gcd%v2[i]==0)
            {
                gcd/=v2[i];
                c1++;
            }
            if(p%2)
                mcmf.addEdge(p,q,c1,0);
            else
                mcmf.addEdge(q,p,c1,0);
        }
        ans+=mcmf.getMaxFlow(src,sink).first;
    }
    P(ans);
    return 0;
}


using namespace std;
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <limits.h>
#include <vector>
#include <map>
#include <bitset>
#include <string>
#include <iterator>
#include <set>
#include <utility>
#include <queue>
#include <numeric>
#include <functional>
#include <ctype.h>
#include <stack>
#include <algorithm>
#include <cstdlib>
#define S(x) scanf("%d",&x)
#define S2(x,y) scanf("%d%d",&x,&y)
#define wl(n) while(n--)
#define ll long long
#define bitcnt(x) __builtin_popcount(x)
#define P(x) printf("%d\n",x)
#define PB push_back
#define MP make_pair
#define fl(i,n) for(i=0;i<n;i++)
#define fil(i,a,n) for(i=a;i<n;i++)
#define rev(i,a,n) for(i=n-1;i>=a;i--)
#define mem(a,i) memset(a,i,sizeof(a))
#define F first
#define S1 second
typedef pair<int,int> P;
vector<int> v2,v4;
std::vector<P> v3;
pair<int,int> p1;
#define MOD 1000000007
#define debug(x)  printf("####%d####\n",x);
#define nl printf("\n");
#define str string
int a[1234567];
string s;
int dp[1001];
ll pow1(ll x,ll y)
{
    if(y==0)
    return 1;
    ll temp= pow1(x,y/2)%MOD;
    if(y%2==0)
    return (temp*temp)%MOD;
    else
    return (((temp*temp)%MOD)*x)%MOD;
}

typedef int fType;
typedef long long cType;

const fType INF = (int)1e9;
const cType DEF_OFFSET = (long long)1e6;
const cType NONE_OFFSET = (long long)1e12;

struct edge {
    int u, v;
    fType flow;
    cType cost;
    edge() {}
    edge(int u, int v, fType f, cType c) : u(u), v(v), flow(f), cost(c) {}
};

struct MinCostMaxFlow {
    int N;
    vector < vector <int> > G;
    vector <edge> E;
    int numEdges;
    vector <int> found, dad;
    vector <cType> dist;

    MinCostMaxFlow(int N):
     N(N), G(N), found(N), dist(N), dad(N), numEdges(0) {}

    void addEdge(int from, int to, fType capacity, cType cost) {
        // cerr << "from : " << from << " to : " << to << " capacity : " << capacity << " cost : " << cost << "\n";
        G[from].push_back(numEdges++);
        E.push_back(edge(from, to, capacity, cost));
        G[to].push_back(numEdges++);
        E.push_back(edge(to, from, 0, cType(-1) * cost));
    }

    bool spfa(int s, int t) {
        fill(dad.begin(), dad.end(), -1);
        fill(dist.begin(), dist.end(), (long long)1e18);
        fill(found.begin(), found.end(), 0);
        queue<int> Q;
        dist[s] = 0;
        Q.push(s);
        found[s] = true;

        while(!Q.empty()) {
          int u = Q.front(); Q.pop();
          if(u == t) continue;
          for (int i =0; i < G[u].size(); ++i) {
            edge &pres = E[G[u][i]];
            int v = pres.v;
            if(pres.flow <= 0) continue;
            if(dist[u] + pres.cost < dist[v]){
                dad[v] = G[u][i];
                dist[v] = dist[u] + pres.cost;
                if(!found[v]) Q.push(v), found[v] = true;
            }
          }
          found[u] = false;
        }
        return (dad[t] != -1);
    }

    fType dfs(int s,int t) {
        fType flow = INF;
        for(int i = dad[t]; i != -1; i = dad[E[i].u]) {
            if(E[i].flow < flow) flow = E[i].flow;
        }
        for(int i = dad[t]; i != -1; i = dad[E[i].u]) {
            E[i].flow -= flow;
            E[i^1].flow += flow;
        }
        return flow;
    }

    pair <fType, cType> getMaxFlow(int s, int t) {
        fType totflow = 0;
        cType totcost = 0;
        while(spfa(s,t)) {
            fType amt = dfs(s,t);
            totflow += amt;
            totcost += dist[t] * (cType)amt;
        }
        return make_pair(totflow, totcost);
    }
};
/*
  MinCostMaxFlow mcmf(m+v1.size()+2);

    int src=m+v1.size();
    int sink=src+1;

    fl(i,m)
    mcmf.addEdge(src,i,1,0);

    fl(i,v1.size())
    mcmf.addEdge(m+i,sink,1,0);

    fl(i,m) {
      fl(j,v1.size()) {
        if(ceilstrength[i]>=jirostrength[j])
          mcmf.addEdge(i,m+j,1,-(ceilstrength[i]-jirostrength[j]));
      }
      mcmf.addEdge(i,sink,1,0);
    }

    pair<fType,cType> flow=mcmf.getMaxFlow(src,sink);

    if(flow.first==m)
      return -flow.second;
    return 0;

*/

int main()
{
    //std::ios_base::sync_with_stdio(false);
    int t;
    int n,i,j,k,m,l;
    S2(n,m);
    fil(i,1,n+1)
    {
        S(a[i]);
        k=a[i];
        for(j=2;j*j<=k;j++)
        {
            if(k%j==0)
            {
                v2.push_back(j);
                while(k%j==0)
                    k/=j;
            }
        }
        if(k>1)
            v2.push_back(k);
    }
    sort(v2.begin(), v2.end());
    v2.erase(unique(v2.begin(), v2.end()),v2.end());

    int ans=0,f;
    fl(i,m)
    {
        S2(j,k);
        v3.push_back(make_pair(j,k));
    }

    int src=n+1;
    int sink=src+1;
    fl(i,v2.size())
    {
        int f=0,c1;
        MinCostMaxFlow mcmf(2*n+2);

        fil(j,1,n+1)
        {
            int p=j;
            c1=0;
            while(a[j]%v2[i]==0)
            {
                a[j]/=v2[i];
                c1++;
            }
            if(p%2)
                mcmf.addEdge(src,j,c1,0);
            else
                mcmf.addEdge(j,sink,c1,0);

        }
        fl(j,m)
        {
            int p=v3[j].first,q=v3[j].second;
            if(p%2)
                mcmf.addEdge(p,q,1e9,0);
            else
                mcmf.addEdge(q,p,1e9,0);
        }
        ans+=mcmf.getMaxFlow(src,sink).first;
    }
    P(ans);
    return 0;
}


using namespace std;
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <limits.h>
#include <vector>
#include <map>
#include <bitset>
#include <string>
#include <iterator>
#include <set>
#include <utility>
#include <queue>
#include <numeric>
#include <functional>
#include <ctype.h>
#include <stack>
#include <algorithm>
#include <cstdlib>
#define S(x) scanf("%d",&x)
#define S2(x,y) scanf("%d%d",&x,&y)
#define wl(n) while(n--)
#define ll long long
#define bitcnt(x) __builtin_popcount(x)
#define P(x) printf("%d\n",x)
#define PB push_back
#define MP make_pair
#define fl(i,n) for(i=0;i<n;i++)
#define fil(i,a,n) for(i=a;i<n;i++)
#define rev(i,a,n) for(i=n-1;i>=a;i--)
#define mem(a,i) memset(a,i,sizeof(a))
#define F first
#define S1 second
typedef pair<int,int> P;
vector<int> v2;
std::vector<P> v3;
pair<int,int> p1;
#define MOD 1000000007
#define debug(x)  printf("####%d####\n",x);
#define nl printf("\n");
#define str string
int a[1234567];
string s;
int dp[1001];
ll pow1(ll x,ll y)
{
    if(y==0)
    return 1;
    ll temp= pow1(x,y/2)%MOD;
    if(y%2==0)
    return (temp*temp)%MOD;
    else
    return (((temp*temp)%MOD)*x)%MOD;
}

// dinic algorithm for fast flow
#define MAX1 109
int capacity[MAX1][MAX1],flow[MAX1][MAX1],v1[MAX1][MAX1],dis[MAX1];
int source,destination,size[MAX1],q[MAX1],i;
bool bfs()
{
    // cout<<destination<<" "<<"gere\n";
    mem(dis,-1);
    int st=0,en=-1;
    dis[source]=0;
    q[++en]=source;
    int i;
    while(st<=en and st!=-1)
    {
        int p=q[st++];
        fl(i,size[p])
        {
            int q1=v1[p][i];
            if(dis[q1]==-1&&flow[p][q1]<capacity[p][q1])
            {
                dis[q1]=dis[p]+1;
                q[++en]=q1;
            }
        }
    }
    return dis[destination]!=-1;
}
int dfs(int ver,int ans)
{
    if(ver==destination)
        return ans;
    int i;
    fl(i,size[ver])
    {
        int p=v1[ver][i];
        if(dis[p]==dis[ver]+1&&flow[ver][p]<capacity[ver][p])
        {
            ans=min(ans,capacity[ver][p]-flow[ver][p]);
            int final=dfs(p,ans);
            if(final>0)
            {
                flow[ver][p]+=final;
                flow[p][ver]-=final;
                return final;
            }
        }
    }
    //dis[ver]=1000000042ll;
    return 0;
}
int dinic()
{
    int ans=0;
    while(bfs())
    {
        while(true)
        {
            int ab=dfs(source,1e9);
            if(ab==0)
                break;
            ans+=ab;
        }
    }
    return ans;
}
void clear()
{
    mem(capacity,0);
    mem(flow,0);
    mem(size,0);
    mem(v1,0);
    mem(dis,0);
}
int main()
{
    //std::ios_base::sync_with_stdio(false);
    int t;
    int n,i,j,k,m,l;
    S2(n,m);
    source=n+1;
    destination=n+2;
    fl(i,n)
    {
        S(a[i]);
        k=a[i];
        for(j=2;j*j<=k;j++)
        {
            if(k%j==0)
            {
                v2.push_back(j);
                while(k%j==0)
                    k/=j;
            }
        }
        if(k>1)
            v2.push_back(k);
    }
    sort(v2.begin(), v2.end());
    v2.erase(unique(v2.begin(), v2.end()),v2.end());
    int ans=0,f;
    fl(i,m)
    {
        S2(j,k);
        j--;
        k--;
        v3.push_back(make_pair(j,k));
    }
    fl(i,v2.size())
    {
        int f=0,c1,c2,c3;
        clear();
        fl(j,m)
        {
            int p=v3[j].first,q=v3[j].second;
            if(q%2)
                swap(p,q);
            int p1=a[p],q1=a[q];
            int gcd=__gcd(p1,q1);

            // p - odd q- even
            c1=0;
            while(p1%v2[i]==0)
            {
                p1/=v2[i];
                c1++;
            }
            c2=0;
            while(q1%v2[i]==0)
            {
                q1/=v2[i];
                c2++;
            }
            c3=0;
            while(gcd%v2[i]==0)
            {
                c3++;
                gcd/=v2[i];
            }

            // cout<<c1<<" "<<c2<<" "<<c3<<"\n";

            if(capacity[source][p+1]==0)
            {
                capacity[source][p+1]=c1;
                capacity[p+1][source]=c1;
                v1[source][size[source]]=p+1;
                v1[p+1][size[p+1]]=source;
                size[source]++;
                size[p+1]++;
            }

            if(capacity[destination][q+1]==0)
            {
                capacity[q+1][destination]=c2;
                capacity[destination][q+1]=c2;
                v1[destination][size[destination]]=q+1;
                v1[q+1][size[q+1]]=destination;
                size[destination]++;
                size[q+1]++;
            }

            capacity[p+1][q+1]=c3;
            capacity[q+1][p+1]=c3;
            v1[q+1][size[q+1]]=p+1;
            v1[p+1][size[p+1]]=q+1;
            size[p+1]++;
            size[q+1]++;

            if(c3>0)
                f=1;
        }
        if(f==1)
        {
            ans+=dinic();
            // cout<<ans<<" here\n";
        }
    }
    P(ans);
    return 0;
}


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

const int N = 1e2 + 100;

class MaxFlow {
  typedef int F;
  const F INF = 1e9 + 23;

  struct edge {
    int to; F cap, flow;
    edge() {}
    edge(int to, F c, F f)
      : to(to), cap(c), flow(f) {}
  };

  int V;
  vector<edge> es;
  vector<int> gr[N];
  int ptr[N], lv[N], q[N];

  bool bfs(int s, int d) {
    fill(lv, lv + V, -1);
    int qh = 0, qt = 0;
    lv[s] = 0; q[qt++] = s;
    while (qh < qt) {
      int v = q[qh++];
      for (auto eid : gr[v]) {
        edge e = es[eid];
        if (lv[e.to] == -1 and e.flow < e.cap) {
          lv[e.to] = lv[v] + 1; q[qt++] = e.to;
        }
      }
    }
    return lv[d] != -1;
  }

  F dfs(int v, int d, F val) {
    if (v == d) return val;

    for ( ; ptr[v] < (int)gr[v].size(); ++ptr[v]) {
      int eid = gr[v][ptr[v]];
      edge e = es[eid];
      if (lv[e.to] != lv[v] + 1) continue;
      F pushed = dfs(e.to, d, min(val, e.cap - e.flow));
      if (pushed > 0) {
        es[eid].flow += pushed;
        es[eid^1].flow -= pushed;
        return pushed;
      }
    }
    return 0;
  }

public:
  MaxFlow(int v) {
    Reset(v);
  }

  void Reset(int v) {
    V = v;
    es.clear();
    for (int i = 0; i < V; ++i) gr[i].clear();
  }

  void AddEdge(int fr, int to, F cap) {
    es.emplace_back(to, cap, 0);
    gr[fr].push_back((int)es.size()-1);
    es.emplace_back(fr, 0, 0);
    gr[to].push_back((int)es.size()-1);
  }

  F Compute(int s, int d) {
    F ans = 0;
    while (bfs(s, d)) {
      fill(ptr, ptr + V, 0);
      while (F now = dfs(s, d, INF)) ans += now;
    }
    return ans;
  }
};

int a[N];//, cnt[N];
int x[N], y[N];
set<int> divs;

int main()
{
  ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
  int n, m;
  cin >> n >> m;
  for (int i = 1; i <= n; ++i) cin >> a[i];
  for (int i = 0; i < m; ++i) {
    cin >> x[i] >> y[i];
    if (x[i] & 1) swap(x[i], y[i]);
  }

  for (int i = 1; i <= n; ++i) {
    int v = a[i];
    for (int p = 2; p <= v/p; ++p) {
      if (v % p == 0) {
        divs.insert(p);
        while (v % p == 0) v /= p;
      }
    }
    if (v > 1) divs.insert(v);
  }

  MaxFlow mf(n+2);
  int ans = 0;
  for (auto d : divs) {
    mf.Reset(n+2);
    for (int i = 1; i <= n; ++i) {
      int cnt = 0;
      while (a[i] % d == 0) {
        ++cnt;
        a[i] /= d;
      }
      if (i & 1) mf.AddEdge(i, n+1, cnt);
      else mf.AddEdge(0, i, cnt);
    }
    for (int i = 0; i < m; ++i) {
      //int cap = min(cnt[x[i]], cnt[y[i]]);
      mf.AddEdge(x[i], y[i], 100);
    }
    ans += mf.Compute(0, n+1);
  }
  cout << ans << '\n';
}
// g++ -W -Wall -Wextra -pedantic -std=c++0x -o p main.cpp


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

const int N = 1e2 + 10;

class MaxFlow {
  typedef int F;
  const F INF = 1e9 + 23;

  struct edge {
    int to; F cap, flow;
    edge() {}
    edge(int to, F c, F f)
      : to(to), cap(c), flow(f) {}
  };

  vector<edge> es;
  vector<int> gr[N];
  int ptr[N], lv[N], q[N];

  bool bfs(int s, int d) {
    fill(lv, lv + N, -1);
    int qh = 0, qt = 0;
    lv[s] = 0; q[qt++] = s;
    while (qh < qt) {
      int v = q[qh++];
      for (auto eid : gr[v]) {
        edge e = es[eid];
        if (lv[e.to] == -1 and e.flow < e.cap) {
          lv[e.to] = lv[v] + 1; q[qt++] = e.to;
        }
      }
    }
    return lv[d] != -1;
  }

  F dfs(int v, int d, F val) {
    if (v == d) return val;

    for ( ; ptr[v] < (int)gr[v].size(); ++ptr[v]) {
      int eid = gr[v][ptr[v]];
      edge e = es[eid];
      if (lv[e.to] != lv[v] + 1) continue;
      int left = e.cap - e.flow;
      if (left == 0) continue;
      F pushed = dfs(e.to, d, min(val, left));
      if (pushed > 0) {
        es[eid].flow += pushed;
        es[eid^1].flow -= pushed;
        return pushed;
      }
    }
    return 0;
  }

public:
  MaxFlow() {
    Reset();
  }

  void Reset() {
    es.clear();
    for (int i = 0; i < N; ++i) gr[i].clear();
  }

  void AddEdge(int fr, int to, F cap) {
    es.emplace_back(to, cap, 0);
    gr[fr].push_back((int)es.size()-1);
    es.emplace_back(fr, 0, 0);
    gr[to].push_back((int)es.size()-1);
  }

  F Compute(int s, int d) {
    F ans = 0;
    while (bfs(s, d)) {
      fill(ptr, ptr + N, 0);
      while (F now = dfs(s, d, INF)) ans += now;
    }
    return ans;
  }
};

int a[N], cnt[N];
int x[N], y[N];
set<int> divs;

int main()
{
  ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
  int n, m;
  cin >> n >> m;
  for (int i = 1; i <= n; ++i) cin >> a[i];
  for (int i = 0; i < m; ++i) {
    cin >> x[i] >> y[i];
    if (x[i] & 1) swap(x[i], y[i]);
  }

  for (int i = 1; i <= n; ++i) {
    int v = a[i];
    for (int p = 2; p <= v/p; ++p) {
      if (v % p == 0) {
        divs.insert(p);
        while (v % p == 0) v /= p;
      }
    }
    if (v > 1) divs.insert(v);
  }

  MaxFlow mf;
  int ans = 0;
  for (auto d : divs) {
    mf.Reset();
    fill(cnt, cnt + N, 0);
    for (int i = 1; i <= n; ++i) {
      while (a[i] % d == 0) {
        ++cnt[i];
        a[i] /= d;
      }
      if (i & 1) mf.AddEdge(i, n+1, cnt[i]);
      else mf.AddEdge(0, i, cnt[i]);
    }
    for (int i = 0; i < m; ++i) {
      int cap = min(cnt[x[i]], cnt[y[i]]);
      mf.AddEdge(x[i], y[i], cap);
    }
    ans += mf.Compute(0, n+1);
  }
  cout << ans << '\n';
}
// g++ -W -Wall -Wextra -pedantic -std=c++0x -o p main.cpp


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

const int N = 1e2 + 100;

class MaxFlow {
  typedef int F;
  const F INF = 1e9 + 23;

  struct edge {
    int to; F cap, flow;
    edge() {}
    edge(int to, F c, F f)
      : to(to), cap(c), flow(f) {}
  };

  int V;
  vector<edge> es;
  vector<int> gr[N];
  int ptr[N], lv[N], q[N];

  bool bfs(int s, int d) {
    fill(lv, lv + V, -1);
    int qh = 0, qt = 0;
    lv[s] = 0; q[qt++] = s;
    while (qh < qt) {
      int v = q[qh++];
      for (auto eid : gr[v]) {
        edge e = es[eid];
        if (lv[e.to] == -1 and e.flow < e.cap) {
          lv[e.to] = lv[v] + 1; q[qt++] = e.to;
        }
      }
    }
    return lv[d] != -1;
  }

  F dfs(int v, int d, F val) {
    if (v == d) return val;

    for ( ; ptr[v] < (int)gr[v].size(); ++ptr[v]) {
      int eid = gr[v][ptr[v]];
      edge e = es[eid];
      if (lv[e.to] != lv[v] + 1) continue;
      int left = e.cap - e.flow;
      if (left == 0) continue;
      F pushed = dfs(e.to, d, min(val, e.cap - e.flow));
      if (pushed > 0) {
        es[eid].flow += pushed;
        es[eid^1].flow -= pushed;
        return pushed;
      }
    }
    return 0;
  }

public:
  MaxFlow(int v) {
    Reset(v);
  }

  void Reset(int v) {
    V = v;
    es.clear();
    for (int i = 0; i < V; ++i) gr[i].clear();
  }

  void AddEdge(int fr, int to, F cap) {
    es.emplace_back(to, cap, 0);
    gr[fr].push_back((int)es.size()-1);
    es.emplace_back(fr, 0, 0);
    gr[to].push_back((int)es.size()-1);
  }

  F Compute(int s, int d) {
    F ans = 0;
    while (bfs(s, d)) {
      fill(ptr, ptr + V, 0);
      while (F now = dfs(s, d, INF)) ans += now;
    }
    return ans;
  }
};

int a[N], cnt[N];
int x[N], y[N];
set<int> divs;

int main()
{
  ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
  int n, m;
  cin >> n >> m;
  for (int i = 1; i <= n; ++i) cin >> a[i];
  for (int i = 0; i < m; ++i) {
    cin >> x[i] >> y[i];
    if (x[i] & 1) swap(x[i], y[i]);
  }

  for (int i = 1; i <= n; ++i) {
    int v = a[i];
    for (int p = 2; p <= v/p; ++p) {
      if (v % p == 0) {
        divs.insert(p);
        while (v % p == 0) v /= p;
      }
    }
    if (v > 1) divs.insert(v);
  }

  MaxFlow mf(n+2);
  int ans = 0;
  for (auto d : divs) {
    mf.Reset(n+2);
    fill(cnt, cnt + N, 0);
    for (int i = 1; i <= n; ++i) {
      while (a[i] % d == 0) {
        ++cnt[i];
        a[i] /= d;
      }
      if (i & 1) mf.AddEdge(i, n+1, cnt[i]);
      else mf.AddEdge(0, i, cnt[i]);
    }
    for (int i = 0; i < m; ++i) {
      int cap = min(cnt[x[i]], cnt[y[i]]);
      mf.AddEdge(x[i], y[i], cap);
    }
    ans += mf.Compute(0, n+1);
  }
  cout << ans << '\n';
}
// g++ -W -Wall -Wextra -pedantic -std=c++0x -o p main.cpp


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

const int N = 1e2 + 10;

class MaxFlow {
  typedef int F;
  const F INF = 1e9 + 23;

  struct edge {
    int to; F cap, flow;
    edge() {}
    edge(int to, F c, F f)
      : to(to), cap(c), flow(f) {}
  };

  vector<edge> es;
  vector<int> gr[N];
  int ptr[N], lv[N], q[N];

  bool bfs(int s, int d) {
    fill(lv, lv + N, -1);
    int qh = 0, qt = 0;
    lv[s] = 0; q[qt++] = s;
    while (qh < qt) {
      int v = q[qh++];
      for (auto eid : gr[v]) {
        edge e = es[eid];
        if (lv[e.to] == -1 and e.flow < e.cap) {
          lv[e.to] = lv[v] + 1; q[qt++] = e.to;
        }
      }
    }
    return lv[d] != -1;
  }

  F dfs(int v, int d, F val) {
    if (v == d) return val;

    for ( ; ptr[v] < (int)gr[v].size(); ++ptr[v]) {
      int eid = gr[v][ptr[v]];
      edge e = es[eid];
      if (lv[e.to] != lv[v] + 1) continue;
      int left = e.cap - e.flow;
      if (left == 0) continue;
      F pushed = dfs(e.to, d, min(val, e.cap - e.flow));
      if (pushed > 0) {
        es[eid].flow += pushed;
        es[eid^1].flow -= pushed;
        return pushed;
      }
    }
    return 0;
  }

public:
  MaxFlow() {
    Reset();
  }

  void Reset() {
    es.clear();
    for (int i = 0; i < N; ++i) gr[i].clear();
  }

  void AddEdge(int fr, int to, F cap) {
    es.emplace_back(to, cap, 0);
    gr[fr].push_back((int)es.size()-1);
    es.emplace_back(fr, 0, 0);
    gr[to].push_back((int)es.size()-1);
  }

  F Compute(int s, int d) {
    F ans = 0;
    while (bfs(s, d)) {
      fill(ptr, ptr + N, 0);
      while (F now = dfs(s, d, INF)) ans += now;
    }
    return ans;
  }
};

int a[N], cnt[N];
int x[N], y[N];
set<int> divs;

int main()
{
  ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
  int n, m;
  cin >> n >> m;
  for (int i = 1; i <= n; ++i) cin >> a[i];
  for (int i = 0; i < m; ++i) {
    cin >> x[i] >> y[i];
    if (x[i] & 1) swap(x[i], y[i]);
  }

  for (int i = 1; i <= n; ++i) {
    int v = a[i];
    for (int p = 2; p <= v/p; ++p) {
      if (v % p == 0) {
        divs.insert(p);
        while (v % p == 0) v /= p;
      }
    }
    if (v > 1) divs.insert(v);
  }

  MaxFlow mf;
  int ans = 0;
  for (auto d : divs) {
    mf.Reset();
    fill(cnt, cnt + N, 0);
    for (int i = 1; i <= n; ++i) {
      while (a[i] % d == 0) {
        ++cnt[i];
        a[i] /= d;
      }
      if (i & 1) mf.AddEdge(i, n+1, cnt[i]);
      else mf.AddEdge(0, i, cnt[i]);
    }
    for (int i = 0; i < m; ++i) {
      int cap = min(cnt[x[i]], cnt[y[i]]);
      mf.AddEdge(x[i], y[i], cap);
    }
    ans += mf.Compute(0, n+1);
  }
  cout << ans << '\n';
}
// g++ -W -Wall -Wextra -pedantic -std=c++0x -o p main.cpp


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

const int N = 1e2 + 100;

class MaxFlow {
  typedef int F;
  const F INF = 1e9 + 23;

  struct edge {
    int to; F cap, flow;
    edge() {}
    edge(int to, F c, F f)
      : to(to), cap(c), flow(f) {}
  };

  vector<edge> es;
  vector<int> gr[N];
  int reve[N*N], ptr[N], lv[N];

  bool bfs(int s, int d) {
    fill(lv, lv + N, -1);
    queue<int> q;
    lv[s] = 0; q.push(s);
    while (!q.empty()) {
      int v = q.front(); q.pop();
      for (auto eid : gr[v]) {
        edge e = es[eid];
        if (lv[e.to] == -1 and e.flow < e.cap) {
          lv[e.to] = lv[v] + 1; q.push(e.to);
        }
      }
    }
    return lv[d] != -1;
  }

  F dfs(int v, int d, F val) {
    if (v == d) return val;

    for ( ; ptr[v] < (int)gr[v].size(); ++ptr[v]) {
      int eid = gr[v][ptr[v]];
      edge e = es[eid];
      if (lv[e.to] != lv[v] + 1) continue;
      F pushed = dfs(e.to, d, min(val, e.cap - e.flow));
      if (pushed > 0) {
        es[eid].flow += pushed;
        es[reve[eid]].flow -= pushed;
        return pushed;
      }
    }
    return 0;
  }

public:
  MaxFlow() {
    Reset();
  }

  void Reset() {
    es.clear();
    for (int i = 0; i < N; ++i) gr[i].clear();
  }

  void AddEdge(int fr, int to, F cap) {
    es.emplace_back(to, cap, 0);
    gr[fr].push_back((int)es.size()-1);
    es.emplace_back(fr, 0, 0);
    gr[to].push_back((int)es.size()-1);
    reve[(int)es.size()-2] = (int)es.size()-1;
    reve[(int)es.size()-1] = (int)es.size()-2;
  }

  F Compute(int s, int d) {
    F ans = 0;
    while (bfs(s, d)) {
      fill(ptr, ptr + N, 0);
      while (F now = dfs(s, d, INF)) ans += now;
    }
    return ans;
  }
};

int a[N], cnt[N];
int x[N], y[N];
set<int> divs;

int main()
{
  ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
  int n, m;
  cin >> n >> m;
  for (int i = 1; i <= n; ++i) cin >> a[i];
  for (int i = 0; i < m; ++i) {
    cin >> x[i] >> y[i];
    if (x[i] & 1) swap(x[i], y[i]);
  }

  for (int i = 1; i <= n; ++i) {
    int v = a[i];
    for (int p = 2; p <= v/p; ++p) {
      if (v % p == 0) {
        divs.insert(p);
        while (v % p == 0) v /= p;
      }
    }
    if (v > 1) divs.insert(v);
  }

  MaxFlow mf;
  int ans = 0;
  for (auto d : divs) {
    mf.Reset();
    for (int i = 1; i <= n; ++i) {
      cnt[i] = 0;
      while (a[i] % d == 0) {
        ++cnt[i];
        a[i] /= d;
      }
      if (i & 1) mf.AddEdge(i, n+1, cnt[i]);
      else mf.AddEdge(0, i, cnt[i]);
    }
    for (int i = 0; i < m; ++i) {
      int cap = min(cnt[x[i]], cnt[y[i]]);
      mf.AddEdge(x[i], y[i], cap);
    }
    ans += mf.Compute(0, n+1);
  }
  cout << ans << '\n';
}
// g++ -W -Wall -Wextra -pedantic -std=c++0x -o p main.cpp