#include <iostream>
#include <iomanip>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <complex>
#include <cstring>
#include <cstdlib>
#include <string>
#include <cmath>
#include <cassert>
#include <queue>
#include <set>
#include <map>
#include <valarray>
#include <bitset>
#include <stack>
#define REP(i,n) for(int i=0;i<(int)n;++i)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)
#define ALL(c) (c).begin(), (c).end()
using namespace std;
typedef long long  ll;
typedef pair<int, int > pii;


typedef vector<vector<int> > matrix;

struct Node {
  vector<Node> vs;
  vector<pii> con;              // (src,to)
  int v;
  void print() {
    if (vs.size() == 0) {
      cout << v;
    } else {
      REP(i,vs.size()) {
        cout << "[";
        vs[i].print();
        cout << "]";
        cout << "(" << con[i].first << "," << con[i].second <<")";
      }
    }
  }
  bool exist(int a) {
    if (vs.size() == 0) {
      return (v == a);
    } else {
      REP(i,vs.size()) {
        if (vs[i].exist(a)) return 1;
      }
    }
    return 0;
  }
  bool connect(vector<pii> &res, int a) {
    // print();cout << endl;
    // cout << a << endl;
    // cout << ":" << exist(a) << endl;
    bool f = 0;
    if (vs.size() == 0) {
      f = v == a;
    } else {
      REP(i,vs.size()) {
        int ii = (i+1)%vs.size();
        if (vs[ii].exist(a)) {
          vs[ii].connect(res,a);
        } else {
          res.push_back(con[i]);
          vs[ii].connect(res,con[i].second);
        }
      }
    }
    return f;
  }
};

typedef vector<vector<int> > matrix;
const int inf = 1<<29;
  
void backward_traverse(int v, int s, int r, matrix &g,
                       vector<int> &no, vector< vector<int> > &comp,
                       vector<int> &prev, vector<int> &mcost,
                       vector<Node> &nodes, vector<pii> &edge,
                       vector<int> &mark, int &cost, bool &found) {
  const int n = g.size();
  if (mark[v]) {
    vector<int> temp = no;
    found = true;
    Node node;
    do {
      cost += mcost[v];
      node.con.push_back(edge[v]);
      v = prev[v];
      node.vs.push_back(nodes[v]);
      
      if (v != s) {
        while (comp[v].size() > 0) {
          no[comp[v].back()] = s;
          comp[s].push_back(comp[v].back());
          comp[v].pop_back();
        }
      }
    } while (v != s);
    reverse(ALL(node.vs));
    reverse(ALL(node.con));
    nodes[s] = node;
    for (int j = 0; j < n; ++j)
      if (j != r && no[j] == s)
        for (int i = 0; i < n; ++i)
          if (no[i] != s && g[i][j] < inf) {
            g[i][j] -= mcost[ temp[j] ];
          }
  }
  mark[v] = true;
  for (int i = 0; i < n; ++i)
    if (no[i] != no[v] && prev[ no[i] ] == v)
      if (!mark[ no[i] ] || i == s)
        backward_traverse(i, s, r, g,
                          no, comp, prev, mcost, nodes, edge, mark, cost, found);
}

