#include using namespace std; #define rep(i,a,b) for(auto i = (a); i < (b); i++) #define pb push_back #define fs first #define sc second typedef long long ll; typedef pair ii; typedef vector vi; typedef vector vvi; typedef vector vii; typedef vector vvii; const double EPS = 1e-9; int n,w; vector WORDS; int line_count = 0; vi memo; vi SOL; int dp(int at) { if(at >= n) return 0; if(memo[at] != -1) return memo[at];; // what should the length be int ans = INT_MAX; int mx = 0; rep(i, at, min(n, at+line_count)) { mx = max(mx, int(WORDS[i].size())); int add = (i+1 != n); ans = min(ans, dp(i+1) + mx + add); } return memo[at] = ans; } void get(int at) { if(at >= n) return; // what should the length be int mx = 0; rep(i, at, min(n, at+line_count)) { mx = max(mx, int(WORDS[i].size())); int add = (i+1 != n); if(memo[at] == dp(i+1) + mx + add) { SOL.pb(mx); get(i+1); return; } } } vi solve(int number_of_lines) { memo = vi(n+1,-1); line_count = number_of_lines; int solution = dp(0); SOL.clear(); if(solution <= w) { // find solution get(0); return SOL; } else { // return empty return {}; } } int main() { cin.sync_with_stdio(false); cin >> n >> w; WORDS = vector(n); rep(i,0,n) cin >> WORDS[i]; // number of lines int lo = 1, hi = n; int bst = 0; vi SS; while(lo <= hi) { int mid = (lo+hi)/2; vi K = solve(mid); if(K.size() == 0) { // no solution lo = mid+1; } else { bst = mid; SS = K; hi = mid-1; } } cout << bst << " " << SS.size() << endl; for(auto a : SS) cout << a << " "; cout << endl; vector> COL_1; int at = 0; rep(i,0,SS.size()) { vector T(bst); rep(j,0,bst) { string he = ""; if(at == n || WORDS[at].size() > SS[i]) { rep(z,0,SS[i]) he += " "; } else { he = WORDS[at]; rep(z,0,SS[i] - WORDS[at].size()) { he += " "; } at++; } T[j] = he; } COL_1.pb(T); } // {contest, nwerc, icpc} // programming ru rep(i,0,bst) { rep(j,0,SS.size()) { cout << COL_1[j][i] << " "; } cout << endl; } }