#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
int n,ans,dn,ddn;
char s[maxn],ss[maxn],p[maxn],pp[maxn];
bool ok1[maxn],ok2[maxn];
struct duan{
	int l,r,a,b;
}d[maxn],dd[maxn];
int bijiao(int pl1,int pl2){
	int l1=maxn,l2=maxn,r1=maxn,r2=maxn;
	if(pl1<=dn)l1=d[pl1].l,r1=d[pl1].r;
	if(pl2<=ddn)l2=dd[pl2].l,r2=dd[pl2].r;
	if(l1==l2&&r1==r2)return 0;
	if(r2==r1){
		if(l1<l2)return 1;
		else return -1;
	}
	else{
		if(r1<r2)return 1;
		else return -1;
	}
}
int main()
{
	freopen("edit.in","r",stdin);
	freopen("edit.out","w",stdout);
	ios::sync_with_stdio(0);
	cin.tie(0);cout.tie(0);
	int t;cin>>t;
	while(t--){
		ans=0;
		cin>>n; cin>>s+1; cin>>ss+1; cin>>p+1; cin>>pp+1;
		int tmp=0;
		for(int i=1;i<=n;i++){
			if(p[i]=='1'){
				if(tmp==0) tmp=i;
				else{
					ok1[i]=1;
					if(i==tmp+1){
						++dn;d[dn].l=tmp;
						if(s[tmp]=='1') d[dn].a++;
						else d[dn].b++;
					}d[dn].r=i;
					if(s[i]=='1') d[dn].a++;
					else d[dn].b++;
				}
			}
			else tmp=0;
		}tmp=0;
		for(int i=1;i<=n;i++){
			if(pp[i]=='1'){
				if(tmp==0) tmp=i;
				else{
					ok2[i]=1;
					if(i==tmp+1){
						++ddn;dd[ddn].l=tmp;
						if(ss[tmp]=='1') dd[ddn].a++;
						else dd[ddn].b++;
					}dd[ddn].r=i;
					if(ss[i]=='1') dd[ddn].a++;
					else dd[ddn].b++;
				}
			}
			else tmp=0;
		}
		int pl1=1,pl2=1;
		while(pl1<=dn||pl2<=ddn){
			int l1=maxn,l2=maxn,r1=maxn,r2=maxn;
			if(pl1<=dn)l1=d[pl1].l,r1=d[pl1].r;
			if(pl2<=ddn)l2=dd[pl2].l,r2=dd[pl2].r;
			int asdf=bijiao(pl1,pl2);
			if(asdf==1||asdf==0){
				bool flag=1;//用来判断是不是整一段都是一种数字
				if(d[pl1].a&&d[pl1].b)flag=0; 
				for(int i=l1;i<=r1;i++){
					if(d[pl1].a==0||d[pl1].b==0){
						while(d[pl1].a>0){
							d[pl1].a--;s[i]='1';
							i++;
						}while(d[pl1].b>0){
							d[pl1].b--;s[i]='0';
							i++;
						}
					}
					if(ss[i]=='1'&&d[pl1].a>0){
						d[pl1].a--;s[i]='1';
					}if(ss[i]=='0'&&d[pl1].b>0){
						d[pl1].b--;s[i]='0';
					}
				}
				pl1++;continue;
			}if(asdf==-1){
				bool flag=1;
				if(dd[pl2].a&&dd[pl2].b)flag=0; 
				for(int i=l2;i<=r2;i++){
					if(dd[pl2].a==0||dd[pl2].b==0){
						while(dd[pl2].a>0){
							dd[pl2].a--;ss[i]='1';
							i++;
						}while(dd[pl2].b>0){
							dd[pl2].b--;ss[i]='0';
							i++;
						}
					}
					if(s[i]=='1'&&dd[pl2].a>0){
						dd[pl2].a--;ss[i]='1';
					}if(s[i]=='0'&&dd[pl2].b>0){
						dd[pl2].b--;ss[i]='0';
					}
				}
				pl2++;continue;
			}
		}
		for(int i=1;i<=n;i++){
			if(s[i]==ss[i])ans++;
		}
//		cout<<s+1<<endl;//
//		cout<<ss+1<<endl;//
		cout<<ans<<endl;
	}
}
//数组写错被硬控一个半小时，毁了 
//10:14有几组数据有出入 
//发现无用分类讨论++..... 
//already 10:27，先不管了 
//11:57还是没想到哪里出错 
//12:32甚至做不对T1，笑了 
/*
yangli:
8
5
566
7928
594
73037
900
40002
619
66647

mine:
8
5
566
7928
594
73037
894 -----900
40002
619
66525 -----66647
*/
//为什么会少呢？
/*可重排的两段之间：
1、相离
显然不会少，直接按另一个固定的数组匹配
2、包含
感觉并不会少，长串优先与短串之前的部分匹配，然后与短串匹配 
即使短串部分不有序由于实际上用的01数量不变所以也不会有影响(?)
3、相交
前方的串先与固定部分匹配，然后相当于包含情况
所以为什么会少？？？
*/
//大样例10个错2个，赌命吧 
