/*~~~~~~~~~~~~~~~
HDU 1827
by mowenwen
2015.8.28
~~~~~~~~~~~~~~~*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define inf 0x7fffffff
#define maxn 1000+10
#define maxm 2000+10
struct Edge
{
int next,v;
}edge[maxm];
int n,m,index,top,tot,scc;
int head[maxn],Stack[maxn],dfn[maxn],low[maxn],belong[maxn],cost[maxn];
int indegree[maxn], outdegree[maxn];
bool instack[maxn];
int Max(int a,int b)
{
return a > b? a: b;
}
void init()
{
memset(head, -1, sizeof(head));
memset(instack, false, sizeof(instack));
memset(dfn, -1, sizeof(dfn));
memset(low, 0, sizeof(low));
memset(indegree, 0, sizeof(indegree));
memset(outdegree, 0, sizeof(outdegree));
memset(belong, 0,sizeof(belong));
tot = 0;
index = 0;
top = 0;
scc = 0;
}
void addedge(int u,int v)
{
edge[tot].next = head[u];
edge[tot].v = v;
head[u] = tot ++;
}
void tarjan(int u)
{
int v;
dfn[u] = low[u] = ++index;
Stack[top ++] = u;
instack[u] = true;
for(int i = head[u];i != -1;i = edge[i].next)
{
v = edge[i].v;
if(dfn[v] == -1)
{
tarjan(v);
if(low[v] < low[u])
low[u] = low[v];
}
else
{
if(instack[v] && dfn[v] < low[u])
{
low[u] = dfn[v];
}
}
}
if(dfn[u] == low[u])
{
scc ++;
int j;
do
{
j = Stack[--top];
instack[j] = false; //这里写错,wa了快20发,555555
belong[j] = scc;
}
while(j != u);
}
}
void solve()
{
for(int i = 1;i <= n;i ++)
{
if(dfn[i] == -1)
tarjan(i);
}
}
int main()
{
while(scanf("%d%d", &n, &m) != EOF)
{
init();
for(int i = 1;i <= n;i ++)
scanf("%d", &cost[i]);
while(m --)
{
int a, b;
scanf("%d%d", &a, &b);
addedge(a, b);
}
solve();
for(int i = 1;i <= n;i ++)
{
for(int j = head[i];j != -1;j = edge[j].next)
{
int u = i;
int v = edge[j].v;
if(belong[u] != belong[v])
{
indegree[belong[v]] ++;
}
}
}
int ans = 0,cnt = 0;
int mincost;
for(int i = 1;i <= scc;i ++)
{
mincost = inf;
if(indegree[i] == 0)
{
cnt ++;
for(int j = 1;j <= n;j ++)
{
if(belong[j] == i)
{
mincost = min(mincost, cost[j]);
}
}
ans += mincost;
}
}
printf("%d %d\n",cnt,ans);
}
return 0;
}