#include using namespace std; #define x first #define y second #define pb push_back #define eb emplace_back #define rep(i,a,b) for(auto i = (a); i != (b); ++i) #define REP(i,n) rep(i,0,n) #define all(v) (v).begin(), (v).end() typedef long long ll; int B, K; // (a, b) \in sizes[i]: company i has a package of size a, containing at least b bolts. vector< pair > sizes[10]; const ll INF = 9e18; int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); cin >> B >> K; REP(i, K) { int len; cin >> len; sizes[i].resize(len); while (len--) cin >> sizes[i][len].x; // sort ascendingly sort(all(sizes[i])); } int ret = 2147483647; // first company is easy: for (auto &pr : sizes[0]) { pr.y = pr.x; } /* WA for missing: for (auto pr : sizes[0]) { if (pr.y >= B) ret = min(ret, pr.x); } */ for (int i = 1; i < K; i++) { // perform knapsacks int msize = sizes[i].back().x; // A[i]: minimum amount of bolts that is inside a collection consisting // of i bolts from several packages of the previous company, or INF if // not possible to make this amount. // Take the minimum because it must always work independent of selection // by the companies' packaging system. vector A(msize * 2 + 1, INF); A[0] = 0; for(auto pr : sizes[i - 1]) { for (int j = 0; j + pr.x < (int) A.size(); j++) A[j + pr.x] = min(A[j + pr.x], A[j] + pr.y); } assert(sizes[i].size() > 0); int boltsum = 0, pkg = 0; while (pkg < (int) sizes[i].size() && boltsum < (int) A.size()) { if (boltsum < sizes[i][pkg].x) boltsum = sizes[i][pkg].x; while (boltsum < (int) A.size() && A[boltsum] == INF) boltsum++; if (boltsum == (int) A.size()) { // in a range of size msize, all were INF. Thus, previous items // are bigger than now. break; } sizes[i][pkg].y = A[boltsum]; pkg++; } // ASSUMPTION: for all j, sizes[i][j] is different for (int ppkg = 0; pkg < (int) sizes[i].size() && ppkg < (int) sizes[i-1].size();) { if (sizes[i - 1][ppkg].x >= sizes[i][pkg].x) { sizes[i][pkg++].y = sizes[i - 1][ppkg].y; } else ppkg++; } assert(pkg == (int) sizes[i].size()); for(auto pr : sizes[i]) { if (pr.y >= B) ret = min(ret, pr.x); } } if (ret == 2147483647) cout << "impossible" << endl; else cout << ret << endl; return 0; }