int minimum_spanning_arborescence(int r, matrix g, vector<pii> &edges) {
  const int n = g.size();
  vector<int> no(n);
  vector< vector<int> > comp(n);
  vector<Node> nodes(n);
  for (int i = 0; i < n; ++i) {
    no[i] = i;
    comp[i].push_back(i);
    nodes[i].v = i;
  }
  int cost = 0;
  vector<int> pprev;
  while (1) {
    vector<int> prev(n, -1);
    vector<int> mcost(n, inf);
    vector<pii> edge(n);
    for (int i = 0; i < n; ++i) {
      for (int j = 0; j < n; ++j) {
        if (j == r) continue;
        if (no[i] != no[j] && g[i][j] < inf) {
          if (g[i][j] < mcost[ no[j] ]) {
            mcost[ no[j] ] = g[i][j];
            prev[ no[j] ] = no[i];
            edge[no[j]] = pii(i,j);
          }
        }
      }
    }
    pprev = prev;
    bool stop = true;
    vector<int> mark(n);
    for (int i = 0; i < n; ++i) {
      if (i == r || mark[i] || comp[i].size() == 0) continue;
      bool found = false;
      backward_traverse(i, i, r, g,
                        no, comp, prev, mcost, nodes, edge, mark, cost, found);
      if (found) stop = false;
    }
    // cout << "cost " << cost << endl;
    // REP(i,n) {
    //   REP(j,n) {
    //     cout << g[i][j] << " ";
    //   }
    //   cout << endl;
    // }
    // cout << "no: ";
    // FOR(it, no) cout << *it << " " ; cout << endl;
    // cout << "mcost: ";
    // FOR(it, mcost) cout << *it << " " ; cout << endl;
    
    // cout << "prev: ";
    // REP(i,n) cout << prev[i] << " "; cout << endl;
    // cout << "prevprev: ";
    // FOR(it, prevprev) cout << *it << " "; cout << endl;
    // cout << endl;
    // nodes[1].print(); cout << endl;
    if (stop) {
      int cnt = 0;
      REP(i,n) {
        if (prev[i] >= 0) {
          nodes[i].connect(edges, edge[i].second);
          // nodes[i].print();
          // cout << " " << edge[i].first << " " << edge[i].second <<endl;
          edges.push_back(pii(edge[i].first, edge[i].second));
          cost += mcost[i];
        }
        if (prev[no[i]] < 0) cnt++;
      }
      // FOR(it, edges) {
      //   cout << it->first << " " << it->second << endl;
      // }
      if (cnt != 1) return -1;
      return cost;
    }
  }
}

struct Edge {
  int src, dst;
  int weight;
  Edge(int src, int dst, int weight) :
    src(src),dst(dst),weight(weight) {}
  bool operator<(const Edge &rhs) const {
    return weight > rhs.weight;
  }
};
typedef vector<Edge> Edges;
typedef vector<Edges> Graph;

vector<int> dijkstra(const Graph &g, int s, vector<int> &prev) {
  int n = g.size();
  vector<int> dist(n,inf);
  dist[s] = 0;
  prev.assign(n, -1);
  priority_queue<Edge> Q; // "e < f" <=> "e.weight > f.weight"
  for (Q.push(Edge(-2, s, 0)); !Q.empty(); ) {
    Edge e = Q.top(); Q.pop();
    if (prev[e.dst] != -1) continue;
    prev[e.dst] = e.src;
    FOR(f,g[e.dst]) {
      if (dist[f->dst] > e.weight+f->weight) {
        dist[f->dst] = e.weight+f->weight;
        Q.push(Edge(f->src, f->dst, e.weight+f->weight));
      }
    }
  }
  return dist;
}

vector<int> buildPath(const vector<int> &prev, int t) {
  vector<int> path;
  for (int u = t; u >= 0; u = prev[u])
    path.push_back(u);
  reverse(ALL(path));
  return path;
}

string name[100];
int m[100];
int sum[100];
pii p[100000];

vector<int> dprev[100];

string tostr(pii a) {
  stringstream ss;
  ss << name[a.first] << " " << a.second;
  return ss.str();
}

