#include <bits/stdc++.h>
using namespace std;
struct EDGE {
  int y;
  EDGE* Next;
};
EDGE EPool[200020];
int EPTop = 0;
EDGE* E[100010];
int insert_edge(int x, int y) {
  EDGE* Now = &EPool[EPTop++];
  Now->y = y;
  Now->Next = E[x];
  E[x] = Now;
  return 0;
}
int LinkTo[100010];
int Choose[100010];
bool dfs(int x) {
  for (EDGE* e = E[x]; e; e = e->Next) {
    int y = e->y;
    if (LinkTo[y] == x) continue;
    if (LinkTo[y] == -1 || dfs(LinkTo[y])) {
      LinkTo[y] = x;
      Choose[x] = y;
      return true;
    }
  }
  return false;
}
struct SHOES {
  int cost;
  int size;
  int id;
  bool operator<(const SHOES& b) const { return cost > b.cost; }
};
SHOES Shoes[100010];
int money[100010];
int csize[100010];
int main(void) {
  memset(Choose, -1, sizeof(Choose));
  memset(LinkTo, -1, sizeof(LinkTo));
  int n = 0;
  scanf("%d", &n);
  for (int i = 0; i < n; i++) {
    int size = 0;
    scanf("%d %d", &Shoes[i].cost, &Shoes[i].size);
    Shoes[i].id = i + 1;
  }
  sort(Shoes, Shoes + n);
  map<int, int> mp;
  for (int i = 0; i < n; i++) mp[Shoes[i].size] = i;
  int m = 0;
  scanf("%d", &m);
  for (int i = 0; i < m; i++) {
    scanf("%d %d", &money[i], &csize[i]);
  }
  for (int i = m - 1; i >= 0; i--) {
    if (mp.find(csize[i] + 1) != mp.end()) {
      int id = mp[csize[i] + 1];
      if (Shoes[id].cost <= money[i]) insert_edge(id, i);
    }
    if (mp.find(csize[i]) != mp.end()) {
      int id = mp[csize[i]];
      if (Shoes[id].cost <= money[i]) insert_edge(id, i);
    }
  }
  long long ans = 0;
  int cnt = 0;
  for (int i = 0; i < n; i++) {
    if (dfs(i)) {
      ans += Shoes[i].cost;
      cnt++;
    }
  }
  printf("%I64d\n%d\n", ans, cnt);
  for (int i = 0; i < n; i++) {
    if (Choose[i] == -1) continue;
    if (LinkTo[Choose[i]] == i) printf("%d %d\n", Choose[i] + 1, Shoes[i].id);
  }
  while (getchar() != EOF)
    ;
  return 0;
}
