#include<bits/stdc++.h>
template<typename T,typename mark_type,int length>
struct segment_tree{
T a[length<<2],original_data[length];
mark_type tag[length<<2];
void pushup(int t){
a[t]=a[t<<1]+a[t<<1|1];
}void pushdown(int t,int len){
if(tag[t].mark()){
a[t<<1]=tag[t].calc(a[t<<1],len-len/2);
a[t<<1|1]=tag[t].calc(a[t<<1|1],len/2);
tag[t<<1]=tag[t<<1]+tag[t];
tag[t<<1|1]=tag[t<<1|1]+tag[t];
tag[t].clear();
}
}
void maintain(int t,int l,int r,int p,T x,int maintain_all){
if(l==r)a[t]=maintain_all?original_data[l]:x;
else{
pushdown(t,r-l+1);
int mid=l+r>>1;
if(p<=mid||maintain_all)maintain(t<<1,l,mid,p,x,maintain_all);
if(p>mid||maintain_all)maintain(t<<1|1,mid+1,r,p,x,maintain_all);
pushup(t);
}
}void update_interval(int t,int l,int r,int L,int R,mark_type update_mark){
if(l>=L&&r<=R)tag[t]=tag[t]+update_mark,a[t]=update_mark.calc(a[t],r-l+1);
else{
pushdown(t,r-l+1);
int mid=l+r>>1;
if(mid>=L)update_interval(t<<1,l,mid,L,R,update_mark);
if(mid<R)update_interval(t<<1|1,mid+1,r,L,R,update_mark);
pushup(t);
}
}void query(int t,int l,int r,int a_,int b_,T&return_value){
if(a_<=l&&r<=b_)return_value=return_value+a[t];
else{
pushdown(t,r-l+1);
int mid=l+r>>1;
if(a_<=mid)query(t<<1,l,mid,a_,b_,return_value);
if(b_>mid)query(t<<1|1,mid+1,r,a_,b_,return_value);
}
}
};
struct mark_type{
int tag;
mark_type operator+(mark_type rhs){
const int g[4][4]={{0,1,2,3},{1,0,2,3},{2,3,2,3},{3,2,2,3}};
return mark_type{g[tag][rhs.tag]};
}inline void clear(){tag=0;}
inline bool mark(){return tag;}
inline int calc(int lhs,int len){
switch(tag){
case 0:return lhs;
case 1:return len-lhs;
case 2:return 0;
default:return 1;
}}
};
inline mark_type get_mark(char c,int rhs){
const int g[4][2]={{0,1},{2,0},{0,0},{0,3}};
return mark_type{g[c%4][rhs]};
}inline int get_result(int ones,int len,char c){
switch(c){
case'A':return ones==len;
case'O':return ones;
case'X':return ones&1;
}
}
using namespace std;
int N,M,Q;
segment_tree<int,mark_type,1<<19>ST[63];
string s[1<<19];
int main(){
cin>>N>>M>>Q;
for(int i=1;i<=N;i++){
long long x;cin>>x;
for(int _=0;_<63;_++)ST[_].original_data[i]=!!(x&(1ll<<_));
}for(int _=0;_<63;_++)ST[_].maintain(1,1,N,2009,2009,1);
for(int i=1;i<=M;i++)cin>>s[i];
for(int _,l,r,op,x,i;Q--;){
cin>>_>>l>>r>>op;
if(_)for(cin>>x,i=0;i<63;i++)ST[i].update_interval(1,1,N,l,r,get_mark(s[op][i],!!(x&(1ll<<i))));
else{
long long res=0;
for(int i=0;i<63;i++)if(int rt=0;ST[i].query(1,1,N,l,r,rt),get_result(rt,r-l+1,s[op][i]))res|=(1ll<<i);
cout<<res<<endl;
}
}
}