int main() {
  int n;
  while(cin >> n) {
    sum[0] = 0;
    int N = 0;
    map<string, int > mp;
    for (int i=0; i<n; ++i) {
      cin >>name[i] >> m[i];
      sum[i+1] = sum[i] + m[i];
      mp[name[i]] = i;
      N += m[i];
    }
    int cnt = 0;
    for (int i=0; i<n; ++i) {
      for (int j=0; j<m[i]; ++j) {
        p[cnt++] = pii(i,j);
      }
    }
    int E;
    cin >> E;
    Graph g(N);
    for(int i=0; i<E; ++i) {
      string cs1,cs2;
      int v1,v2,c;
      cin >> cs1>>v1>>cs2>>v2>>c;
      int c1 = mp[cs1];
      int c2 = mp[cs2];
      int a = sum[c1] + v1;
      int b = sum[c2] + v2;
      g[a].push_back(Edge(a,b,c));
    }
    matrix mat(n,vector<int>(n));
    vector<int> prev;
    for (int i=0; i<n ;++i) {
      vector<int> dist = dijkstra(g, sum[i], dprev[i]);
      // FOR(it, dprev[i]) cout << "*" << *it; cout << endl;
      for (int j=0; j<n; ++j) {
        mat[i][j] = dist[sum[j]];
      }
    }
    // for (int i=0; i<n; ++i) {
    //   for (int j=0;j<n; ++j) {
    //     cout << mat[i][j] << " ";
    //   }
    //   cout << endl;
    // }
    int Q;
    cin >> Q;
    for (int i=0; i<Q; ++i) {
      string cs3;
      int v3;
      cin >> cs3 >> v3;
      int c3 = mp[cs3];
      int a = sum[c3] + v3;
      vector<int> dist = dijkstra(g, a, prev);
      bool ng = 0;
      REP(i,n) {
        if (dist[sum[i]] == inf) {
          ng = 1;
        }
      }
      if (ng) {
        cout << "Impossible" << endl;
      } else {
        int res = dist[sum[c3]];
        vector<pii> edges;
        int tmpres = minimum_spanning_arborescence(c3, mat, edges);
        int ans = res + tmpres;

        if (res == inf || tmpres < 0)  {
          assert(0);
        } else {
          cout << ans << endl;
          vector<int> path = buildPath(prev, sum[c3]);
          set<pii> ST; int cnt = 0;
          REP(i,path.size()-1) {
            ST.insert(pii(path[i], path[i+1])); cnt++;
            // cout << tostr(p[path[i]]) << " " << tostr(p[path[i+1]]) << endl;
          }
          assert(edges.size() == n-1);
          set<int> S;
          FOR(it, edges) S.insert(it->second);
          assert(S.size() == n-1);
          FOR(it, edges) {
            int a = it->second;
            int b = it->first;
            int A = sum[a];

            vector<int> path = buildPath(dprev[b], A);
            REP(i,path.size()-1) {
              ST.insert(pii(path[i], path[i+1])); cnt++;
              // cout << tostr(p[path[i]]) << " " << tostr(p[path[i+1]]) << endl;
            }
          }
          FOR(it, ST) {
            cout << tostr(p[it->first]) << " " << tostr(p[it->second]) << endl;
          }
        }
      }
      puts("-----");
    }
  }
}

### Prompt

Please formulate a Cpp solution to the following problem:

Problem

In 19XX, the Allied Forces were formed in n countries. Each country belonging to the Allied Forces has set up one or more bases in the country to protect itself from the invasion of enemy forces and is on the alert. Figure 1 shows an example of an Allied country, where the rectangle represents each country and the circle within it represents the base of that country.


Figure 1
Figure 1


When an enemy army invades, the information is to be transmitted from the base where it was first discovered to the bases of other countries or own countries belonging to the Allied Forces. It costs a positive integer to convey information to other locations.

In addition, each country has exactly one base to which soldiers belonging to the Allied Translator and Interpreter Section (ATIS) are assigned. Only this soldier can speak the language of all countries belonging to the Allied Forces, and the other soldiers can only speak the language of their own country. Therefore, when the base that received the information tries to convey the information to another country, if the base does not have soldiers belonging to ATIS, the information is transmitted from there to the base having soldiers belonging to ATIS in the home country and the information is sent to other countries. Need to be sent.

Each country is assigned a number from 0 to [the number of bases in that country-1], and the 0th base has soldiers belonging to ATIS. In other words, only the 0th base can transmit information to the bases in other countries, and communication from other bases to other countries is not possible. In addition, if the information is transmitted to the 0th base of the country, it is assumed that the information is transmitted to the whole country.

Communication is not possible between all bases for various reasons. Even if information can be transmitted from one base to another, the opposite is not always true. In addition, the cost of transmitting information from one base to another is not always the same as the cost of transmitting information to another base.

