#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include constexpr int MOD = 998244353; template class ModInt { long long int raw_value; static long long int inverse(const long long int value) { long long int x = value, y = MOD, a = 1, b = 0, c = 0, d = 1; while (y != 0) { const auto q = x / y; const auto e = a - c * q; const auto f = b - d * q; a = c; b = d; c = e; d = f; x = y; y = c * value - d * MOD; } assert(std::abs(x) == 1LL); return x == 1 ? a % MOD : -a % MOD; } public: ModInt() : raw_value{ 0 } {}; ModInt(const int value) : raw_value{ value } {}; ModInt(const long long int value) : raw_value{ value % MOD } {}; ModInt operator+(const ModInt right) const { return raw_value + right.raw_value; } ModInt& operator+=(const ModInt right) { return *this = *this + right; } ModInt operator-(const ModInt right) const { return raw_value - right.raw_value; } ModInt& operator-=(const ModInt right) { return *this = *this - right; } ModInt operator*(const ModInt right) const { return raw_value * right.raw_value; } ModInt& operator*=(const ModInt right) const { return *this = *this * right; } ModInt operator/(const ModInt right) const { return raw_value * inverse(right.raw_value); } ModInt operator/=(const ModInt right) { return *this = *this / right; } ModInt pow(long long int exp) const { ModInt result(1), base{ *this }; while (exp > 0) { if ((exp & 1) == 1) { result *= base; } base *= base; exp >>= 1; } return result; } long long int value() const { return (raw_value + MOD) % MOD; } }; template std::ostream& operator<<(std::ostream& os, const ModInt& mint) { return os << (mint.value() + MOD) % MOD; } template class Matrix { std::vector> vec; int _row, _column; public: int row() const { return _row; } int column() const { return _column; } static Matrix E(const int size) { Matrix result(size, size); for (auto i = 0; i < size; ++i) { result[i][i] = 1; } return result; } Matrix(const int row, const int column) : vec(row, std::vector(column)), _row{ row }, _column{ column } {}; Matrix(Matrix&& other) = default; Matrix(const Matrix & other) = default; Matrix& operator=(Matrix &&other) = default; Matrix& operator=(const Matrix & other) = default; const std::vector& operator[](const int index) const { return vec[index]; } std::vector& operator[](const int index) { return vec[index]; } Matrix operator*(const Matrix& right) const { const int row = this->row(); const int mid = this->column(); const int column = right.column(); Matrix result(row, column); for (auto i = 0; i < row; ++i) { for (auto j = 0; j < column; ++j) { T value = vec[i][0] * right.vec[0][j]; for (auto k = 1; k < mid; ++k) { value += vec[i][k] * right.vec[k][j]; } result[i][j] = value; } } return result; } Matrix& operator*=(const Matrix& right) { return *this = *this * right; } Matrix pow(long long int exp) const { auto result = Matrix::E(row()); auto base = *this; while (exp > 0) { if ((exp & 1) == 1) { result *= base; } base *= base; exp >>= 1; } return result; } }; template std::ostream& operator<<(std::ostream& os, const Matrix& matrix) { for (auto i = 0; i < matrix.row(); ++i) { os << '['; for (auto j = 0; j < matrix.column(); ++j) { if (j > 0) { os << ", "; } os << matrix[i][j]; } os << "]\n"; } return os; } Matrix> make_matrix(const int size) { const int half = size / 2; Matrix> result(half + 1, half + 1); for (auto i = 0; i <= half; ++i) { if (0 <= i - 1) { result[i][i - 1] = (half - i + 1) * (half - i + 1); } result[i][i] = (half - i) * (half - i - 1) + i * (i - 1) + 2 * (size - 2 * i) * i; if (i + 1 <= half) { result[i][i + 1] = (i + 1) * (i + 1); } } return result; } template std::ostream& operator<<(std::ostream& os, const std::vector& vec) { os << "["; for (auto i = 0; i < vec.size(); ++i) { if (i > 0) { os << ", "; } os << vec[i]; } return os << "]"; } int main() { std::string str; std::cin >> str; int k; std::cin >> k; const int size = str.size(); const int half = size / 2; std::vector>>> memo(size + 1, std::vector>>(half + 1, std::vector>(half + 1))); memo[0][0][0] = 1; for (auto i = 0; i < size; ++i) { const auto c = str[i]; for (auto height = 0; height <= half; ++height) { for (auto to_right = 0; to_right <= half; ++to_right) { if (c == '(') { ModInt pattern{ 0 }; if (0 <= height - 1) { pattern += memo[i][height - 1][to_right]; } if (height + 1 <= half && 0 < to_right) { pattern += memo[i][height + 1][to_right - 1]; } memo[i + 1][height][to_right] = pattern; } else { ModInt pattern{ 0 }; if (height + 1 <= half) { pattern += memo[i][height + 1][to_right]; } if (0 <= height - 1) { pattern += memo[i][height - 1][to_right]; } memo[i + 1][height][to_right] = pattern; } } } } const auto matrix = make_matrix(size).pow(k); ModInt result{ 0 }; for (auto to_right = 0; to_right <= half; ++to_right) { result += matrix[0][to_right] * memo[size][0][to_right]; } std::cout << result << '\n'; }