#include <bits/stdc++.h>
//#define int long long
#define fastio ios::sync_with_stdio(0), cin.tie(0);
using namespace std;
#ifdef LOCAL
#define cout cout << "\033[0;32m"
#define cerr cerr << "\033[0;31m"
#define endl "\n" << "\033[0m"
#else
#pragma GCC optimize("O3,unroll-loops")
#pragma GCC target("avx,avx2,sse,sse2,sse3,sse4,popcnt")
#define endl "\n"
#endif
const int MAX_N = 5e5+10;
const int INF = 1e9;
mt19937 seed(time(NULL));
inline int rnd(int l, int r){ return uniform_int_distribution(l, r)(seed); }
// declare
int n, q, l, r;
vector<string> s;
struct Treap{
Treap *l, *r;
int pri, val, sz;
bool b, sum;
char c;
Treap(int _b, int _c){
l = nullptr;
r = nullptr;
pri = rnd(1, 1e9);
sz = 1;
sum = b = _b;
c = _c;
}
} *tr[3], *tr_l[3], *tr_r[3], *tr_mid[3], *cmp[3], *tr_tmp, *tr_tmpx[6];
int size(Treap *a){
return a ? a->sz : 0;
}
int sum(Treap *a){
return a ? a->sum : 0;
}
void pull(Treap *t){
t->sz = size(t->l)+size(t->r)+1;
t->sum = (sum(t->l) || sum(t->r) || t->b);
}
Treap *merg(Treap *a, Treap *b){
if (!a || !b) return a ? a : b;
if (a->pri > b->pri){
a->r = merg(a->r, b);
pull(a);
return a;
}else{
b->l = merg(a, b->l);
pull(b);
return b;
}
}
void split(Treap *&t, int k, Treap *&a, Treap *&b){
if (!t) a = b = nullptr;
else if (size(t->l)+1<=k){
a = t;
split(t->r, k-size(t->l)-1, a->r, b);
pull(a);
}else{
b = t;
split(t->l, k, a, b->l);
pull(b);
}
}
ostream & operator << (ostream &os, Treap *t){
if (t==0) return os;
os << t->l;
os << t->c;
os << t->r;
return os;
}
void print(Treap *t){
if (t->l!=0) print(t->l);
cout << t->c;
if (t->r!=0) print(t->r);
}
char treap_get(Treap *&t, int k){
if (size(t->l) + 1 < k) {
return treap_get(t->r, k-size(t->l)-1);
} else if (k == size(t->l)+1) {
return t->c;
} else {
return treap_get(t->l, k);
}
}
int longest_zero_subarray(Treap *&t){
if (t == nullptr) return 0;
else if (sum(t->l) == false) {
return size(t->l) + ((t->b) ? (0) : 1 + longest_zero_subarray(t->r));
} else {
return longest_zero_subarray(t->l);
}
}
inline bool check_swap(int id1, int id2, int i) {
split(cmp[i], l, tr_tmpx[0], tr_tmpx[1]);
int ret = longest_zero_subarray(tr_tmpx[1]);
cmp[i] = merg(tr_tmpx[0], tr_tmpx[1]);
if (ret >= r - l + 1) return false;
return treap_get(tr_mid[id1], ret + 1) > treap_get(tr_mid[id2], ret + 1);
}
inline void srt(int id1, int id2, int i, int j, int k) {
if (check_swap(id1, id2, i)) {
swap(tr_mid[id1], tr_mid[id2]);
split(cmp[j], l, tr_tmpx[0], tr_tmp);
split(tr_tmp, r - l + 1, tr_tmpx[1], tr_tmpx[2]);
split(cmp[k], l, tr_tmpx[3], tr_tmp);
split(tr_tmp, r - l + 1, tr_tmpx[4], tr_tmpx[5]);
cmp[j] = merg(tr_tmpx[0], merg(tr_tmpx[4], tr_tmpx[2]));
cmp[k] = merg(tr_tmpx[3], merg(tr_tmpx[1], tr_tmpx[5]));
}
}
void solve1(){
// input
cin >> n >> q;
s.resize(3);
for (int i=0 ; i<3 ; i++){
cin >> s[i];
}
// process
for (int j = 0 ; j < n ; j++) {
for (int i = 0 ; i < 3 ; i++) {
tr[i] = merg(tr[i], new Treap(false, s[i][j]));
}
cmp[0] = merg(cmp[0], new Treap(s[0][j] != s[1][j], '-'));
cmp[1] = merg(cmp[1], new Treap(s[0][j] != s[2][j], '-'));
cmp[2] = merg(cmp[2], new Treap(s[1][j] != s[2][j], '-'));
}
// queries
for (int cases = 0 ; cases < q; ++cases){
cin >> l >> r;
l--, r--;
for (int j = 0; j < 3; ++j) {
split(tr[j], l, tr_l[j], tr_tmp);
split(tr_tmp, r - l + 1, tr_mid[j], tr_r[j]);
}
srt(0, 1, 0, 1, 2);
srt(0, 2, 1, 0, 2);
srt(1, 2, 2, 0, 1);
for (int j = 0; j < 3; ++j) {
tr[j] = merg(merg(tr_l[j], tr_mid[j]), tr_r[j]);
}
}
for (int i = 0; i < 3; ++i) {
print(tr[i]);
cout << endl;
}
return;
}
signed main(){
fastio;
int t = 1;
while (t--){
solve1();
}
return 0;
}