    #include<iostream>
    #include<iomanip>
    #include<cstdio>
    #include<cstdlib>
    #include<algorithm>
    #include<cassert>
    #include<ctime>
    #include<cwctype>
    #include<chrono>
    #include<random>
     
    #include<cstring>
    #include<vector>
    #include<queue>
    #include<set>
    #include<map>
    #include<unordered_set>
    #include<unordered_map>
    #include<bitset>
     
    #include<cmath>
    #include<complex>
     
    using namespace std;
    #define szof(x) ((int) x.size())
     
    struct segtree{
    	struct node{
    		int sum = 0;
    		int tag = 0;
    		bool put = false;
     
    		node() {};
    		node(int sum): sum(sum){};
     
    		void modify(int l, int r, int v){
    			// update range l <= x < r
    			sum = (r - l) * v;
    			tag = v;
    			put = true;
    		}
     
    		void unite(const node &a, const node &b){
    			sum = a.sum + b.sum;
    		}
    	};
     
    	node unite(const node &a, const node &b) const {
    		node ret;
    		ret.unite(a,b);
    		return ret;
    	}
     
    	int n;
    	vector<node> tree;
     
    	segtree(int n): n(n), tree(n << 2, node(0)) {}
    	segtree(int n, int val): n(n), tree(n << 2,node(val)) {}
     
    	inline void pull(int p){
    		tree[p].unite(tree[p << 1], tree[(p << 1) + 1]);
    	}
     
    	inline void push(int p, int l, int r){
    		int m = (l + r) >> 1;
    		if(tree[p].put){
    			tree[p << 1].modify(l, m, tree[p].tag);
    			tree[(p << 1) + 1].modify(m, r, tree[p].tag);
    			tree[p].put = false;
    		}
    	}
     
    	void build(int p, int l, int r, const vector<int> &v){
    		// build range l <= x <= r
    		if( l == r - 1 ){
    			tree[p].modify(l,r,v[l]);
    			return;
    		}
    		int m = (l + r) >> 1;
    		build(p << 1, l, m, v);
    		build((p << 1) + 1, m, r, v);
    		pull(p);
    	}
     
    	//query and modify need to be top down to ensure updates go through.	
     
    	void modify(int p, int l, int r, int ll, int rr, int v){
    		// modifies range l <= x < r
    		if(ll <= l && r <= rr){
    			tree[p].modify(l,r,v);
    			return;
    		}
    		int m = (l + r) >> 1;
    		push(p, l, r);
    		if(ll < m) modify(p << 1, l, m, ll, rr, v);
    		if(rr > m) modify((p << 1) + 1, m, r, ll, rr, v);
    		pull(p);
    	}
    	
    	node query(int p, int l, int r, int ll, int rr){
    		// query range l <= x < r
    		if(ll <= l && r <= rr) return tree[p];
    		int m = (l + r) >> 1;
    		push(p, l, r);
    		node ret;
    		if(ll < m && rr > m) ret = unite(query(p << 1, l, m, ll, rr), query((p << 1) + 1, m, r, ll, rr));
    		else if(ll < m) ret = query(p << 1, l, m, ll, rr);
    		else if(rr > m) ret = query((p << 1) + 1, m, r, ll, rr);
    		pull(p);
    		return ret;
    	}
     
    	inline void modify(int l, int r, int v) {modify(1,0,n,l,r,v);}
    	inline node query(int l, int r) {return query(1,0,n,l,r);}
    	inline node get(int i) {return query(i,i+1);}
     
    	void print(){
    		for(node i : tree) cerr << i.sum << " ";
    		cerr << endl;
    	}
    };
     
    int main(){
    	ios_base::sync_with_stdio(false);
    	cin.tie(nullptr);
    	int T; cin >> T;
    	for(int tt = 0; tt < T; ++tt){
    		int n, q; cin >> n >> q;
    		string s, f;
    		cin >> s >> f;
    		vector<int> l(q), r(q);
    		for(int i = 0; i < q; ++i){
    			cin >> l[i] >> r[i];
    			l[i]--, r[i];
    		}
    		segtree st(n);
    		for(int i = 0; i < n; ++i) st.modify(i, i+1, (int) f[i] - '0');
    		bool ok = true;
    		for(int i = q-1; i >= 0; --i){
    			int sum = st.query(l[i],r[i]).sum;
    			int len = r[i] - l[i];
    			if(2 * sum == len){
    				ok = false;
    				break;
    			}
    			st.modify(l[i],r[i], 2 * sum < len ? 0 : 1);
    		}
    		for(int i = 0; i < n; ++i){
    			if(st.get(i).sum != (int) s[i] - '0'){
    				ok = false;
    				break;
    			}
    		}
    		cout << (ok ? "YES" : "NO") << endl;
    	}
    	return 0;
    }
