#include <bits/stdc++.h>
using namespace std;
namespace FastIO_ {
template <typename T>
T read() {
  T x = 0;
  int f = 1;
  char c = getchar();
  while (c < '0' || c > '9') {
    if (c == '-') f = -1;
    c = getchar();
  }
  while (c >= '0' && c <= '9')
    x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
  return x * f;
}
template <typename T>
void _print(T x) {
  if (x > 9) _print(x / 10);
  putchar(x % 10 + '0');
}
template <typename T>
void print(T x, char c) {
  if (x < 0) putchar('-'), x = -x;
  _print(x);
  if (c) putchar(c);
}
}  // namespace FastIO_
namespace BIT_ {
template <typename T>
struct BIT {
  int Size;
  vector<T> Num;
  BIT<T>() { memset(Num, 0, sizeof Num); }
  BIT<T>(int S) { Num.resize(Size = S, 0); }
  void Update(T x, int pos) {
    for (int i = pos; i <= Size; i += (i & -i)) Num[i] += x;
  }
  T GetSum(int pos) {
    T ret = 0;
    for (int i = pos; i > 0; i -= (i & -i)) ret += Num[i];
    return ret;
  }
};
}  // namespace BIT_
namespace Math_ {
template <typename T1, typename T2>
T1 Pow(T1 x, T2 y, int MOD) {
  T1 ret = 1;
  while (y) {
    if (y & 1) ret = ret * x % MOD;
    y >>= 1;
    x = x * x % MOD;
  }
  return ret;
}
void GetPrime(int N, vector<int> &Prime) {
  vector<int> vis;
  vis.resize(N + 5, 0);
  for (int i = 2; i <= N; i++) {
    if (!vis[i]) Prime.push_back(i);
    for (int j = 0; j < int(Prime.size()) && Prime[j] * i <= N; j++) {
      vis[Prime[j] * i] = 1;
      if (i % Prime[j] == 0) break;
    }
  }
}
template <typename T>
void Divide(T N, vector<pair<int, int> > &A, vector<int> Prime) {
  for (int i = 0; i < int(Prime.size()); i++) {
    int p = Prime[i], cnt = 0;
    while (N % p == 0) N /= p, cnt++;
    if (cnt) A.push_back(make_pair(p, cnt));
  }
  if (N > 1) A.push_back(make_pair(N, 1));
}
void GetFac(int N, int MOD, int *fac) {
  fac[0] = 1;
  for (int i = 1; i <= N; i++) fac[i] = (long long)fac[i - 1] * i % MOD;
}
void GetFac(int N, int MOD, int *fac, int *facInv) {
  GetFac(N, MOD, fac);
  facInv[N] = Pow<int, int>(fac[N], MOD - 2, MOD);
  for (int i = N - 1; i >= 1; i--)
    facInv[i] = (long long)facInv[i + 1] * (i + 1) % MOD;
}
void GetC(int N, int **C, int MOD) {
  C[0][0] = 1;
  for (int i = 1; i <= N; i++)
    for (int j = 1; j <= i; j++)
      C[i][j] = ((long long)C[i - 1][j - 1] + (long long)C[i - 1][j]) % MOD;
}
int calC(int N, int M, int MOD, int *fac, int *facInv) {
  if (M > N) return 0;
  return (long long)fac[N] * facInv[N - M + 1] % MOD * facInv[M] % MOD;
}
int calC(int N, int M, int MOD) {
  if (M > N) return 0;
  if (M > N - M) M = N - M;
  int ret = 1, cnt = 1;
  for (int i = N; i >= N - M + 1; i--)
    ret = (long long)ret * i / cnt % MOD, cnt++;
  return ret;
}
int calA(int N, int M, int MOD, int *fac, int *facInv) {
  if (M > N) return 0;
  return (long long)fac[N] * facInv[N - M + 1] % MOD;
}
int calA(int N, int M, int MOD) {
  if (M > N) return 0;
  int ret = 1;
  for (int i = N; i >= N - M + 1; i--) ret = (long long)ret * i % MOD;
  return ret;
}
}  // namespace Math_
namespace Graph_ {
struct Graph {
  int N, M;
  vector<int> Match, vis;
  vector<vector<int> > G;
  Graph() {
    N = 0, M = 0, G.clear();
    Match.clear(), vis.clear();
  }
  Graph(int Size) { G.resize(Size + 5, vector<int>(0, 0)); }
  bool MaxMatch_dfs(int u, int id) {
    for (int i = 0; i < int(G[u].size()); i++) {
      int v = G[u][i];
      if (vis[v] != id) {
        vis[v] = id;
        if (!Match[v] || MaxMatch_dfs(Match[v], id)) {
          Match[v] = u;
          Match[u] = v;
          return 1;
        }
      }
    }
    return 0;
  }
  int MaxMatch(int X) {
    int ret = 0;
    Match.clear();
    Match.resize(N + 5, 0);
    vis.resize(N + 5, 0);
    for (int i = 1; i <= X; i++)
      if (!Match[i]) ret += MaxMatch_dfs(i, i);
    return ret;
  }
};
}  // namespace Graph_
using namespace FastIO_;
using namespace Graph_;
int N, M;
Graph A(2 * 100000);
struct Shoes {
  int C, S, ID;
} P[100000 + 5];
map<int, int> cnt;
bool cmp(Shoes i, Shoes j) { return i.C > j.C; }
int main() {
  N = read<int>();
  for (int i = 1; i <= N; i++)
    P[i].C = read<int>(), P[i].S = read<int>(), P[i].ID = i;
  ;
  sort(P + 1, P + N + 1, cmp);
  for (int i = 1; i <= N; i++) cnt[P[i].S] = i;
  M = read<int>();
  for (int i = 1; i <= M; i++) {
    int D = read<int>(), L = read<int>();
    if (cnt.count(L) && P[cnt[L]].C <= D) A.G[cnt[L]].push_back(i + N);
    if (cnt.count(L + 1) && P[cnt[L + 1]].C <= D)
      A.G[cnt[L + 1]].push_back(i + N);
  }
  A.N = N + M;
  int tmp = A.MaxMatch(N);
  long long Ans = 0;
  for (int i = 1; i <= N; i++)
    if (A.Match[i]) Ans += P[i].C;
  print<long long>(Ans, '\n'), print<int>(tmp, '\n');
  for (int i = 1; i <= N; i++)
    if (A.Match[i]) print<int>(A.Match[i] - N, ' '), print<int>(P[i].ID, '\n');
}
