#include <bits/stdc++.h>
using namespace std;
inline int sqr(int x) { return x * x; }
inline int cube(int x) { return x * x * x; }
inline long long sqrLL(long long x) { return x * x; }
inline long long cubeLL(long long x) { return x * x * x; }
const long long LLINF = 9223372036854775807LL;
const long long LLINF17 = 100000000000000000LL;
const int INF = 1000000000;
const int INF9 = 1000000000;
long long MOD = 1000000007;
const double eps = 1e-7;
const double PI = acos(-1.0);
template <typename T>
void check(T &a, const T &b) {
  if (a >= b) {
    a %= b;
  }
}
template <typename T>
void read(T &x) {
  register T c = getchar();
  x = 0;
  int t = 0;
  if (c == '-') t = 1, c = getchar();
  for (; (c < 48 || c > 57); c = getchar())
    ;
  for (; c > 47 && c < 58; c = getchar()) {
    x = (x << 1) + (x << 3) + c - 48;
  }
  if (t) x = -x;
}
template <typename T>
T gcd(T u, T v) {
  if (u == v) return u;
  if (u == 0) return v;
  if (v == 0) return u;
  if (~u & 1) {
    if (v & 1)
      return gcd(u >> 1, v);
    else
      return gcd(u >> 1, v >> 1) << 1;
  }
  if (~v & 1) return gcd(u, v >> 1);
  if (u > v) return gcd((u - v) >> 1, v);
  return gcd((v - u) >> 1, u);
}
long long mulmod(long long a, long long b, long long m) {
  long long q = (long long)(((long double)a * (long double)b) / (long double)m);
  long long r = a * b - q * m;
  if (r > m) r %= m;
  if (r < 0) r += m;
  return r;
}
template <typename T, typename S>
T expo(T e, S n) {
  T x = 1, p = e;
  while (n) {
    if (n & 1) x = x * p;
    p = p * p;
    n >>= 1;
  }
  return x;
}
template <typename T>
T powerL(T e, T n, T &m) {
  T x = 1, p = e;
  while (n) {
    if (n & 1) x = mulmod(x, p, m);
    p = mulmod(p, p, m);
    n >>= 1;
  }
  return x;
}
template <typename T>
T InverseEuler(T a, T &m) {
  return (a == 1 ? 1 : power(a, m - 2, m));
}
const int NUM = 100000 + 5;
vector<int> v[NUM], _v[NUM], cost;
int n, _m;
bool vis[NUM];
stack<int> s;
void dfs(int index, long long &mini, long long &tot, bool cond,
         vector<int> const (&t)[NUM]) {
  if (vis[index]) return;
  vis[index] = true;
  if (!cond) {
    if (mini == (long long)cost[index]) {
      tot++;
    } else if (mini > (long long)cost[index]) {
      mini = (long long)cost[index];
      tot = 1LL;
    }
  }
  for (int(i) = (0); (i) < (t[index].size()); (i)++) {
    if (!vis[t[index][i]]) {
      dfs(t[index][i], mini, tot, cond, t);
    }
  }
  if (cond) s.push(index);
  return;
}
int main() {
  read(n);
  cost.resize(n + 2);
  long long h = 0LL;
  for (int(i) = (1); (i) <= (n); (i)++) {
    read(cost[i]);
    h += (long long)cost[i];
  }
  read(_m);
  if (!_m) {
    printf("%I64d 1\n", h);
    return 0;
  }
  for (int(i) = (0); (i) < (_m); (i)++) {
    int a, b;
    read(a), read(b);
    v[a].push_back(b);
    _v[b].push_back(a);
  }
  long long mini = 0;
  long long ans = 1LL;
  for (int(i) = (1); (i) <= (n); (i)++) {
    if (!vis[i]) dfs(i, mini, ans, 1, v);
  }
  memset(vis, false, sizeof(vis));
  while (s.size()) {
    int index = s.top();
    s.pop();
    if (!vis[index]) {
      long long temp1 = INF;
      long long temp2 = 0;
      dfs(index, temp1, temp2, 0, _v);
      mini += temp1;
      ans *= temp2;
      check(ans, MOD);
    }
  }
  printf("%I64d %I64d\n", mini, ans);
  return 0;
}