Based on these facts, I would like to know the transmission method with the lowest total cost of disseminating information to the entire Allied army when a base discovers an enemy army. It is assumed that the information has been distributed to the entire Allied Forces when the information is transmitted from the base where the enemy army is first found to the 0th base of all the countries belonging to the Allied Forces.

Since the base where the enemy army was found is given as a question, output the method of transmitting the information to the entire Allied army and its cost at the lowest cost.

For example, consider the following case (Sample Input 4, first question)

Suppose the first base of the country neepal discovers an enemy army. In this case, since it is not possible to communicate from the first base to another country, the information is first transmitted to the 0th base in the home country.

Next, the information is transmitted from the 0th base to the country luxenbourg, noway. It is possible to communicate directly from neepal to the 0th base of luxenbourg, but it is cheaper to convey the information to the 3rd base and then to the 0th base. In this case, the minimum cost to convey information to the 0th country of all countries is 12. There are multiple transmission methods that cost only 12, but one of them may be output as the answer.

The red arrow in Figure 2 below is one of the answers.


<image>
Figure 2

Constraints

* 1 ≤ n ≤ 26
* 1 ≤ mi ≤ 100
* 0 ≤ e ≤ 322400
* 0 ≤ costi ≤ 100
* 1 ≤ q ≤ 10
* countryname is a character string consisting of lowercase letters ‘a’ to ‘z’ and having a length of 1 or more and 20 or less.
* No more than one country with the same name will be given
* When c1i and c2i of the pair of communicable bases are the same, v1i and v2i are different
* When c1i and c2i of the pair of communicable bases are different, v1i is always 0.

Input


n
countryname0 m0
countryname1 m1
...
countrynamen-1 mn-1
e
c10 v10 c20 v20 cost0
c11 v11 c21 v21 cost1
...
c1e-1 v1e-1 c2e-1 v2e-1 coste-1
q
c30 v30
c31 v31
...
c3q-1 v3q-1



* n represents the number of countries belonging to the Allied Forces
* countrynamei is the name of the i-th country belonging to the Allied Forces, and mi is the number of bases in the i-th country.
* e represents the number of pairs of bases that can communicate
* The following e-line is given the cost cost of transmitting information from the base v1i in country c1i to the base v2i in country c2i.
* q represents the number of questions
* The following line q is given the name c3i of the country where the enemy army was found and its base v3i.
* c1i, c2i, c3i are any of the countries belonging to the Allied Forces
* v1i, v2i, v3i can never be more than the number of bases in the country

Output

The answer to each question is output in the following format.

