During military training, csy immortals didn't take a look at the fairy question that fell out in seconds(
Breakthrough: for a sequence with a difference of \ (\ pm 1 \) between two adjacent numbers, the longest ascending subsequence must be an equal difference sequence with a tolerance of \ (1 \). Because assuming that there are two adjacent elements \ (x,y \) of the longest ascending subsequence and meet \ (y-x\ge 2 \), since the number difference between the two adjacent elements in the sequence can only be \ (\ pm 1 \), there must be a position between them with a value equal to \ (x+1 \), selecting this element will certainly make the LIS length longer.
Therefore, for the first question, it is obvious that the two endpoints of the longest ascending subsequence will be taken at the beginning and end of a certain paragraph. Therefore, if we find the number \ (v_i \) at the end of each paragraph, the answer to the first question is \ (1 + \ Max \ limits_{I < j}v_j-v_i \).
Next, consider the second question, and remember that the answer to the first question is \ (mx \), so it is not difficult to find that if we arrange all the binary \ ((i,j) \) of \ (v_j-v_i, J > I \) in a column in the order of increasing \ (J \), then the \ (v_j \) of the corresponding binary must be monotonic, and if we shrink \ (v_j \) into a continuous segment, For each continuous segment, take the largest \ (J \) as the right end point \ (R_k \) of the continuous segment and the smallest of the corresponding \ (I \) as the left end point \ (L_k \), then it is not difficult to prove that any two pairs of \ ([L_k,R_k] \) do not intersect, otherwise we will certainly increase the length of LIS by combining them.
That is to say, we just need to calculate the number of increasing sequences with length of \ (mx \) for all \ ([L_k,R_k] \), and then add them up to be the answer to the second question. Note that since \ (V {R _k} - V {L _k} = mx \), the value of LIS in this interval can only be \ (\ {V {L _k}, V {L _k} + 1, \ cdots, V {R _k} \} \), so consider transferring with LIS value as the state. Let \ (DP {I, j} \) indicate that the position of \ (V {L _k} \ SIM I \) in the sequence is determined. The number of schemes currently in the \ (j \) segment can be transferred by enumerating the segment in which \ (i+1 \) is in the sequence. Direct transfer will explode, but according to the conditions and equations of DP transfer, it is not difficult to find that \ (V {L _k} \ SIM V {R _k} \) can be divided into \ (\ mathcal O(R_k-L_k+1) \) segments. If the transfer equations in this segment are the same, matrix fast power optimization can be used, and the complexity is \ (n^4\log v \).
const int MAXN = 50; const int MOD = 998244353; const ll INF = 1e18; int n, m, a[MAXN + 5], b[MAXN + 5], res; ll sum[MAXN + 5], mx = 0; struct mat { int v[MAXN + 5][MAXN + 5]; mat() {memset(v, 0, sizeof(v));} mat operator * (const mat &rhs) { mat res; for (int i = 1; i <= m; i++) for (int j = 1; j <= m; j++) for (int k = 1; k <= m; k++) res.v[i][j] = (res.v[i][j] + 1ll * v[i][k] * rhs.v[k][j]) % MOD; return res; } }; int calc(int l, int r) { // printf("calc %d %d\n", l, r); m = r - l + 1; static ll key[MAXN * 2 + 5], uni[MAXN * 2 + 5]; int cnt = 0, num = 0; for (int i = l + 1; i <= r; i++) { ll L = sum[i - 1] + ((a[i] > 0) ? 1 : -1), R = sum[i]; if (L > R) swap(L, R); if (L - 1 >= sum[l]) key[++cnt] = L - 1; key[++cnt] = R; } sort(key + 1, key + cnt + 1); key[0] = -INF; for (int i = 1; i <= cnt; i++) if (key[i] != key[i - 1]) uni[++num] = key[i]; mat prd; for (int i = l; i <= r; i++) if (sum[i] == sum[l]) prd.v[1][i - l + 1] = 1; for (int i = 2; i <= num; i++) { mat trs; vector<int> vec; for (int j = l + 1; j <= r; j++) { ll L = sum[j - 1] + ((a[j] > 0) ? 1 : -1), R = sum[j]; if (L > R) swap(L, R); if (L <= uni[i] && uni[i] <= R) vec.pb(j); } for (int id : vec) for (int j = l; j < id; j++) trs.v[j - l + 1][id - l + 1] = 1; for (int id : vec) if (a[id] > 0) trs.v[id - l + 1][id - l + 1] = 1; // printf("itvl %d [%lld, %lld]\n", i, uni[i - 1] + 1, uni[i]); // for (int j = 1; j <= m; j++) for (int k = 1; k <= m; k++) // printf("%d%c", trs.v[j][k], " \n"[k == m]); ll len = uni[i] - uni[i - 1]; for (; len; len >>= 1, trs = trs * trs) if (len & 1) prd = prd * trs; // printf("curdp: "); // for (int j = 1; j <= m; j++) printf("%d%c", prd.v[1][j], " \n"[j == m]); } int sum = 0; for (int i = 1; i <= m; i++) sum = (sum + prd.v[1][i]) % MOD; return sum; } int main() { scanf("%d%*d", &n); for (int i = 1; i <= n; i++) scanf("%d", &a[i]); for (int ed = n, i = (n = 0) + 1; i <= ed; i++) if (a[i]) b[++n] = a[i]; swap(a, b); if (!n) return puts("1 1"), 0; for (int i = 1; i <= n; i++) sum[i] = sum[i - 1] + a[i]; bool flg = 1; for (int i = 1; i <= n; i++) flg &= (a[i] < 0); if (flg) return printf("1 %d\n", (-sum[n] + 1) % MOD), 0; for (int i = 0; i <= n; i++) for (int j = i + 1; j <= n; j++) chkmax(mx, sum[j] - sum[i]); for (int i = 0; i <= n;) { int pos = -1; for (int j = i + 1; j <= n; j++) if (sum[j] - sum[i] == mx) pos = j; if (~pos) res = (res + calc(i, pos)) % MOD, i = pos + 1; else i++; } printf("%lld %d\n", mx + 1, res); return 0; }