#include using namespace std; constexpr int N = 1e5 + 514; namespace Otakus { int n; char s1[N], s2[N], t1[N], t2[N]; struct ary { int l, r, k; // left, right, 0 or 1 (t) int one, zero; // cnt 1 && cnt 0 } a1[N], a2[N]; int len1, len2; void init() { int T; cin >> T; t1[0] = '0'; t2[0] = '0'; while (T--) { cin >> n; t1[n + 1] = '0'; t2[n + 1] = '0'; len1 = len2 = 0; for (int i = 1; i <= n; i++) { cin >> s1[i]; a1[i].l = a1[i].r = a1[i].k = a1[i].one = a1[i].zero = 0; } for (int i = 1; i <= n; i++) { cin >> s2[i]; a2[i].l = a2[i].r = a2[i].k = a2[i].one = a2[i].zero = 0; } for (int i = 1; i <= n; i++) cin >> t1[i]; for (int i = 1; i <= n; i++) cin >> t2[i]; for (int i = 1; i <= n; i++) { if (t1[i] == '1' && (t1[i - 1] == '0' && t1[i + 1] == '0')) t1[i] = '0'; if (t2[i] == '1' && (t2[i - 1] == '0' && t2[i + 1] == '0')) t2[i] = '0'; } for (int i = 1; i <= n; i++) { if (t1[i] == '0') { ++len1; a1[len1].l = a1[len1].r = i; a1[len1].k = 0; if (s1[i] == '1') a1[len1].one = 1; else a1[len1].zero = 1; } else { if (t1[i - 1] == '1') { a1[len1].r++; if (s1[i] == '1') a1[len1].one++; else a1[len1].zero++; } else { ++len1; a1[len1].l = a1[len1].r = i; a1[len1].k = 1; if (s1[i] == '1') a1[len1].one = 1; else a1[len1].zero = 1; } } if (t2[i] == '0') { ++len2; a2[len2].l = a2[len2].r = i; a2[len2].k = 0; if (s2[i] == '1') a2[len2].one = 1; else a2[len2].zero = 1; } else { if (t2[i - 1] == '1') { a2[len2].r++; if (s2[i] == '1') a2[len2].one++; else a2[len2].zero++; } else { ++len2; a2[len2].l = a2[len2].r = i; a2[len2].k = 1; if (s2[i] == '1') a2[len2].one = 1; else a2[len2].zero = 1; } } } int i = 1, j = 1, ans = 0; while (i <= len1 && j <= len2) { if (a1[i].k == 1 && a2[j].k == 1) { int tmp1 = min(a1[i].one, a2[j].one); int tmp0 = min(a1[i].zero, a2[j].zero); ans += tmp1 + tmp0; a1[i].one -= tmp1; a2[j].one -= tmp1; a1[i].zero -= tmp0; a2[j].zero -= tmp0; if (a1[i].r < a2[j].r) { /* if (tmp1 + tmp0 < a1[i].r - a1[i].l + 1) { a2[j].one -= a1[i].zero; a2[j].one = max(a2[j].one, 0); a2[j].zero -= a1[i].one; a2[j].zero = max(a2[j].zero, 0); } */ if (a1[i].one) a2[j].zero -= a1[i].one; if (a1[i].zero) a2[j].one -= a1[i].zero; a2[j].l = a1[i].r + 1; i++; } else if (a1[i].r > a2[j].r) { /* if (tmp1 + tmp0 < a2[j].r - a2[j].l + 1) { a1[i].one -= a2[j].zero; a1[i].one = max(a1[i].one, 0); a1[i].zero -= a2[j].one; a1[i].zero = max(a1[i].zero, 0); } */ if (a2[j].one) a1[i].zero -= a2[j].one; if (a2[j].zero) a1[i].one -= a2[j].zero; a1[i].l = a2[j].r + 1; j++; } else { // ans += min(a1[i].one, a2[j].one) + min(a1[i].zero, a2[j].zero); i++; j++; } } else if (a1[i].k == 1 && a2[j].k == 0) { if (s2[a2[j].l] == '1') { ans += min(a1[i].one, 1); if (min(a1[i].one, 1) == 0) a1[i].zero--; a1[i].one -= min(a1[i].one, 1); } else { ans += min(a1[i].zero, 1); if (min(a1[i].zero, 1) == 0) a1[i].one--; a1[i].zero -= min(a1[i].zero, 1); } a1[i].l = a2[j].r + 1; if (a1[i].l > a1[i].r) i++; j++; } else if (a1[i].k == 0 && a2[j].k == 1) { if (s1[a1[i].l] == '1') { ans += min(a2[j].one, 1); if (min(a2[j].one, 1) == 0) a2[j].zero--; a2[j].one -= min(a2[j].one, 1); } else { ans += min(a2[j].zero, 1); if (min(a2[j].zero, 1) == 0) a2[j].one--; a2[j].zero -= min(a2[j].zero, 1); } a2[j].l = a1[i].r + 1; if (a2[j].l > a2[j].r) j++; i++; } else { ans += (s1[a1[i].l] == s2[a2[j].l]); i++; j++; } } cout << ans << '\n'; } } } int main() { freopen("edit.in", "r", stdin); freopen("edit.out", "w", stdout); Otakus::init(); return 0; } // for 2h I'm ready to AFO