#include <bits/stdc++.h>
using namespace std;
long long int mypow(long long int a, long long int b) {
  long long int res = 1;
  while (b) {
    if (b & 1) res = res * a;
    b >>= 1;
    if (b) {
      a = a * a;
    }
  }
  return res;
}
long long int modpow(long long int a, long long int b,
                     long long int m = 1000000007) {
  a %= m;
  long long int res = 1;
  while (b) {
    if (b & 1) res = res * a % m;
    b >>= 1;
    if (b) {
      a = a * a % m;
    }
  }
  return res;
}
long long int modinv(long long int a) {
  return modpow(a, 1000000007 - 2, 1000000007);
}
vector<long long int> power(11);
void computepower() {
  vector<int> p = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31};
  for (int(i) = (0); (i) < (p.size()); ++(i)) {
    power[i] = modpow(2, p[i]) - 1;
  }
}
vector<long long int> powerof2(60);
void computepower2() {
  powerof2[0] = 1;
  for (int(i) = (1); (i) < (60); ++(i)) {
    powerof2[i] = powerof2[i - 1] * 2;
  }
}
vector<long long int> modinvr(100005);
void computemodinvr() {
  modinvr[0] = modinvr[1] = 1;
  for (int i = 2; i < 100005; i++)
    modinvr[i] =
        modinvr[1000000007 % i] * (1000000007 - 1000000007 / i) % 1000000007;
}
vector<long long int> modinvrfact(100005);
vector<long long int> factr(100005);
void computeodinvrfact() {
  factr[0] = 1;
  modinvrfact[0] = 1;
  for (int(i) = (1); (i) < (100005); ++(i)) {
    factr[i] = (factr[i - 1] * i) % 1000000007;
    modinvrfact[i] = modinv(factr[i]) % 1000000007;
  }
}
bool mycompr(pair<int, int> i1, pair<int, int> i2) {
  return i1.second > i2.second;
}
void unique_elem(vector<long long int> &v) {
  sort(v.begin(), v.end());
  auto ip = unique(v.begin(), v.end());
  v.resize(distance(v.begin(), ip));
}
void unique_elem_with_count(vector<long long int> &a,
                            vector<long long int> &unique,
                            vector<long long int> &cnt_unique,
                            vector<long long int> &sum_unique, int n) {
  sort(a.begin(), a.end());
  long long int j = 0;
  long long int sum = 0;
  while (j < n) {
    long long int cnt = 1;
    if (j != n - 1) {
      while (a[j + 1] == a[j]) {
        cnt++;
        j++;
        if (j == n - 1) {
          break;
        }
      }
    }
    sum += cnt;
    unique.push_back(a[j]);
    cnt_unique.push_back(cnt);
    sum_unique.push_back(sum);
    j++;
  }
}
void bfs(int root, int par, vector<bool> &vis, vector<long long int> &dist,
         vector<vector<int> > &adj) {
  queue<int> q;
  q.push(root);
  dist[root] = 0;
  vis[root] = true;
  while (!q.empty()) {
    int p = q.front();
    q.pop();
    for (int i = 0; i < adj[p].size(); i++) {
      if (vis[adj[p][i]] == false) {
        dist[adj[p][i]] = dist[p] + 1;
        q.push(adj[p][i]);
        vis[adj[p][i]] = true;
      }
    }
  }
}
void bfs_tree(int p, int par, vector<vector<long long int> > &adj,
              vector<long long int> &ways, vector<long long int> &dist) {
  for (int i = 0; i < adj[p].size(); i++) {
    if (adj[p][i] == par) {
      continue;
    }
    bfs_tree(adj[p][i], p, adj, ways, dist);
  }
}
void topologicalSortUtil(int v, bool visited[], stack<int> &Stack,
                         vector<vector<long long int> > &adj,
                         vector<bool> &finish) {
  visited[v] = true;
  for (int(i) = (0); (i) < (adj[v].size()); ++(i))
    if (!visited[adj[v][i]])
      topologicalSortUtil(adj[v][i], visited, Stack, adj, finish);
    else {
      if (finish[adj[v][i]] == false) {
      }
    }
  finish[v] = true;
  Stack.push(v);
}
void topologicalSort(long long int V, vector<vector<long long int> > &adj,
                     stack<int> &Stack) {
  bool *visited = new bool[V + 1];
  vector<bool> finish(V + 1, false);
  for (int i = 0; i < V + 1; i++) visited[i] = false;
  for (int i = 1; i < V + 1; i++)
    if (visited[i] == false)
      topologicalSortUtil(i, visited, Stack, adj, finish);
}
void dfs(long long int v, vector<bool> &visited, stack<int> &st,
         vector<vector<long long int> > &adj) {
  visited[v] = true;
  for (int(i) = (0); (i) < (adj[v].size()); ++(i)) {
    if (!visited[adj[v][i]]) {
      dfs(adj[v][i], visited, st, adj);
    }
  }
  st.push(v);
}
void getTranspose(vector<vector<long long int> > &adj,
                  vector<vector<long long int> > &adj_tr, long long int n) {
  for (int(i) = (1); (i) < (n + 1); ++(i)) {
    for (int(j) = (0); (j) < (adj[i].size()); ++(j))
      adj_tr[adj[i][j]].push_back(i);
  }
}
void findSCCs(vector<vector<long long int> > &adj, long long int n,
              vector<long long int> &a) {
  stack<int> Stack;
  vector<bool> visited(n + 1, false);
  for (int(i) = (1); (i) < (n + 1); ++(i))
    if (!visited[i]) dfs(i, visited, Stack, adj);
  vector<vector<long long int> > adj_tr(n + 1);
  getTranspose(adj, adj_tr, n);
  for (int(i) = (0); (i) < (n + 1); ++(i)) visited[i] = false;
  long long int prod = 1, ans = 0;
  while (!Stack.empty()) {
    long long int v = Stack.top();
    Stack.pop();
    if (!visited[v]) {
      stack<int> st1;
      dfs(v, visited, st1, adj_tr);
      vector<long long int> v;
      long long int minm = 1e9 + 1;
      while (!st1.empty()) {
        long long int x = st1.top();
        v.push_back(x);
        st1.pop();
        minm = min(minm, a[x]);
      }
      long long int cnt = 0;
      for (int(i) = (0); (i) < (v.size()); ++(i)) {
        if (a[v[i]] == minm) {
          cnt++;
        }
      }
      prod *= cnt;
      prod %= 1000000007;
      ans += minm;
    }
  }
  cout << ans << " " << prod << '\n';
}
void graph(vector<vector<long long int> > &adj, long long int m) {
  long long int x, y;
  for (int(i) = (0); (i) < (m); ++(i)) {
    cin >> x >> y;
    adj[x].push_back(y);
  }
}
void decToBinary(int n, vector<int> &binaryNum) {
  binaryNum.resize(32, 0);
  int i = 0;
  while (n > 0) {
    binaryNum[i] = n % 2;
    n = n / 2;
    i++;
  }
}
long long int Binarytodec(string &st) {
  computepower2();
  long long int len = st.size();
  long long int num = 0;
  for (int(i) = (0); (i) < (st.size()); ++(i)) {
    if (st[i] == '1') {
      num += powerof2[len - i - 1];
    }
  }
  return num;
}
vector<int> spf(1000005);
void sieve() {
  spf[1] = 1;
  for (int i = 2; i < 1000005; i++) spf[i] = i;
  for (int i = 4; i < 1000005; i += 2) spf[i] = 2;
  for (int i = 3; i * i < 1000005; i++) {
    if (spf[i] == i) {
      for (int j = i * i; j < 1000005; j += i) {
        if (spf[j] == j) {
          spf[j] = i;
        }
      }
    }
  }
}
vector<int> getFactorization(int x) {
  vector<int> ret;
  map<int, int> fact;
  while (x != 1) {
    ret.push_back(spf[x]);
    if (fact.find(spf[x]) == fact.end()) {
      fact[spf[x]] = 1;
    } else {
      fact[spf[x]]++;
    }
    x = x / spf[x];
  }
  for (auto it = fact.begin(); it != fact.end(); it++) {
    if (it->second & 1) {
      ret.push_back(it->first);
    }
  }
  return ret;
}
void calc_pref(vector<long long int> &a, vector<long long int> &prefsum) {
  prefsum[0] = a[0];
  for (int(i) = (1); (i) < (a.size()); ++(i)) {
    prefsum[i] = prefsum[i - 1] + a[i];
  }
}
bool containsOnlyDigit(string str) {
  int l = str.length();
  for (int i = 0; i < l; i++) {
    if (str.at(i) < '0' || str.at(i) > '9') return false;
  }
  return true;
}
void solve() {
  long long int n, m, l, q, k;
  cin >> n;
  vector<long long int> a(n + 1);
  vector<vector<long long int> > adj(n + 1);
  for (int(i) = (1); (i) < (n + 1); ++(i)) {
    cin >> a[i];
  }
  cin >> m;
  graph(adj, m);
  findSCCs(adj, n, a);
}
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  int t = 1;
  int tt = 1;
  while (t--) {
    solve();
  }
}
