#include<bits/stdc++.h>
#define int long long
using namespace std;
#define read(x) scanf("%lld",&x)
#define writepr(x,y) printf("%lld %lld\n",x,y)
const int MAXN = 2e5 + 10;
int n,m,val[MAXN],idx,head[MAXN],head_new[MAXN],idx_new,in[MAXN],T;
int Answerw = 0,Answerk = 1e18;
struct node{int v,nxt;}edge[MAXN],edge_new[MAXN];
inline void add(int u,int v)
{
edge[++ idx].v = v;
edge[idx].nxt = head[u];
head[u] = idx;
}
inline void add_new(int u,int v)
{
edge_new[++ idx_new].v = v;
edge_new[idx_new].nxt = head_new[u];
head_new[u] = idx_new;
}
int dfn[MAXN],low[MAXN],col[MAXN],sizk[MAXN],sizw[MAXN],st[MAXN];
bool vis[MAXN];
int top,sccnt,ind;
inline void init()
{
fill(dfn,dfn + n + 1,0);
fill(sizk,sizk + n + 1,0);
fill(sizw,sizw + n + 1,0);
fill(st,st + top + 1,0);
fill(head,head + idx + 1,0);
fill(head_new,head_new + idx_new + 1,0);
top = sccnt = ind = idx_new = idx = 0;
}
void tarjan(int u)
{
dfn[u] = low[u] = ++ ind;
vis[u] = 1;
st[++ top] = u;
for(int i = head[u];i;i = edge[i].nxt)
{
int v = edge[i].v;
if(!dfn[v])
{
tarjan(v);
low[u] = min(low[u],low[v]);
}
else if(vis[v])
low[u] = min(low[u],dfn[v]);
}
if(low[u] == dfn[u])
{
sccnt ++;
while(st[top + 1] != u)
{
col[st[top]] = sccnt;
sizk[sccnt] ++;
sizw[sccnt] += val[st[top]];
vis[st[top --]] = 0;
}
}
}
signed main()
{
read(T);
while(T --)
{
init();
read(n),read(m);
for(int i = 1;i <= n;i ++) read(val[i]);
for(int i = 1;i <= m;i ++)
{
int u,v;
read(u),read(v);
if(u == v) continue;
add(u,v);
}
for(int i = 1;i <= n;i ++)
{
if(!dfn[i]) tarjan(i);
}
for(int u = 1;u <= n;u ++)
{
for(int i = head[u];i;i = edge[i].nxt)
{
int v = edge[i].v;
if(col[u] != col[v])
{
add_new(col[u],col[v]);
in[col[v]] ++;
}
}
}
Answerk = 0,Answerw = 1e18;
vector <int> dpk(sccnt + 1,0),dpw(sccnt + 1,0);
queue <int> q;
for(int i = 1;i <= sccnt;i ++)
{
if(!in[i])
{
q.push(i);
dpw[i] = sizw[i],dpk[i] = sizk[i];
Answerk = max(Answerk,dpk[i]);
}
}
while(!q.empty())
{
int u = q.front();
q.pop();
for(int i = head_new[u];i;i = edge_new[i].nxt)
{
int v = edge_new[i].v;
if(!(-- in[v])) q.push(v);
if(dpk[v] < dpk[u] + sizk[v])
{
dpk[v] = dpk[u] + sizk[v];
dpw[v] = dpw[u] + sizw[v];
Answerk = max(Answerk,dpk[v]);
}
else if(dpk[v] == dpk[u] + sizk[v])
dpw[v] = min(dpw[v],dpw[u] + sizw[v]);
}
}
for(int i = 1;i <= sccnt;i ++)
{
if(dpk[i] == Answerk) Answerw = min(Answerw,dpw[i]);
}
writepr(Answerk,Answerw);
}
return 0;
}