#include <vector>
#include <iostream>
#include <algorithm>
#include <cstring>
#define ENABLE_LCS
#define ENABLE_LIS
#define ENABLE_MAIN
#ifdef ENABLE_LCS
namespace lcs {
constexpr auto N = 50, M = 50;
int dp[N + 1][M + 1];
template <typename Iterable> int lcs(Iterable a, Iterable b) {
memset(dp, sizeof(dp), 0);
auto n = a.size();
auto m = b.size();
for (auto i = 0; i < n; ++i) for (auto j = 0; j < m; ++j) {
dp[i + 1][j + 1] = a[i] == b[j] ? dp[i][j] + 1 : std::max(dp[i][j + 1], dp[i + 1][j]);
}
return dp[n][m];
}
}
#endif
#ifdef ENABLE_LIS
namespace lis {
constexpr auto N = 50;
int INF = 2000000001;
int dp[N];
int lis(std::vector<int> a) {
auto n = a.size();
for (auto &i: dp) i = INF;
for (auto i = 0; i < n; ++i) {
*std::lower_bound(dp, dp + N, a[i]) = a[i];
}
return std::lower_bound(dp, dp + N, INF) - dp;
}
}
#endif
#ifdef ENABLE_MAIN
int main() {
std::string x = "XMJYAUZ", y = "MZJAWXU";
std::cout << lcs::lcs(x, y) << " should be 4" << std::endl;
std::vector<int> a = {0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15};
std::cout << lis::lis(a) << " should be 6" << std::endl;
return 0;
}
#endif
I2luY2x1ZGUgPHZlY3Rvcj4KI2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8YWxnb3JpdGhtPgojaW5jbHVkZSA8Y3N0cmluZz4KCiNkZWZpbmUgRU5BQkxFX0xDUwojZGVmaW5lIEVOQUJMRV9MSVMKI2RlZmluZSBFTkFCTEVfTUFJTgoKI2lmZGVmIEVOQUJMRV9MQ1MKbmFtZXNwYWNlIGxjcyB7CiAgY29uc3RleHByIGF1dG8gTiA9IDUwLCBNID0gNTA7CiAgaW50IGRwW04gKyAxXVtNICsgMV07CgogIHRlbXBsYXRlIDx0eXBlbmFtZSBJdGVyYWJsZT4gaW50IGxjcyhJdGVyYWJsZSBhLCBJdGVyYWJsZSBiKSB7CiAgICBtZW1zZXQoZHAsIHNpemVvZihkcCksIDApOwogICAgYXV0byBuID0gYS5zaXplKCk7CiAgICBhdXRvIG0gPSBiLnNpemUoKTsKICAgIGZvciAoYXV0byBpID0gMDsgaSA8IG47ICsraSkgZm9yIChhdXRvIGogPSAwOyBqIDwgbTsgKytqKSB7CiAgICAgICAgZHBbaSArIDFdW2ogKyAxXSA9IGFbaV0gPT0gYltqXSA/IGRwW2ldW2pdICsgMSA6IHN0ZDo6bWF4KGRwW2ldW2ogKyAxXSwgZHBbaSArIDFdW2pdKTsKICAgIH0KICAgIHJldHVybiBkcFtuXVttXTsKICB9Cn0KI2VuZGlmCgojaWZkZWYgRU5BQkxFX0xJUwpuYW1lc3BhY2UgbGlzIHsKICBjb25zdGV4cHIgYXV0byBOID0gNTA7CiAgaW50IElORiA9IDIwMDAwMDAwMDE7CiAgaW50IGRwW05dOwoKICBpbnQgbGlzKHN0ZDo6dmVjdG9yPGludD4gYSkgewogICAgYXV0byBuID0gYS5zaXplKCk7CiAgICBmb3IgKGF1dG8gJmk6IGRwKSBpID0gSU5GOwogICAgZm9yIChhdXRvIGkgPSAwOyBpIDwgbjsgKytpKSB7CiAgICAgICpzdGQ6Omxvd2VyX2JvdW5kKGRwLCBkcCArIE4sIGFbaV0pID0gYVtpXTsKICAgIH0KICAgIHJldHVybiBzdGQ6Omxvd2VyX2JvdW5kKGRwLCBkcCArIE4sIElORikgLSBkcDsKICB9Cn0KI2VuZGlmCgojaWZkZWYgRU5BQkxFX01BSU4KaW50IG1haW4oKSB7CiAgc3RkOjpzdHJpbmcgeCA9ICJYTUpZQVVaIiwgeSA9ICJNWkpBV1hVIjsKICBzdGQ6OmNvdXQgPDwgbGNzOjpsY3MoeCwgeSkgPDwgIiBzaG91bGQgYmUgNCIgPDwgc3RkOjplbmRsOwoKICBzdGQ6OnZlY3RvcjxpbnQ+IGEgPSB7MCwgOCwgNCwgMTIsIDIsIDEwLCA2LCAxNCwgMSwgOSwgNSwgMTMsIDMsIDExLCA3LCAxNX07CiAgc3RkOjpjb3V0IDw8IGxpczo6bGlzKGEpIDw8ICIgc2hvdWxkIGJlIDYiIDw8IHN0ZDo6ZW5kbDsKICByZXR1cm4gMDsKfQojZW5kaWY=