#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;   }