// https://szkopul.edu.pl/problemset/problem/-wqX-o_o75CVLx7xCqeuZSRq/site/?key=statement
#include <bits/stdc++.h>
// Nasycanie makrofanów
// using namespace std;
// #define GARY_DBG
#define GARY_LIB
// #define int long long
// constexpr int sizik = 1000 * 1001;
constexpr int sizik = 146, sizik2 = 20, NEE = 88888;
#define ar std::array
#define pr std::pair
#define vec std::vector
typedef vec<vec<int>> _kra;
bool isDigit(char c) {
return '0' <= c && c <= '9';
}
int getDigit(char c) {
return c - '0';
}
bool isMinus(char c) {
return c == '-';
}
std::vector<int> kra[sizik];
int path_compr[sizik][sizik2];
using TTT = ar<int, 4>;
struct cmp {
_GLIBCXX14_CONSTEXPR
bool operator()(const TTT& __x, const TTT& __y) const {
if (__x[3] > __y[3]) {
return true;
} else if (__x[3] == __y[3]) {
if (__x[0] > __y[0])
return true;
else if (__x[0] == __y[0]) {
return __x[1] > __y[1];
} else {
return false;
}
} else {
return false;
}
}
};
void solve() {
int n;
std::cin >> n;
std::string s;
std::getline(std::cin, s);
for (int i = 0; i < n; i++) {
std::getline(std::cin, s);
int mult = 1;
for (const auto& c : s) {
if (isMinus(c)) {
mult = -1;
continue;
}
if (!isDigit(c)) {
mult = 1;
continue;
}
int x = mult * getDigit(c);
// dodaj krawędź
kra[i].push_back(x);
}
}
// run dijkstra
for (int i = 0; i <= 19; i++) {
// std::cout << "temperatura: " << i << std::endl;
for (int k = 0; k < sizik; k++) {
for (int j = 0; j < sizik2; j++) {
path_compr[k][j] = -1;
}
}
// początkowa temperatura po znormalizowaniu jest równa i stopni (nie-Celsjusza)
// załóżmy: [akt_ziomek, akt_temp, prev_temp]
std::priority_queue<TTT, vec<TTT>, cmp> q;
q.push({0, i, i, 0});
// std::cout << "przed while " << std::endl;
int pierwszy = NEE, drugi = NEE;
while (!q.empty()) {
auto [akt_ziomek, akt_temp, prev_temp, koszt] = q.top();
q.pop();
if (!(0 <= akt_temp && akt_temp <= 19)) {
continue;
}
if (path_compr[akt_ziomek][akt_temp] != -1) {
continue;
}
path_compr[akt_ziomek][akt_temp] = prev_temp;
//
// if (abs(akt_temp - prev_temp) > 3) std::cout << "akt_temp: " << akt_temp << " | prev_temp" << prev_temp << std::endl;
if (akt_ziomek == n) {
if (pierwszy > koszt) {
pierwszy = koszt;
drugi = akt_temp;
}
continue;
}
for (const auto& x : kra[akt_ziomek]) {
q.push({akt_ziomek + 1, akt_temp + x, akt_temp, koszt + abs(x)});
}
}
// std::cout << "PO while " << std::endl;
// bool isGood = false;
// int init_temp = -1;
// for (int j = 0; j < sizik2; j++) {
// if (path_compr[n][j] != -1) {
// isGood = true;
// init_temp = j;
// }
// }
bool isGood = pierwszy != NEE;
int init_temp = drugi;
// std::cout << "HERE GOOD " << std::endl;
// std::cout << "p: " << pierwszy << " " << drugi << " " << isGood << std::endl;
// std::cout << "isGood: " << (int)isGood << std::endl;
if (!isGood) {
std::cout << "NIE\n";
} else {
std::vector<int> ans;
for (int j = n; j >= 1; j--) {
int t = init_temp - path_compr[j][init_temp];
// std::cout << "init_temp: " << init_temp << " | " << path_compr[j][init_temp] << " | t: " << t << std::endl;
ans.push_back(t);
init_temp = path_compr[j][init_temp];
}
std::reverse(ans.begin(), ans.end());
for (const auto& a : ans) {
std::cout << (int)a << " ";
}
std::cout << '\n';
// verify ans
int verify = i + 15;
for (const auto& a : ans) {
verify += a;
if (!(15 <= verify && verify <= 34)) {
std::cout << "BAD_ANS ABOVE ! WARNING " << std::endl;
}
// std::cout << "verified: " << verify << std::endl;
}
}
}
}
int32_t main() {
#ifndef GARY_DBG
std::ios_base::sync_with_stdio(0);
std::cin.tie(0);
std::cout.tie(0);
#endif
int t = 1;
// std::cin >> t;
for (; t > 0; t--) {
solve();
}
return 0;
}