#include<deque>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 1500
#define N1 22
#define inf 0x3f3f3f3f
using namespace std;
inline int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=getchar();}
while(ch<='9'&&ch>='0') x=x*10+ch-'0',ch=getchar();
return x*f;
}
int num=1,h[N],flag[N],f[N],id[N1][N1],id1[N1][N1],id2[N1][N1];
int T,pre[N],path[N],n,m,used[N1][N1],mp[N1][N1],mp1[N1][N1];
int dx[]={-1,-1,-1,0,0,1,1,1},dy[]={-1,0,1,-1,1,-1,0,1};
struct node{
int y,z,next,c;
}data[N<<3];
inline void insert1(int x,int y,int z,int c){
data[++num].y=y;data[num].z=z;data[num].next=h[x];h[x]=num;data[num].c=c;
data[++num].y=x;data[num].z=0;data[num].next=h[y];h[y]=num;data[num].c=-c;
}
inline bool spfa(){
memset(f,0x3f,sizeof(f));f[0]=0;memset(pre,-1,sizeof(pre));deque<int>q;
q.push_back(0);memset(flag,0,sizeof(flag));flag[0]=1;
while(!q.empty()){
int x=q.front();q.pop_front();flag[x]=0;
for (int i=h[x];i;i=data[i].next){
int y=data[i].y,c=data[i].c,z=data[i].z;
if (f[x]+c<f[y]&&z){
f[y]=f[x]+c;path[y]=i;pre[y]=x;
if (!flag[y]){
flag[y]=1;
if(!q.empty()&&f[y]<f[q.front()]) q.push_front(y);else q.push_back(y);
}
}
}
}if (pre[T]==-1) return 0;else return 1;
}
char s[50];
int main(){
freopen("bzoj2668.in","r",stdin);
n=read();m=read();int tot=0;int cnt=0;
for (int i=1;i<=n;++i)
for (int j=1;j<=m;++j) id[i][j]=++tot,id1[i][j]=++tot,id2[i][j]=++tot;T=tot+1;
for (int i=1;i<=n;++i){
scanf("%s",s+1);
for (int j=1;j<=m;++j) {
mp[i][j]=s[j]-'0';//if (mp[i][j]) ++cnt;
for (int k=0;k<8;++k){
int x=i+dx[k],y=j+dy[k];
if (x<1||x>n||y<1||y>m) continue;
insert1(id2[i][j],id[x][y],inf,1);
}
}
}
for (int i=1;i<=n;++i){
scanf("%s",s+1);
for (int j=1;j<=m;++j) mp1[i][j]=s[j]-'0';
}
for (int i=1;i<=n;++i){
scanf("%s",s+1);
for (int j=1;j<=m;++j) used[i][j]=s[j]-'0';
}int cnt1=0;
for (int i=1;i<=n;++i){
for (int j=1;j<=m;++j){
if ((mp[i][j]&&mp1[i][j])||(!mp[i][j]&&!mp1[i][j]))
insert1(id[i][j],id1[i][j],used[i][j]>>1,0),
insert1(id1[i][j],id2[i][j],used[i][j]>>1,0);
if (!mp[i][j]&&mp1[i][j]){
++cnt;
insert1(0,id1[i][j],1,0);insert1(id[i][j],id1[i][j],used[i][j]>>1,0);
insert1(id1[i][j],id2[i][j],used[i][j]+1>>1,0);
}
if (mp[i][j]&&!mp1[i][j]){
++cnt1;
insert1(id1[i][j],T,1,0);insert1(id[i][j],id1[i][j],used[i][j]+1>>1,0);
insert1(id1[i][j],id2[i][j],used[i][j]>>1,0);
}
}
}
int ans=0,ans1=0;
while(spfa()){
int minn=inf,now=T;
while(now) minn=min(minn,data[path[now]].z),now=pre[now];ans+=minn;now=T;ans1+=f[T]*minn;
while(now) data[path[now]].z-=minn,data[path[now]^1].z+=minn,now=pre[now];
}
if (cnt1!=cnt) puts("-1");else
if (ans!=cnt) puts("-1");else printf("%d",ans1);
return 0;
}