#include #define endl '\n' #include #include using namespace std; #include #include using namespace __gnu_pbds; #define ordered_set tree< pair < int, int > , null_type,less< pair < int, int > >, rb_tree_tag,tree_order_statistics_node_update> const int MAXN = 1e4 + 10; void speed() { ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); } int n, m; int cost[MAXN]; vector < pair < int, int > > g; vector < int > onset[MAXN], u[MAXN]; map < pair< int, int >, int > act; long long ss; int used[MAXN]; void read() { cin >> n >> m; for (int i = 1; i <= n; ++ i) { cin >> cost[i]; g.push_back(make_pair(-cost[i], i)); } sort(g.begin(), g.end()); for (int i = 1; i <= m; ++ i) { int cnt; cin >> cnt; ss += cnt; while(cnt --) { int x; cin >> x; act[make_pair(i, x)] = 1; onset[i].push_back(x); u[x].push_back(i); } } } vector < int > scenes; vector < int > colour[MAXN]; int ffixed[MAXN]; mt19937 mt; unordered_map < int, pair < int, int > > vals; void solve() { int round = 0; vector < int > passed; for (auto &[c, i]: g) { int change = 0; round ++; c = -c; /*for (auto x: scenes) { if(round-1 != 0 && used[x] == round-1 && act[make_pair(x, i)]) { to_add.push_back(x); } else newv.push_back(x); }*/ if(m <= 500 && n <= 500) { change = 1; for (int r = 1; r < round; ++ r) { vector < int > newc; vector < int > addto; int flag = 0; for (auto x: colour[r]) { if(ffixed[x] == 1 || flag) { flag = 1; addto.push_back(x); } else if(act[make_pair(x, i)]) { ffixed[x] = 1; addto.push_back(x); } else newc.push_back(x); } for (auto x: addto) newc.push_back(x); colour[r] = newc; } } for(auto s: u[i]) { if(!used[s]) { scenes.push_back(s); colour[round].push_back(s); used[s] = round; } } passed.push_back(i); if(change) { scenes.clear(); for (int r = 1; r <= round; ++ r) { for (auto x: colour[r]) scenes.push_back(x); } } } round ++; for (int i = 1; i <= m; ++ i) { if(used[i])continue; used[i] = round; scenes.push_back(i); } } int nomer[MAXN]; long long find_answer(vector < int > &scenes) { int id = -1; for (auto x: scenes) { id ++; nomer[x] = id; } long long ans = 0; for (int i = 1; i <= n; ++ i) { int minx = -1, maxx = -1; for (auto s: u[i]) { if(maxx == -1) { minx = nomer[s]; maxx = nomer[s]; } else { minx = min(minx, nomer[s]); maxx = max(maxx, nomer[s]); } } ans += (maxx - minx + 1) * cost[i]; } return ans; } ordered_set s; void betteroff() { if(ss >= 5e4)return; /*if(ss >= 5e4) { int i, j; long long pre = find_answer(scenes); while((clock()/CLOCKS_PER_SEC < 3)) { i = mt() % m; j = mt() % m; if(i == j)continue; swap(scenes[i], scenes[j]); long long currv = find_answer(scenes); if(currv < pre) { pre = currv; } else swap(scenes[i], scenes[j]); } return; }*/ while((clock()/CLOCKS_PER_SEC < 4) && s.size() == 0) { for (int i = 0; i < m; ++ i) { for (int j = 0; j < m; ++ j) s.insert(make_pair(i, j)); } int i, j; long long pre = find_answer(scenes); while(s.size() && (clock()/CLOCKS_PER_SEC < 4.5)) { int plain = s.size(); int no = mt() % plain; pair < int, int > curr = *s.find_by_order(no); s.erase(curr); i = curr.first; j = curr.second; if(i == j)continue; swap(scenes[i], scenes[j]); long long currv = find_answer(scenes); if(currv < pre) { pre = currv; } else swap(scenes[i], scenes[j]); } } //cout << find_answer(scenes) << endl; } int main() { #ifdef ONLINE_JUDGE freopen("star.in", "r", stdin); freopen("star.out", "w", stdout); #endif mt.seed(time(nullptr)); speed(); read(); solve(); betteroff(); for (auto x: scenes) cout << x << " "; cout << endl; return 0; }