#include <bits/stdc++.h>
using namespace std;
template <class T>
T sq(T x) {
  return x * x;
}
const long long inf = 2147383647;
const double pi = 2 * acos(0.0);
const double eps = 1e-9;
const long long maxint = 2147483647;
const long long minint = -2147483648;
long long gcd(long long a, long long b) {
  while (b) {
    a = a % b;
    swap(a, b);
  }
  return a;
}
long long lcm(long long a, long long b) { return (a / gcd(a, b)) * b; }
long long power(long long a, long long p) {
  long long res = 1, x = a;
  while (p) {
    if (p & 1) res = res * x;
    x = x * x;
    p >>= 1;
  }
  return res;
}
long long bigmod(long long a, long long p, long long mod) {
  long long res = 1, x = a;
  while (p) {
    if (p & 1) res = (res * x) % mod;
    x = (x * x) % mod;
    p >>= 1;
  }
  return res;
}
map<int, int> mp, mp2;
struct pop {
  int first, second, id;
};
vector<pop> people;
int m;
int assign[100010];
long long memo[100010][2][2];
long long dp(int pos, int a, int b) {
  if (pos == m) {
    return 0;
  }
  if (memo[pos][a][b] != -1) return memo[pos][a][b];
  int na, nb;
  if (pos + 1 < m && people[pos].first == people[pos + 1].first) {
    na = a;
    nb = b;
  } else if (pos + 1 < m && people[pos].first + 1 == people[pos + 1].first) {
    na = b;
    nb = 1;
  } else {
    na = 1;
    nb = 1;
  }
  long long x = dp(pos + 1, na, nb);
  long long y = x;
  if (a && people[pos].second >= mp[people[pos].first]) {
    int na, nb;
    if (pos + 1 < m && people[pos].first == people[pos + 1].first) {
      na = 0;
      nb = b;
    } else if (pos + 1 < m && people[pos].first + 1 == people[pos + 1].first) {
      na = b;
      nb = 1;
    } else {
      na = 1;
      nb = 1;
    }
    y = mp[people[pos].first] + dp(pos + 1, na, nb);
  }
  long long z = x;
  if (b && people[pos].second >= mp[people[pos].first + 1]) {
    int na = a, nb = b;
    if (pos + 1 < m && people[pos + 1].first == people[pos].first) {
      na = a;
      nb = 0;
    } else if (pos + 1 < m && people[pos].first + 1 == people[pos + 1].first) {
      na = 0;
      nb = 1;
    } else {
      na = 1;
      nb = 1;
    }
    z = mp[people[pos].first + 1] + dp(pos + 1, na, nb);
  }
  long long r = max(max(x, y), z);
  return memo[pos][a][b] = r;
}
bool compare(const pop &a, const pop &b) {
  if (a.first < b.first)
    return true;
  else if (a.first == b.first && a.second < b.second)
    return true;
  else
    return false;
}
void init(int pos, int a, int b, long long res) {
  if (pos == m) return;
  int na, nb;
  if (pos + 1 < m && people[pos].first == people[pos + 1].first) {
    na = a;
    nb = b;
  } else if (pos + 1 < m && people[pos].first + 1 == people[pos + 1].first) {
    na = b;
    nb = 1;
  } else {
    na = 1;
    nb = 1;
  }
  long long x = dp(pos + 1, na, nb);
  if (x == res) {
    assign[pos] = -1;
    return init(pos + 1, na, nb, res);
  }
  long long y = x;
  if (a && people[pos].second >= mp[people[pos].first]) {
    int na, nb;
    if (pos + 1 < m && people[pos].first == people[pos + 1].first) {
      na = 0;
      nb = b;
    } else if (pos + 1 < m && people[pos].first + 1 == people[pos + 1].first) {
      na = b;
      nb = 1;
    } else {
      na = 1;
      nb = 1;
    }
    y = mp[people[pos].first] + dp(pos + 1, na, nb);
    if (y == res) {
      assign[pos] = people[pos].first;
      return init(pos + 1, na, nb, res - mp[people[pos].first]);
    }
  }
  long long z = x;
  if (b && people[pos].second >= mp[people[pos].first + 1]) {
    int na = a, nb = b;
    if (pos + 1 < m && people[pos + 1].first == people[pos].first) {
      na = a;
      nb = 0;
    } else if (pos + 1 < m && people[pos].first + 1 == people[pos + 1].first) {
      na = 0;
      nb = 1;
    } else {
      na = 1;
      nb = 1;
    }
    z = mp[people[pos].first + 1] + dp(pos + 1, na, nb);
    if (z == res) {
      assign[pos] = people[pos].first + 1;
      return init(pos + 1, na, nb, res - mp[people[pos].first + 1]);
    }
  }
}
int main() {
  memset(memo, -1, sizeof memo);
  int n;
  scanf("%d", &n);
  int i;
  for (i = 0; i < n; i++) {
    int ci, si;
    scanf("%d %d", &ci, &si);
    mp[si] = ci;
    mp2[si] = i + 1;
  }
  scanf("%d", &m);
  for (i = 0; i < m; i++) {
    pop temp;
    scanf("%d %d", &temp.second, &temp.first);
    temp.id = i + 1;
    people.push_back(temp);
  }
  sort(people.begin(), people.end(), compare);
  long long res = dp(0, 1, 1);
  printf("%lld\n", res);
  init(0, 1, 1, res);
  int r = 0;
  for (i = 0; i < m; i++) {
    int t = assign[i];
    if (t == -1) continue;
    if (mp2[t] > 0) r++;
  }
  printf("%d\n", r);
  for (i = 0; i < m; i++) {
    int t = assign[i];
    if (t == -1) continue;
    if (mp2[t] > 0) {
      printf("%d %d\n", people[i].id, mp2[t]);
    }
  }
  return 0;
}
