1 #include <iostream>
2 #include <cstdio>
3 #include <fstream>
4 #include <algorithm>
5 #include <cmath>
6 #include <deque>
7 #include <vector>
8 #include <queue>
9 #include <string>
10 #include <cstring>
11 #include <map>
12 #include <stack>
13 #include <set>
14 #define INF 0x3f3f3f3f
15 #define OPEN_FILE
16 #define MAXN 626
17 using namespace std;
18
19 int n;
20 int win[MAXN], remain[MAXN][MAXN];
21 struct Edge{
22 int from, to, cap, flow;
23 //Edge(int u, int v, int c, int f) :from(u), to(v), cap(c), flow(f){};
24 };
25 bool comp(const Edge& a, const Edge& b){
26 return (a.from < b.from || (a.from == b.from && a.to < b.to));
27 }
28 struct Dinic{
29 int n, m, i, s, t;
30 Edge e;
31 vector<Edge> edges;
32 vector<int> G[MAXN];
33 int d[MAXN], cur[MAXN];
34 bool vis[MAXN];
35 void init(int n){
36 this->n = n;
37 for (i = 0; i <= n; i++){
38 G[i].clear();
39 }
40 edges.clear();
41 }
42 void AddEdge(int from, int to, int cap){
43 edges.push_back(Edge{ from, to, cap, 0 });
44 edges.push_back(Edge{ to, from, 0, 0 });
45 m = edges.size();
46 G[from].push_back(m - 2);
47 G[to].push_back(m - 1);
48 }
49 bool BFS(){
50 memset(vis, 0, sizeof(vis));
51 queue<int> Q;
52 Q.push(s);
53 d[s] = 0;
54 vis[s] = 1;
55 while (!Q.empty()){
56 int x = Q.front();
57 Q.pop();
58 for (i = 0; i < G[x].size(); i++){
59 Edge& e = edges[G[x][i]];
60 if (!vis[e.to] && e.cap > e.flow){
61 vis[e.to] = true;
62 d[e.to] = d[x] + 1;
63 Q.push(e.to);
64 }
65 }
66 }
67 return vis[t];
68 }
69 int DFS(int x, int a){
70 if (x == t || a == 0) return a;
71 int flow = 0, f;
72 for (int& i = cur[x]; i < G[x].size(); i++){
73 Edge& e = edges[G[x][i]];
74 if (d[x] + 1 == d[e.to] && (f = DFS(e.to, min(a, e.cap - e.flow))) > 0){
75 e.flow += f;
76 edges[G[x][i] ^ 1].flow -= f;
77 flow += f;
78 a -= f;
79 if (a == 0) break;
80 }
81 }
82 return flow;
83 }
84 int MaxFlow(int s, int t, int need){
85 int flow = 0;
86 this->s = s;
87 this->t = t;
88 while (BFS()){
89 memset(cur, 0, sizeof(cur));
90 flow += DFS(s, INF);
91 if (flow > need) return flow;
92 }
93 return flow;
94 }
95 bool checkFull(int s){
96 for (int i = 0; i < G[s].size(); i++){
97 if (edges[G[s][i]].flow != edges[G[s][i]].cap){
98 return false;
99 }
100 }
101 return true;
102 }
103 };
104
105 int main()
106 {
107 #ifdef OPEN_FILE
108 freopen("in.txt", "r", stdin);
109 freopen("out.txt", "w", stdout);
110 #endif // OPEN_FILE
111 int T, x;
112 scanf("%d", &T);
113 for (int cas = 1; cas <= T; cas++){
114 scanf("%d", &n);
115 memset(win, 0, sizeof(win));
116 for (int i = 1; i <= n; i++){
117 scanf("%d%d", &win[i], &x);
118 }
119 memset(remain, 0, sizeof(remain));
120 int p = 0;
121 for (int i = 1; i <= n; i++){
122 for (int j = 1; j <= n; j++){
123 scanf("%d", &x);
124 if (i == j) continue;
125 remain[i][0] += x;
126 if (remain[i][j] == 0 && remain[j][i] == 0){
127 remain[i][j] = x;
128 ++p;
129 }
130 }
131 }
132 int s = 0, t = n + p + 1, q;
133 bool flag, first;
134 Dinic ex;
135 first = false;
136 for (int k = 1; k <= n; k++){
137 ex.init(n * n);
138 flag = false;
139 q = 1;
140 int total = win[k] + remain[k][0];
141 for (int i = 1; i <= n; i++){
142 for (int j = i + 1; j <= n; j++){
143 if (!remain[i][j]) continue;
144 ex.AddEdge(s, q, remain[i][j]);
145 ex.AddEdge(q, p + i, INF);
146 ex.AddEdge(q, p + j, INF);
147 q++;
148 }
149 if (total - win[i] < 0) {
150 flag = true;
151 break;
152 }
153 ex.AddEdge(p + i, t, total - win[i]);
154 }
155 if (flag){
156 continue;
157 }
158 ex.MaxFlow(s, t, INF);
159 if (ex.checkFull(0)){
160 if (first){
161 printf(" ");
162 }
163 printf("%d", k);
164 first = true;
165 }
166 }
167 printf("\n");
168 }
169 }