On the last line of the answer to each question, print one line of 5'-', "-----" (excluding ").

If the answer exists

The first line outputs the minimum cost required to disseminate information from the country base given in the question to the entire Allied Forces.

The transmission method at that time is output on the second and subsequent lines. The transmission method is expressed in the following format.


c40 v40 c50 v50
c41 v41 c51 v51
...


Indicates that information has been transmitted from the base v4i in country c4i to the base v5i in country c5i.

Be careful of the following.

* It is not necessary to output in the order in which communication was performed
* If there is one or more transmission methods that minimize the total cost, one of them should be output.
* Do not output the same communicable pair more than once
* c4i, c5i must be one of the countries given in the input
* v4i, v5i must be less than the number of bases in the country




If the answer does not exist

Print “Impossible” (excluding “)” on one line.

Examples

Input

3
frence 1
usi 1
powland 1
2
usi 0 frence 0 10
frence 0 powland 0 10
2
usi 0
powland 0


Output

20
usi 0 frence 0
frence 0 powland 0
-----
Impossible
-----


Input

2
usso 2
caneda 2
4
usso 1 usso 0 1
usso 0 caneda 0 10
usso 0 caneda 1 2
caneda 1 caneda 0 2
1
usso 1


Output

5
usso 1 usso 0
usso 0 caneda 1
caneda 1 caneda 0
-----


Input

3
chinax 1
ok 1
austraria 2
6
chinax 0 austraria 0 5
austraria 0 chinax 0 5
austraria 1 austraria 0 1
ok 0 austraria 0 5
austraria 0 ok 0 5
ok 0 austraria 1 1
2
chinax 0
ok 0


Output

10
chinax 0 austraria 0
austraria 0 ok 0
-----
7
ok 0 austraria 1
austraria 1 austraria 0
austraria 0 chinax 0
-----


Input

3
neepal 2
luxenbourg 4
noway 2
12
neepal 1 neepal 0 2
neepal 0 noway 1 2
neepal 0 luxenbourg 0 10
neepal 0 luxenbourg 3 2
luxenbourg 3 luxenbourg 1 2
luxenbourg 3 luxenbourg 2 2
luxenbourg 1 luxenbourg 0 2
luxenbourg 2 luxenbourg 0 2
noway 1 noway 0 2
noway 0 neepal 0 2
noway 0 luxenbourg 3 2
noway 0 luxenbourg 0 10
3
neepal 1
luxenbourg 3
noway 1


Output

12
neepal 1 neepal 0
neepal 0 luxenbourg 3
luxenbourg 3 luxenbourg 2
luxenbourg 2 luxenbourg 0
neepal 0 noway 1
noway 1 noway 0
-----
Impossible
-----
10
noway 1 noway 0
neepal 0 luxenbourg 3
luxenbourg 3 luxenbourg 2
luxenbourg 2 luxenbourg 0
noway 0 neepal 0
-----

### Response

```cpp
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <complex>
#include <cstring>
#include <cstdlib>
#include <string>
#include <cmath>
#include <cassert>
#include <queue>
#include <set>
#include <map>
#include <valarray>
#include <bitset>
#include <stack>
#define REP(i,n) for(int i=0;i<(int)n;++i)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)
#define ALL(c) (c).begin(), (c).end()
using namespace std;
typedef long long  ll;
typedef pair<int, int > pii;


typedef vector<vector<int> > matrix;

struct Node {
  vector<Node> vs;
  vector<pii> con;              // (src,to)
  int v;
  void print() {
    if (vs.size() == 0) {
      cout << v;
    } else {
      REP(i,vs.size()) {
        cout << "[";
        vs[i].print();
        cout << "]";
        cout << "(" << con[i].first << "," << con[i].second <<")";
      }
    }
  }
  bool exist(int a) {
    if (vs.size() == 0) {
      return (v == a);
    } else {
      REP(i,vs.size()) {
        if (vs[i].exist(a)) return 1;
      }
    }
    return 0;
  }
  bool connect(vector<pii> &res, int a) {
    // print();cout << endl;
    // cout << a << endl;
    // cout << ":" << exist(a) << endl;
    bool f = 0;
    if (vs.size() == 0) {
      f = v == a;
    } else {
      REP(i,vs.size()) {
        int ii = (i+1)%vs.size();
        if (vs[ii].exist(a)) {
          vs[ii].connect(res,a);
        } else {
          res.push_back(con[i]);
          vs[ii].connect(res,con[i].second);
        }
      }
    }
    return f;
  }
};

typedef vector<vector<int> > matrix;
const int inf = 1<<29;
  
void backward_traverse(int v, int s, int r, matrix &g,
                       vector<int> &no, vector< vector<int> > &comp,
                       vector<int> &prev, vector<int> &mcost,
                       vector<Node> &nodes, vector<pii> &edge,
                       vector<int> &mark, int &cost, bool &found) {
  const int n = g.size();
  if (mark[v]) {
    vector<int> temp = no;
    found = true;
    Node node;
    do {
      cost += mcost[v];
      node.con.push_back(edge[v]);
      v = prev[v];
      node.vs.push_back(nodes[v]);
      
      if (v != s) {
        while (comp[v].size() > 0) {
          no[comp[v].back()] = s;
          comp[s].push_back(comp[v].back());
          comp[v].pop_back();
        }
      }
    } while (v != s);
    reverse(ALL(node.vs));
    reverse(ALL(node.con));
    nodes[s] = node;
    for (int j = 0; j < n; ++j)
      if (j != r && no[j] == s)
        for (int i = 0; i < n; ++i)
          if (no[i] != s && g[i][j] < inf) {
            g[i][j] -= mcost[ temp[j] ];
          }
  }
  mark[v] = true;
  for (int i = 0; i < n; ++i)
    if (no[i] != no[v] && prev[ no[i] ] == v)
      if (!mark[ no[i] ] || i == s)
        backward_traverse(i, s, r, g,
                          no, comp, prev, mcost, nodes, edge, mark, cost, found);
}

int minimum_spanning_arborescence(int r, matrix g, vector<pii> &edges) {
  const int n = g.size();
  vector<int> no(n);
  vector< vector<int> > comp(n);
  vector<Node> nodes(n);
  for (int i = 0; i < n; ++i) {
    no[i] = i;
    comp[i].push_back(i);
    nodes[i].v = i;
  }
  int cost = 0;
  vector<int> pprev;
  while (1) {
    vector<int> prev(n, -1);
    vector<int> mcost(n, inf);
    vector<pii> edge(n);
    for (int i = 0; i < n; ++i) {
      for (int j = 0; j < n; ++j) {
        if (j == r) continue;
        if (no[i] != no[j] && g[i][j] < inf) {
          if (g[i][j] < mcost[ no[j] ]) {
            mcost[ no[j] ] = g[i][j];
            prev[ no[j] ] = no[i];
            edge[no[j]] = pii(i,j);
          }
        }
      }
    }
    pprev = prev;
    bool stop = true;
    vector<int> mark(n);
    for (int i = 0; i < n; ++i) {
      if (i == r || mark[i] || comp[i].size() == 0) continue;
      bool found = false;
      backward_traverse(i, i, r, g,
                        no, comp, prev, mcost, nodes, edge, mark, cost, found);
      if (found) stop = false;
    }
    // cout << "cost " << cost << endl;
    // REP(i,n) {
    //   REP(j,n) {
    //     cout << g[i][j] << " ";
    //   }
    //   cout << endl;
    // }
    // cout << "no: ";
    // FOR(it, no) cout << *it << " " ; cout << endl;
    // cout << "mcost: ";
    // FOR(it, mcost) cout << *it << " " ; cout << endl;
    
    // cout << "prev: ";
    // REP(i,n) cout << prev[i] << " "; cout << endl;
    // cout << "prevprev: ";
    // FOR(it, prevprev) cout << *it << " "; cout << endl;
    // cout << endl;
    // nodes[1].print(); cout << endl;
    if (stop) {
      int cnt = 0;
      REP(i,n) {
        if (prev[i] >= 0) {
          nodes[i].connect(edges, edge[i].second);
          // nodes[i].print();
          // cout << " " << edge[i].first << " " << edge[i].second <<endl;
          edges.push_back(pii(edge[i].first, edge[i].second));
          cost += mcost[i];
        }
        if (prev[no[i]] < 0) cnt++;
      }
      // FOR(it, edges) {
      //   cout << it->first << " " << it->second << endl;
      // }
      if (cnt != 1) return -1;
      return cost;
    }
  }
}

struct Edge {
  int src, dst;
  int weight;
  Edge(int src, int dst, int weight) :
    src(src),dst(dst),weight(weight) {}
  bool operator<(const Edge &rhs) const {
    return weight > rhs.weight;
  }
};
typedef vector<Edge> Edges;
typedef vector<Edges> Graph;

vector<int> dijkstra(const Graph &g, int s, vector<int> &prev) {
  int n = g.size();
  vector<int> dist(n,inf);
  dist[s] = 0;
  prev.assign(n, -1);
  priority_queue<Edge> Q; // "e < f" <=> "e.weight > f.weight"
  for (Q.push(Edge(-2, s, 0)); !Q.empty(); ) {
    Edge e = Q.top(); Q.pop();
    if (prev[e.dst] != -1) continue;
    prev[e.dst] = e.src;
    FOR(f,g[e.dst]) {
      if (dist[f->dst] > e.weight+f->weight) {
        dist[f->dst] = e.weight+f->weight;
        Q.push(Edge(f->src, f->dst, e.weight+f->weight));
      }
    }
  }
  return dist;
}

vector<int> buildPath(const vector<int> &prev, int t) {
  vector<int> path;
  for (int u = t; u >= 0; u = prev[u])
    path.push_back(u);
  reverse(ALL(path));
  return path;
}

string name[100];
int m[100];
int sum[100];
pii p[100000];

vector<int> dprev[100];

string tostr(pii a) {
  stringstream ss;
  ss << name[a.first] << " " << a.second;
  return ss.str();
}

int main() {
  int n;
  while(cin >> n) {
    sum[0] = 0;
    int N = 0;
    map<string, int > mp;
    for (int i=0; i<n; ++i) {
      cin >>name[i] >> m[i];
      sum[i+1] = sum[i] + m[i];
      mp[name[i]] = i;
      N += m[i];
    }
    int cnt = 0;
    for (int i=0; i<n; ++i) {
      for (int j=0; j<m[i]; ++j) {
        p[cnt++] = pii(i,j);
      }
    }
    int E;
    cin >> E;
    Graph g(N);
    for(int i=0; i<E; ++i) {
      string cs1,cs2;
      int v1,v2,c;
      cin >> cs1>>v1>>cs2>>v2>>c;
      int c1 = mp[cs1];
      int c2 = mp[cs2];
      int a = sum[c1] + v1;
      int b = sum[c2] + v2;
      g[a].push_back(Edge(a,b,c));
    }
    matrix mat(n,vector<int>(n));
    vector<int> prev;
    for (int i=0; i<n ;++i) {
      vector<int> dist = dijkstra(g, sum[i], dprev[i]);
      // FOR(it, dprev[i]) cout << "*" << *it; cout << endl;
      for (int j=0; j<n; ++j) {
        mat[i][j] = dist[sum[j]];
      }
    }
    // for (int i=0; i<n; ++i) {
    //   for (int j=0;j<n; ++j) {
    //     cout << mat[i][j] << " ";
    //   }
    //   cout << endl;
    // }
    int Q;
    cin >> Q;
    for (int i=0; i<Q; ++i) {
      string cs3;
      int v3;
      cin >> cs3 >> v3;
      int c3 = mp[cs3];
      int a = sum[c3] + v3;
      vector<int> dist = dijkstra(g, a, prev);
      bool ng = 0;
      REP(i,n) {
        if (dist[sum[i]] == inf) {
          ng = 1;
        }
      }
      if (ng) {
        cout << "Impossible" << endl;
      } else {
        int res = dist[sum[c3]];
        vector<pii> edges;
        int tmpres = minimum_spanning_arborescence(c3, mat, edges);
        int ans = res + tmpres;

        if (res == inf || tmpres < 0)  {
          assert(0);
        } else {
          cout << ans << endl;
          vector<int> path = buildPath(prev, sum[c3]);
          set<pii> ST; int cnt = 0;
          REP(i,path.size()-1) {
            ST.insert(pii(path[i], path[i+1])); cnt++;
            // cout << tostr(p[path[i]]) << " " << tostr(p[path[i+1]]) << endl;
          }
          assert(edges.size() == n-1);
          set<int> S;
          FOR(it, edges) S.insert(it->second);
          assert(S.size() == n-1);
          FOR(it, edges) {
            int a = it->second;
            int b = it->first;
            int A = sum[a];

            vector<int> path = buildPath(dprev[b], A);
            REP(i,path.size()-1) {
              ST.insert(pii(path[i], path[i+1])); cnt++;
              // cout << tostr(p[path[i]]) << " " << tostr(p[path[i+1]]) << endl;
            }
          }
          FOR(it, ST) {
            cout << tostr(p[it->first]) << " " << tostr(p[it->second]) << endl;
          }
        }
      }
      puts("-----");
    }
  }
}

```