#include <bits/stdc++.h>   using namespace std;   const int inf = 0x3f3f3f3f;   const double eps = 1e-6;   template <typename A, typename B>   ostream& operator<<(ostream& os, const pair<A, B>& p) {     return os << p.first <<  ,  << p.second;   }   template <typename T>   struct point {     T x, y;     point(T xx = 0, T yy = 0) : x(xx), y(yy) {}     T len2() const { return x * x + y * y; }     double len() const { return sqrt(double(len2())); }     bool operator==(const point<T>& p) const { return x == p.x && y == p.y; }   };   template <typename T>   point<T> operator+(const point<T>& a, const point<T>& b) {     return point<T>(a.x + b.x, a.y + b.y);   }   template <typename T>   point<T> operator-(const point<T>& a, const point<T>& b) {     return point<T>(a.x - b.x, a.y - b.y);   }   template <typename T>   T scal(const point<T>& a, const point<T>& b) {     return a.x * b.x + a.y * b.y;   }   template <typename T>   T vect(const point<T>& a, const point<T>& b) {     return a.x * b.y - a.y * b.x;   }   template <typename T>   ostream& operator<<(ostream& os, const point<T>& p) {     return os <<  (  << p.x <<  ,  << p.y <<  ) ;   }   const int maxn = 100100;   pair<int, pair<int, int> > a[maxn], b[maxn];   int below[maxn], direct[maxn], belowsecond[maxn];   long long d[maxn][2];   int main() {     int n;     cin >> n;     for (int i = 0; i < n; i++) {       scanf( %d%d , &a[i].second.first, &a[i].first);       a[i].second.second = i;     }     int m;     cin >> m;     for (int i = 0; i < m; i++) {       scanf( %d%d , &b[i].second.first, &b[i].first);       b[i].second.second = i;     }     sort(a, a + n);     sort(b, b + m);     memset(direct, -1, sizeof(direct));     memset(below, -1, sizeof(below));     memset(belowsecond, -1, sizeof(belowsecond));     for (int i = 0; i < n; i++) {       pair<int, pair<int, int> >* d1 =           lower_bound(b, b + m,                       pair<int, pair<int, int> >(                           a[i].first, pair<int, int>(a[i].second.first, 0)));       pair<int, pair<int, int> >* d2 =           lower_bound(b, b + m,                       pair<int, pair<int, int> >(                           a[i].first - 1, pair<int, int>(a[i].second.first, 0)));       if (d1 != b + m && d1->first == a[i].first &&           d1->second.first >= a[i].second.first) {         direct[i] = d1->second.second;       }       if (d2 != b + m && d2->first + 1 == a[i].first &&           d2->second.first >= a[i].second.first) {         below[i] = d2->second.second;         d2++;         if (d2 != b + m && d2->first + 1 == a[i].first &&             d2->second.first >= a[i].second.first) {           belowsecond[i] = d2->second.second;         }       }     }     long long mx = 0;     for (int i = 0; i < n; i++) {       if (direct[i] >= 0) {         long long q = max(d[i][0], d[i][1]);         d[i + 1][1] = max(d[i + 1][1], a[i].second.first + q);       }       if (below[i] >= 0) {         d[i + 1][0] = max(d[i + 1][0], d[i][0] + a[i].second.first);         if (i > 0 && direct[i - 1] != below[i]) {           d[i + 1][0] = max(d[i + 1][0], d[i][1] + a[i].second.first);         }         if (i > 0 && direct[i - 1] == below[i] && belowsecond[i] >= 0) {           d[i + 1][0] = max(d[i + 1][0], d[i][1] + a[i].second.first);         }       }       d[i + 1][0] = max(d[i + 1][0], max(d[i][0], d[i][1]));       mx = max(mx, max(d[i + 1][0], d[i + 1][1]));     }     cout << mx << endl;     int cur = n;     int t = 0;     if (d[cur][t] != mx) t++;     assert(d[cur][t] == mx);     vector<pair<int, int> > res;     set<int> guyused;     for (; cur > 0; cur--) {       if (res.size()) {         guyused.insert(res.back().second);       }       if (d[cur - 1][0] == d[cur][t]) {         t = 0;         continue;       }       if (d[cur - 1][1] == d[cur][t]) {         t = 1;         continue;       }       int p = a[cur - 1].second.first;       if (!guyused.count(direct[cur - 1])) {         if (p + d[cur - 1][1] == mx && direct[cur - 1] >= 0) {           res.push_back(               pair<int, int>(a[cur - 1].second.second, direct[cur - 1]));           mx -= p;           t = 1;           continue;         }         if (p + d[cur - 1][0] == mx && direct[cur - 1] >= 0) {           res.push_back(               pair<int, int>(a[cur - 1].second.second, direct[cur - 1]));           mx -= p;           t = 0;           continue;         }       }       assert(below[cur - 1] >= 0);       if (!guyused.count(below[cur - 1])) {         if (d[cur - 1][0] + p == mx) {           res.push_back(pair<int, int>(a[cur - 1].second.second, below[cur - 1]));           mx -= p;           t = 0;           continue;         }         if (cur - 2 < 0 ||             (direct[cur - 2] != below[cur - 1] && d[cur - 1][1] + p == mx)) {           res.push_back(pair<int, int>(a[cur - 1].second.second, below[cur - 1]));           mx -= p;           t = 1;           continue;         }       }       assert(!guyused.count(belowsecond[cur - 1]));       if (cur - 2 >= 0 && direct[cur - 2] == below[cur - 1] &&           belowsecond[cur - 1] >= 0 && d[cur - 1][1] + p == mx) {         res.push_back(             pair<int, int>(a[cur - 1].second.second, belowsecond[cur - 1]));         mx -= p;         t = 1;         continue;       }       assert(0);     }     printf( %d n , res.size());     for (int i = 0; i < res.size(); i++) {       printf( %d %d n , res[i].second + 1, res[i].first + 1);     }     return 0;   }