#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef complex<double> P;
#define REP(i,n) for(int i=0;i<n;++i)
#define REPR(i,n) for(int i=1;i<n;++i)

#define DEBUG(x) cout<<#x<<": "<<x<<endl
#define DEBUG_VEC(v) REP(i,v.size())cout<<#v<<"["<<i<<"]: "<<v[i]<<endl
#define ALL(a) (a).begin(),(a).end()

// ??????????????¨????????????

// ????????°???????????°?????????????????§?????????????§???? 2????????????????????¢?´¢??¨??¨???
// http://www.slideshare.net/iwiwi/2-12188757
// ????????????

struct node_t{
  char val;
  node_t *ch[2];
  ll pri;
  int cnt;
  // string sum;
  node_t(char v,ll p):val(v),pri(p),cnt(1){
    // sum = "";
    // sum += v;
    ch[0]=ch[1]=NULL;
  }
};
int count(node_t *t){
  return t==NULL ? 0 : t->cnt;
}
// string sum(node_t *t){
//   return t==NULL ? "" : t->sum;
// }
node_t* update(node_t *t){
  t->cnt = count(t->ch[0]) + 1 + count(t->ch[1]);
  // t->sum = sum(t->ch[0]) + t->val + sum(t->ch[1]);
  return t;
}
node_t* merge(node_t *l, node_t *r){
  if(!l || !r) return !l?r:l;
  if(l->pri > r->pri){
    l->ch[1] = merge(l->ch[1],r);
    return update(l);
  }else{
    r->ch[0] = merge(l,r->ch[0]);
    return update(r);
  }
}
pair<node_t*,node_t*> split(node_t *t, int k){
  if(!t) return make_pair((node_t*)NULL,(node_t*)NULL);
  if(k <= count(t->ch[0])){
    pair<node_t*,node_t*> s = split(t->ch[0],k);
    t->ch[0] = s.second;
    return make_pair(s.first,update(t));
  }else{
    pair<node_t*,node_t*> s = split(t->ch[1],k-count(t->ch[0])-1);
    t->ch[1] = s.first;
    return make_pair(update(t),s.second);
  }
}
node_t* insert(node_t *t,int k,char val,ll pri){
  pair<node_t*,node_t*> lr = split(t,k);
  node_t* v = new node_t(val,pri);
  node_t* p = merge(lr.first,v);
  return merge(p,lr.second);
}
node_t* erase(node_t *t,int k){
  pair<node_t*,node_t*> mr = split(t,k);
  pair<node_t*,node_t*> lm = split(mr.first,k-1);
  return merge(lm.first,mr.second);
}
void renew(node_t *t,int k,char val){
  node_t *target = t;
  vector<node_t*> l;
  int cnt = count(target);
  int left = 0;
  while(true){
    l.push_back(target);
    int lcnt = count(target->ch[0]);
    if(left+lcnt==k)break;
    if(left+lcnt>k)target = target->ch[0];
    if(left+lcnt<k){
      target = target->ch[1];
      left += lcnt+1;
    }
  }
  target->val = val;
  int sz = l.size();
  REP(i_,sz){
    int i = sz-1-i_;
    update(l[i]);
  }
}
void dfs(node_t *t,char *res){
  if(!t)return;
  int lcnt = count(t->ch[0]);
  res[lcnt] = t->val;
  dfs(t->ch[0],res);
  dfs(t->ch[1],res+lcnt+1);
}
void output(node_t *t){
  int len = count(t);
  char ret[len];
  dfs(t,ret);
  REP(i,len)cout<<ret[i];
  cout<<endl;
}

node_t* str[100010];

ll rd(){
  // xorshift
  static ll x = 123456789, y = 362436069, z = 521288629, w = 88675123;
  ll t;
  t = x ^ (x<<11);
  x=y;y=z;z=w;
  return w=(w^(w>>19)^(t^(t>>8)));
}

int main(){
  int N,Q;
  cin >> N >> Q;
  // string S[N];
  // REP(i,N) cin >> S[i];
  REP(i,N){
    string s;
    cin>>s;
    int len = s.size();
    str[i] = new node_t(s[0],rd());
    REPR(j,len){
      str[i] = insert(str[i],count(str[i]),s[j],rd());
    }
  }
  REP(_,Q){
    int q_type;
    cin>>q_type;
    if(q_type == 1){
      int a,b,c,d;
      cin>>a>>b>>c>>d;
      --a;--b;--c;--d;
      pair<node_t*,node_t*> sa = split(str[a],b);
      pair<node_t*,node_t*> sc = split(str[c],d);
      str[a] = merge(sa.first,sc.second);
      str[c] = merge(sc.first,sa.second);
    }else{
      int a,b;
      char c;
      cin>>a>>b>>c;
      --a;--b;
      renew(str[a],b,c);
      // str[a] = erase(str[a],b+1);
      // str[a] = insert(str[a],b,c,rd());
    }
  }
  REP(i,N){
    // cout << output(str[i]) << endl;
    output(str[i]);
  }
  return 0;
}

Measured memory_bytes: 97616