#include "bits/stdc++.h"
using namespace std;
#ifdef LOCAL
#include "debug.h"
#else
#define debug(x...)
#endif
#define int long long
constexpr int MOD1 = 1e9 + 7;
constexpr int MOD2 = 1e9 + 9;
constexpr int k1 = 223;
constexpr int k2 = 309;
inline int md1(long long n) {
n %= MOD1;
if (n < 0) {
n += MOD1;
}
return n;
}
inline int md2(long long n) {
n %= MOD2;
if (n < 0) {
n += MOD2;
}
return n;
}
void solve() {
vector<int> p1(100000), p2(100000);
p1[0] = 1;
p2[0] = 1;
for (int i = 1; i < 100000; i++) {
p1[i] = md1(p1[i - 1] * k1);
p2[i] = md2(p2[i - 1] * k2);
}
int n, m;
cin >> n >> m;
vector<int> A(n), B(m);
for (int &i : A) {
cin >> i;
}
for (int &i : B) {
cin >> i;
}
vector<int> rA = A, rB = B;
reverse(rA.begin(), rA.end());
reverse(rB.begin(), rB.end());
vector<pair<int, int>> hashA(n + 1), hashrA(n + 1), hashB(m + 1), hashrB(m + 1);
for (int i = n - 1; i >= 0; i--) {
hashA[i] = {md1(hashA[i + 1].first * k1 + A[i]), md2(hashA[i + 1].second * k2 + A[i])};
hashrA[i] = {md1(hashrA[i + 1].first * k1 + rA[i]), md2(hashrA[i + 1].second * k2 + rA[i])};
}
for (int i = m - 1; i >= 0; i--) {
hashB[i] = {md1(hashB[i + 1].first * k1 + B[i]), md2(hashB[i + 1].second * k2 + B[i])};
hashrB[i] = {md1(hashrB[i + 1].first * k1 + rB[i]), md2(hashrB[i + 1].second * k2 + rB[i])};
}
auto getA = [&](int l, int r) -> pair<int, int> {
return {md1(hashA[l].first - md1(hashA[r + 1].first * p1[r - l + 1])), md2(hashA[l].second - md2(hashA[r + 1].second * p2[r - l + 1]))};
};
auto getB = [&](int l, int r) -> pair<int, int> {
return {md1(hashB[l].first - md1(hashB[r + 1].first * p1[r - l + 1])), md2(hashB[l].second - md2(hashB[r + 1].second * p2[r - l + 1]))};
};
auto getrA = [&](int l, int r) -> pair<int, int> {
return {md1(hashrA[l].first - md1(hashrA[r + 1].first * p1[r - l + 1])), md2(hashrA[l].second - md2(hashrA[r + 1].second * p2[r - l + 1]))};
};
auto getrB = [&](int l, int r) -> pair<int, int> {
return {md1(hashrB[l].first - md1(hashrB[r + 1].first * p1[r - l + 1])), md2(hashrB[l].second - md2(hashrB[r + 1].second * p2[r - l + 1]))};
};
auto can = [&](int len) -> bool {
int half = len / 2;
if (len % 2 == 1) {
vector<pair<int, int>> S;
for (int i = half; i < n - half; i++) {
pair<int, int> get = getA(i - half, i), getr = getrA(n - i - half - 1, n - i - 1);
S.emplace_back(md1(get.first - getr.first), md2(get.second - getr.second));
}
sort(S.begin(), S.end());
for (int i = half; i < m - half; i++) {
pair<int, int> get = getB(i - half, i), getr = getrB(m - i - half - 1, m - i - 1);
if (binary_search(S.begin(), S.end(), make_pair(md1(getr.first - get.first), md2(getr.second - get.second)))) {
return true;
}
}
} else {
vector<pair<int, int>> S;
for (int i = half - 1; i < n - half; i++) {
pair<int, int> get = getA(i - half + 1, i), getr = getrA(n - i - half - 1, n - i - 2);
S.emplace_back(md1(get.first - getr.first), md2(get.second - getr.second));
}
sort(S.begin(), S.end());
for (int i = half - 1; i < m - half; i++) {
pair<int, int> get = getB(i - half + 1, i), getr = getrB(m - i - half - 1, m - i - 2);
if (binary_search(S.begin(), S.end(), make_pair(md1(getr.first - get.first), md2(getr.second - get.second)))) {
return true;
}
}
}
return false;
};
// odd
int L = 0, R = min(n, m);
while (L + 1 != R) {
int M = (L + R) / 2;
if (M * 2 + 1 > min(n, m)) {
R = M;
continue;
}
if (can(M * 2 + 1)) {
L = M;
} else {
R = M;
}
}
// even
int L1 = 0, R1 = min(n, m);
while (L1 + 1 != R1) {
int M = (L1 + R1) / 2;
if (M * 2 > min(n, m)) {
R1 = M;
continue;
}
if (can(M * 2)) {
L1 = M;
} else {
R1 = M;
}
}
cout << max(L * 2 + 1, L1 * 2);
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(NULL);
int tests = 1;
// cin >> tests;
while (tests--) {
solve();
}
return 0;
}