#include<bits/stdc++.h>
#define x0 x_0
#define x1 x_1
#define y0 y_0
#define y1 y_1
#define yn y_n
#define j0 j_0
#define j1 j_1
#define d0 d_0
#define d1 d_1
#define k0 k_0
#define k1 k_1
#define LL long long
#define LD long double
using namespace std;
struct node{
	int AND,OR,ANDp,ORp;
};
int t,n,sumt1[100010],sumt2[100010];
string s1,s2,t1,t2;
node tr1[400010],tr2[400010];
#define update update1
#define tr tr1
void update(int x,int l,int r,int pos,int data){
	if(l==r) {tr[x].AND=tr[x].OR=data,tr[x].ANDp=(data==0 ? l : -1),tr[x].ORp=(data==1 ? l : -1);return ;}
	int mid=(l+r)>>1;
	if(pos<=mid) update(x<<1,l,mid,pos,data);
	else update(x<<1|1,mid+1,r,pos,data);
	tr[x].AND=(tr[x<<1].AND&tr[x<<1|1].AND),
	tr[x].OR=(tr[x<<1].OR|tr[x<<1|1].OR);
	if(tr[x<<1].AND==0) tr[x].ANDp=tr[x<<1].ANDp;
	else tr[x].ANDp=tr[x<<1|1].ANDp;
	if(tr[x<<1].OR==1) tr[x].ORp=tr[x<<1].ORp;
	else tr[x].ORp=tr[x<<1|1].ORp;
	return ;
}
#undef update
#undef tr
#define update update2
#define tr tr2
void update(int x,int l,int r,int pos,int data){
	if(l==r) {tr[x].AND=tr[x].OR=data,tr[x].ANDp=(data==0 ? l : -1),tr[x].ORp=(data==1 ? l : -1);return ;}
	int mid=(l+r)>>1;
	if(pos<=mid) update(x<<1,l,mid,pos,data);
	else update(x<<1|1,mid+1,r,pos,data);
	tr[x].AND=(tr[x<<1].AND&tr[x<<1|1].AND),
	tr[x].OR=(tr[x<<1].OR|tr[x<<1|1].OR);
	if(tr[x<<1].AND==0) tr[x].ANDp=tr[x<<1].ANDp;
	else tr[x].ANDp=tr[x<<1|1].ANDp;
	if(tr[x<<1].OR==1) tr[x].ORp=tr[x<<1].ORp;
	else tr[x].ORp=tr[x<<1|1].ORp;
	return ;
}
#undef update
#undef tr
#define tr tr1
int query1_0(int x,int l,int r,int pos){
	if(l==r) return tr[x].ANDp;
	int mid=(l+r)>>1;
	if(pos<=mid){
		int val=query1_0(x<<1,l,mid,pos);
		if(val!=-1) return val;
		return tr[x<<1|1].ANDp;
	}else return query1_0(x<<1|1,mid+1,r,pos);
}
int query1_1(int x,int l,int r,int pos){
	if(l==r) return tr[x].ORp;
	int mid=(l+r)>>1;
	if(pos<=mid){
		int val=query1_1(x<<1,l,mid,pos);
		if(val!=-1) return val;
		return tr[x<<1|1].ORp;
	}else return query1_1(x<<1|1,mid+1,r,pos);
}
#undef tr
#define tr tr2
int query2_0(int x,int l,int r,int pos){
	if(l==r) return tr[x].ANDp;
	int mid=(l+r)>>1;
	if(pos<=mid){
		int val=query2_0(x<<1,l,mid,pos);
		if(val!=-1) return val;
		return tr[x<<1|1].ANDp;
	}else return query2_0(x<<1|1,mid+1,r,pos);
}
int query2_1(int x,int l,int r,int pos){
	if(l==r) return tr[x].ORp;
	int mid=(l+r)>>1;
	if(pos<=mid){
		int val=query2_1(x<<1,l,mid,pos);
		if(val!=-1) return val;
		return tr[x<<1|1].ORp;
	}else return query2_1(x<<1|1,mid+1,r,pos);
}
#undef tr
int main(){
	freopen("edit.in","r",stdin);
	freopen("edit.out","w",stdout);
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	cin>>t;
	while(t--){
		cin>>n>>s1>>s2>>t1>>t2,s1=" "+s1,s2=" "+s2,t1=" "+t1,t2=" "+t2;
		for(int i=1;i<=n;++i){
			sumt1[i]=sumt1[i-1]+(t1[i]=='1');
			sumt2[i]=sumt2[i-1]+(t2[i]=='1');
			update1(1,1,n,i,s1[i]-'0');
			update2(1,1,n,i,s2[i]-'0');
		}
		int ans=0;
		for(int i=1;i<=n;++i){
			if(s1[i]==s2[i]) {++ans;continue;}
			if(i==n) continue;
			if(s1[i]=='0'){
				int fdp=query1_1(1,1,n,i+1);
				if(fdp!=-1 && sumt1[fdp]-sumt1[i-1]==fdp-i+1){
					swap(s1[i],s1[fdp]);
					update1(1,1,n,i,s1[i]-'0'),
					update1(1,1,n,fdp,s1[fdp]-'0'),++ans;
				}else{
					fdp=query2_0(1,1,n,i+1);
					if(fdp!=-1 && sumt2[fdp]-sumt2[i-1]==fdp-i+1){
						swap(s2[i],s2[fdp]);
						update2(1,1,n,i,s2[i]-'0'),
						update2(1,1,n,fdp,s2[fdp]-'0'),++ans;
					}else continue;
				}
			}else{
				int fdp=query1_0(1,1,n,i+1);
				if(fdp!=-1 && sumt1[fdp]-sumt1[i-1]==fdp-i+1){
					swap(s1[i],s1[fdp]);
					update1(1,1,n,i,s1[i]-'0'),
					update1(1,1,n,fdp,s1[fdp]-'0'),++ans;
				}else{
					fdp=query2_1(1,1,n,i+1);
					if(fdp!=-1 && sumt2[fdp]-sumt2[i-1]==fdp-i+1){
						swap(s2[i],s2[fdp]);
						update2(1,1,n,i,s2[i]-'0'),
						update2(1,1,n,fdp,s2[fdp]-'0'),++ans;
					}else continue;
				}
			}
		}
		cout<<ans<<"\n";	
	}
	return 0;
}
/*
1
6
011101
111010
111010
101101
*/
