#include<bits/stdc++.h>
#define ll long long
#define re register
#define cs const
namespace IO{
inline char gc(){
static cs int Rlen=1<<24|1;
static char buf[Rlen],*p1,*p2;
return (p1p2)&&(p2=(p1=buf)+fread(buf,1,Rlen,stdin),p1p2)?EOF:*p1++;
}
}
using namespace IO;
using stdcerr;
using stdcout;
#define lc son[u][0]
#define rc son[u][1]
cs int N=1.1e6+7;
int son[N][2],fa[N],siz[N],tot;
inline void pushup(int u){siz[u]=siz[lc]+siz[rc]+1;}
inline bool get(int u){return son[fa[u]][1]==u;}
inline void Rotate(int u){
int p=fa[u],pp=fa[p],d=get(u);
if(pp)son[pp][get(p)]=u;son[p][d]=son[u][!d],fa[son[p][d]]=p;
son[u][!d]=p,fa[p]=u,fa[u]=pp;pushup(p);pushup(u);
}
inline void Splay(int u,int f=0){
for(int p;(p=fa[u])!=f;Rotate(u))
if(fa[p]!=f)Rotate(get(u)==get(p)?p:u);
}
inline int Rank(int u){Splay(u);return siz[lc];}
inline int get_mn(int u){Splay(u);while(lc)u=lc;Splay(u);return u;}
inline int get_mx(int u){Splay(u);while(rc)u=rc;Splay(u);return u;}
inline bool iscon(int u,int v){return get_mn(u)==get_mn(v);}
inline void inorder_dfs(int u){
if(lc)inorder_dfs(lc);cerr<<u<<" ";if(rc)inorder_dfs(rc);
}
inline int query(int u,int v){
if(!iscon(u,v))return -1;
int rk_u=Rank(u),rk_v=Rank(v);Splay(u);
if(rk_u>=rk_v)return rk_u-rk_v;return rk_u-rk_v+siz[u];
}
inline void merge(int u,int v){
if(!u||!v||iscon(u,v))return ;Splay(u);Splay(v);
while(rc)u=rc;Splay(u);rc=v;fa[v]=u;pushup(u);
}
inline void apart(int u,bool flag){//u扔到环头
Splay(u);int tmp=lc;fa[lc]=0;lc=0;pushup(u);if(!flag)merge(u,tmp);
}
inline void del(int u){Splay(u);fa[lc]=fa[rc]=0;lc=rc=0;siz[u]=1;}
int st[N],tp;
int build(int l,int r){
if(l>r)return 0;int mid=l+r>>1,u=st[mid];
rc=build(l,mid-1),lc=build(mid+1,r);
siz[u]=r-l+1;fa[lc]=fa[rc]=u;return u;
}
#undef lc
#undef rc
cs int M=507;
int n,m,Q,a[M][M][2],p[M][M][2][2],use[M][M][4];
// a[x][y][0] : 该点上方的边是否存在
// a[x][y][1] : 该点左方的边是否存在
// p[0][1] : 上方边向上的拆分
// p[0][0] : 上方边向下的拆分
// p[1][1] : 左侧边向右的拆分
// p[1][0] : 左侧边向左的拆分
// 方向 : 0上,1左,2下,3右
// use 表示对应方向上的边是否存在
// 询问0 :左侧,上方 询问1 : 右侧,下方
cs int dx[]={0,0,1,0};
cs int dy[]={0,0,0,1};
//get_back 顺时针
//get_next 逆时针
inline int get_next(int d,int x,int y){for(int re i=1;i<4;++i)if(use[x][y][(d+i)&3])return (d+i)&3;return -1;}
inline int get_back(int d,int x,int y){for(int re i=3;i>0;--i)if(use[x][y][(d+i)&3])return (d+i)&3;return -1;}
// op = 0 : 这个点上方的边执行操作
// op = 1 : 这个点左侧的边执行操作
inline void ins(int x,int y,int op){
a[x][y][op]=true;
if(op0){
int tx=x-1,ty=y;use[x][y][0]=use[tx][ty][2]=true;
int e1=p[x][y][0][1],e2=p[x][y][0][0],e3,e4;
int t1=get_back(0,x,y),t2=get_back(2,tx,ty);
if(!t1&&!t2)merge(e1,e2);
else if(t1&&!t2){
e3=p[x+dx[t1]][y+dy[t1]][t1&1][t1!=3];
merge(e2,e1),apart(e3,0);merge(e1,e3);
}else if(!t1&&t2){
e4=p[tx+dx[t2]][y+dy[t2]][t2&1][t21];
merge(e1,e2),apart(e4,0);merge(e2,e4);
}else {
e3=p[x+dx[t1]][y+dy[t1]][t1&1][t1!=3];
e4=p[tx+dx[t2]][ty+dy[t2]][t2&1][t21];
int t=iscon(e3,e4);apart(e4,0),apart(e3,t);
merge(e1,e3),merge(e2,e4);if(!t)merge(e3,e2);
}
}else {
int tx=x,ty=y-1;use[x][y][1]=use[tx][ty][3]=true;
int e1=p[x][y][1][0],e2=p[x][y][1][1],e3,e4;
int t1=get_back(1,x,y),t2=get_back(3,tx,ty);
if(!t1&&!t2)merge(e1,e2);
else if(t1&&!t2){
e3=p[x+dx[t1]][y+dy[t1]][t1&1][t12];
merge(e2,e1),apart(e3,0);merge(e1,e3);
}else if(!t1&&t2){
e4=p[tx+dx[t2]][ty+dy[t2]][t2&1][t2!=0];
merge(e1,e2);apart(e4,0);merge(e2,e4);
}else {
e3=p[x+dx[t1]][y+dy[t1]][t1&1][t1==2];
e4=p[tx+dx[t2]][ty+dy[t2]][t2&1][t2!=0];
int t=iscon(e3,e4);
apart(e4,0),apart(e3,t);
merge(e1,e3),merge(e2,e4);
if(!t)merge(e3,e2);
}
}
}
inline void del(int x,int y,int op){
a[x][y][op]=false;
if(op0){
int tx=x-1,ty=y;use[x][y][0]=use[tx][ty][2]=false;
int e1=p[x][y][0][1],e2=p[x][y][0][0],e3,e4;
int t1=get_back(0,x,y),t2=get_back(2,tx,ty);
if(!t1&&!t2)del(e1),del(e2);
else if(t1&&!t2){
e3=p[x+dx[t1]][y+dy[t1]][t1&1][t1!=3];
apart(e3,0),del(e1),del(e2);
}else if(!t1&&t2){
e4=p[tx+dx[t2]][ty+dy[t2]][t2&1][t21];
apart(e4,0),del(e1),del(e2);
}else {
e3=p[x+dx[t1]][y+dy[t1]][t1&1][t1!=3];
e4=p[tx+dx[t2]][ty+dy[t2]][t2&1][t21];
int t=iscon(e3,e4);apart(e4,0),apart(e3,t);
del(e1),del(e2);if(!t)merge(e4,e3);
}
}else {
int tx=x,ty=y-1;use[x][y][1]=use[tx][ty][3]=false;
int e1=p[x][y][1][0],e2=p[x][y][1][1],e3,e4;
int t1=get_back(1,x,y),t2=get_back(3,tx,ty);
if(!t1&&!t2)del(e1),del(e2);
else if(t1&&!t2){
e3=p[x+dx[t1]][y+dy[t1]][t1&1][t12];
apart(e3,0),del(e1),del(e2);
}else if(!t1&&t2){
e4=p[tx+dx[t2]][ty+dy[t2]][t2&1][t2!=0];
apart(e4,0),del(e1),del(e2);
}else {
e3=p[x+dx[t1]][y+dy[t1]][t1&1][t1==2];
e4=p[tx+dx[t2]][ty+dy[t2]][t2&1][t2!=0];
int t=iscon(e3,e4);apart(e4,0),apart(e3,t);
del(e1),del(e2);if(!t)merge(e4,e3);
}
}
}
inline void read(int &x,int &y,int &op){
int x0=gi(),y0=gi(),x1=gi(),y1=gi();
if(x0>x1||y0>y1)stdswap(x0,x1),stdswap(y0,y1);
x=x1,y=y1;op=x0==x1;
}
inline void Ins(){int x,y,op;read(x,y,op);ins(x,y,op);}
inline void Del(){int x,y,op;read(x,y,op);del(x,y,op);}
inline void Query(){
int x0,y0,o0,d0,x1,y1,o1,d1;
read(x0,y0,o0),d0=gi(),read(x1,y1,o1),d1=gi();
cout<<query(p[x0][y0][o0][d0],p[x1][y1][o1][d1])<<"\n";
}
#undef zxyoi
signed main(){
#ifdef zxyoi
freopen("farewell.in","r",stdin);
#else
#ifndef ONLINE_JUDGE
freopen("farewell.in","r",stdin);freopen("farewell.out","w",stdout);
#endif
#endif
n=gi(),m=gi(),Q=gi();
for(int re i=1;i<=n;++i)a[i][0][0]=a[i][m][0]=true;
for(int re i=1;i<=m;++i)a[0][i][1]=a[n][i][1]=true;
for(int re i=1;i<=n;++i)for(int re j=1;j<m;++j)a[i][j][0]=gi();
for(int re i=1;i<n;++i)for(int re j=1;j<=m;++j)a[i][j][1]=gi();
for(int re i=1;i<=n;++i)for(int re j=0;j<=m;++j)p[i][j][0][0]=++tot,siz[tot]=1;
for(int re i=1;i<=n;++i)for(int re j=0;j<=m;++j)p[i][j][0][1]=++tot,siz[tot]=1;
for(int re i=0;i<=n;++i)for(int re j=1;j<=m;++j)p[i][j][1][0]=++tot,siz[tot]=1;
for(int re i=0;i<=n;++i)for(int re j=1;j<=m;++j)p[i][j][1][1]=++tot,siz[tot]=1;
for(int re i=1;i<=n;++i)use[i][0][0]=use[i-1][0][2]=use[i][m][0]=use[i-1][m][2]=true;
for(int re i=1;i<=m;++i)use[0][i][1]=use[0][i-1][3]=use[n][i][1]=use[n][i-1][3]=true;
for(int re i=1;i<=m;++i)st[++tp]=p[0][i][1][1];
for(int re i=1;i<=n;++i)st[++tp]=p[i][m][0][0];
for(int re i=m;i>=1;--i)st[++tp]=p[n][i][1][0];
for(int re i=n;i>=1;--i)st[++tp]=p[i][0][0][1];build(1,tp);
for(int re i=1;i<=n;++i)for(int re j=1;j<m;++j)if(a[i][j][0])ins(i,j,0);
for(int re i=1;i<n;++i)for(int re j=1;j<=m;++j)if(a[i][j][1])ins(i,j,1);
while(Q--)switch(gi()){case 1:Ins();break;case 2:Del();break;case 3:Query();}
return 0;
}