#pragma GCC optimize ("O3")
#include <iostream>
#include <iomanip>
#include <istream>
#include <ostream>
#include <sstream>
#include <iterator>
#include <vector>
#include <algorithm>
#include <queue>
#include <deque>
#include <list>
#include <stack>
#include <map>
#include <unordered_map>
#include <set>
#include <bitset>
#include <utility>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <string>
#include <ctime>
#include <cctype>
#include <cstdlib>
#include <numeric>
#define IINF 1000000000
#define INF 3223372036854775807
#define MOD 1000000007
#define mod 1000000007
#define INT_MAX_ 2147483647
#define EPS (1e-10)
#define REP(i, a, n) fo-r (ll i = a; i < (ll)(n); i++)
#define REPE(i, a, n) for (ll i = a; i <= (ll)(n); i++)
//#define rep(i,n)for (ll i = 0; i < (ll)(n); i++)
#define rep(i,l,r)for(ll i=(l);i<(r);i++)
#define rep1(i,n) for(int i=1;i<=(int)(n);i++)
#define Endl endl
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define mt make_tuple
#define eb emplace_back
#define mmax(x,y)(x>y?x:y)
#define mmin(x,y)(x<y?x:y)
#define chmax(x,y) x=mmax(x,y)
#define chmin(x,y) x=mmin(x,y)
#define all(x) (x).begin(),(x).end()
#define siz(x) (ll)(x).size()
#define PI acos(-1.0)
#define me memset
#define bit(n,k) ((n>>k)&1)
#define lg length()
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;
typedef long double ld;
typedef pair<int,int>Pin;
typedef pair<ll,ll>Pll;
template<class T> using V=vector<T>;
//template<typename T> using min_priority_queue = priority_queue<T, vector<T>, greater<T> >;
long long GCD(long long a, long long b) {return b?GCD(b,a%b):a;}
long long LCM(long long a, long long b) {return a/GCD(a,b)*b;}
ll pom(ll a,ll n,int m){ll x=1;for(a%=m;n;n/=2)n&1?x=x*a%m:0,a=a*a%m;return x;}
#define invp(a,p)pom(a,p-2,p)
int dx[4]={-1,0,1,0};
int dy[4]={0,-1,0,1};
int ddx[8]={-1,0,1,0,1,1,-1,-1};
int ddy[8]={0,-1,0,1,1,-1,1,-1};
ll cmp1(pair<Pll,ll> a,pair<Pll,ll> b){
        return a.fi.se>b.fi.se;
}
ll cmp2(pair<Pll,ll> a,pair<Pll,ll> b){
        return a.se<b.se;
}
//----------------------------------------------------------------------

//----------------------------------------------------------------------
int main(int argc, char * argv[]){
    cin.tie(0);
    ios::sync_with_stdio(false);
    //-------------------------------
    //ll begin_t=clock();
    //freopen("big.txt", "r", stdin);
    //freopen("out3.txt", "w", stdout);
    //-----------------------------
    ll n,m;
    cin>>n>>m;
    char a[n+1][m+1];
    int b[n+1][m+1];
    ll sum[n+1][m+1];
    for(ll i=0;i<n;i++){
        for(ll j=0;j<m;j++){
            cin>>a[i][j];
            b[i][j]=a[i][j]-'0';
            sum[i][j]=0;
        }
    }
    if(n<2||m<2){
        cout<<0<<endl;
        return 0;
    }
    if(mmin(n,m)>=4){
        cout<<-1<<endl;
        return 0;
    }
    ll ans=0;
    /*
    ll e=0;
    for(ll i=0;i<n-1;i++){
        for(ll j=0;j<m-1;j++){
            ll a1 = a[i][j]-'0';
            ll a2 = a[i+1][j]-'0';
            ll a3 = a[i+1][j+1]-'0';
            ll a4 = a[i][j+1]-'0';
            ll x = a1+a2+a3+a4;
            if(x%2==0)e++;
        }
    }
    ans=e/2;
    if(e%2!=0)ans++;
    cout<<ans<<Endl;
    */
    bool color[n+1][m+1];
    me(color,0,sizeof(color));
    if(m==2){
        ll j=0;
        for(ll i=0;i<n-2;){
            ll x = b[i][j]+b[i+1][j]+b[i][j+1]+b[i+1][j+1];
            ll y = b[i+1][j]+b[i+2][j]+b[i+1][j+1]+b[i+2][j+1];
            if(x%2==0&&y%2==0){
                b[i+1][j]=1-b[i+1][j];
                ans++;
                i+=2;
            }
            else if(x%2==0){
                ans++;
                i+=2;
            }
            else if(y%2==0){
                i++;
                if(i==n-3)ans++;
            }
        }
    }
    else if(n==2){
        for(ll j=0;j<m-2;){
            ll x = b[0][j]+b[1][j]+b[0][j+1]+b[1][j+1];
            ll y = b[1][j+2]+b[0][j+2]+b[1][j+1]+b[0][j+1];
            if(x%2==0&&y%2==0){
                b[1][j+1]=1-b[1][j+1];
                ans++;
                j+=2;
            }
            else if(x%2==0){
                ans++;
                j+=2;
            }
            else if(y%2==0){
                j++;
                if(j==m-3)ans++;
            }
        }
    }
    else{

        ll e2=0,e4=0;
        for(ll i=0;i<n-2;i++){
            for(ll j=0;j<m-2;j++){
                if(color[i][j]||color[i+1][j]||color[i][j+1]||color[i+1][j+1])continue;
                ll a1 = a[i][j]+a[i+1][j]+a[i+1][j+1]+a[i][j+1];
                ll a2 = a[i+1][j]+a[i+2][j]+a[i+2][j+1]+a[i+1][j+1];
                ll a3 = a[i][j+1]+a[i+1][j+1]+a[i+1][j+2]+a[i][j+2];
                ll a4 = a[i+1][j+1]+a[i+2][j+1]+a[i+2][j+2]+a[i+1][j+2];
                if(a1%2==0&&a2%2==0&&a3%2==0&&a4%2==0){e4++;
                color[i][j]=1;
                color[i+1][j]=1;
                color[i][j+1]=1;
                color[i+1][j+1]=1;}
            }
        }

        ans+=e4;
        for(ll i=0;i<n-1;i++){
            for(ll j=0;j<m-2;j++){
                if(color[i][j]||color[i][j+1])continue;
                ll a1 = a[i][j]+a[i+1][j]+a[i+1][j+1]+a[i][j+1];
                ll a3 = a[i][j+1]+a[i+1][j+1]+a[i+1][j+2]+a[i][j+2];
                if(a1%2==0&&a3%2==0){e2++;
                color[i][j]=1;
                color[i][j+1]=1;}
            }
        }
        for(ll i=0;i<n-2;i++){
            for(ll j=0;j<m-1;j++){
                if(color[i+1][j]||color[i+1][j+1])continue;
                ll a2 = a[i+1][j]+a[i+2][j]+a[i+2][j+1]+a[i+1][j+1];
                ll a1 = a[i][j]+a[i+1][j]+a[i+1][j+1]+a[i][j+1];
                if(a2%2==0&&a1%2==0)
                    {e2++;
                color[i+1][j]=1;
                color[i+1][j+1]=1;}
            }
        }
        ll e=0;
        //cout<<e2<<endl;
        ans+=e2;
        for(ll i=0;i<n-1;i++){
            for(ll j=0;j<m-1;j++){
                if(color[i][j])continue;
                ll a1 = a[i][j]-'0';
                ll a2 = a[i+1][j]-'0';
                ll a3 = a[i+1][j+1]-'0';
                ll a4 = a[i][j+1]-'0';
                ll x = a1+a2+a3+a4;
                if(x%2==0)e++;
            }
        }
        ans+=e;
    }
    cout<<ans<<endl;
    //------------------------------
    //fclose(stdin);
    //fclose(stdout);
    //ll end_t=clock();cout<<"time="<<end_t-begin_t<<"ms"<<endl;
    //-------------------------------
    return 0;
}
//----------------------------------------------------------------------


#pragma GCC optimize ("O3")
#include <iostream>
#include <iomanip>
#include <istream>
#include <ostream>
#include <sstream>
#include <iterator>
#include <vector>
#include <algorithm>
#include <queue>
#include <deque>
#include <list>
#include <stack>
#include <map>
#include <unordered_map>
#include <set>
#include <bitset>
#include <utility>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <string>
#include <ctime>
#include <cctype>
#include <cstdlib>
#include <numeric>
#define IINF 1000000000
#define INF 3223372036854775807
#define MOD 1000000007
#define mod 1000000007
#define INT_MAX_ 2147483647
#define EPS (1e-10)
#define REP(i, a, n) fo-r (ll i = a; i < (ll)(n); i++)
#define REPE(i, a, n) for (ll i = a; i <= (ll)(n); i++)
//#define rep(i,n)for (ll i = 0; i < (ll)(n); i++)
#define rep(i,l,r)for(ll i=(l);i<(r);i++)
#define rep1(i,n) for(int i=1;i<=(int)(n);i++)
#define Endl endl
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define mt make_tuple
#define eb emplace_back
#define mmax(x,y)(x>y?x:y)
#define mmin(x,y)(x<y?x:y)
#define chmax(x,y) x=mmax(x,y)
#define chmin(x,y) x=mmin(x,y)
#define all(x) (x).begin(),(x).end()
#define siz(x) (ll)(x).size()
#define PI acos(-1.0)
#define me memset
#define bit(n,k) ((n>>k)&1)
#define lg length()
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;
typedef long double ld;
typedef pair<int,int>Pin;
typedef pair<ll,ll>Pll;
template<class T> using V=vector<T>;
//template<typename T> using min_priority_queue = priority_queue<T, vector<T>, greater<T> >;
long long GCD(long long a, long long b) {return b?GCD(b,a%b):a;}
long long LCM(long long a, long long b) {return a/GCD(a,b)*b;}
ll pom(ll a,ll n,int m){ll x=1;for(a%=m;n;n/=2)n&1?x=x*a%m:0,a=a*a%m;return x;}
#define invp(a,p)pom(a,p-2,p)
int dx[4]={-1,0,1,0};
int dy[4]={0,-1,0,1};
int ddx[8]={-1,0,1,0,1,1,-1,-1};
int ddy[8]={0,-1,0,1,1,-1,1,-1};
ll cmp1(pair<Pll,ll> a,pair<Pll,ll> b){
        return a.fi.se>b.fi.se;
}
ll cmp2(pair<Pll,ll> a,pair<Pll,ll> b){
        return a.se<b.se;
}
//----------------------------------------------------------------------
int c[1000010][3];
int a[2][3];
ll dp[1000010][8];
bool OK(int j,int p){
    if(j==0){
        a[0][0]=0;
        a[0][1]=0;
        a[0][2]=0;
    }
    else if(j==1){
        a[0][0]=0;
        a[0][1]=0;
        a[0][2]=0;
    }
    else if(j==2){
        a[0][0]=0;
        a[0][1]=1;
        a[0][2]=0;
    }
    else if(j==3){
        a[0][0]=0;
        a[0][1]=1;
        a[0][2]=1;
    }
    else if(j==4){
        a[0][0]=1;
        a[0][1]=0;
        a[0][2]=0;
    }
    else if(j==5){
        a[0][0]=1;
        a[0][1]=0;
        a[0][2]=1;
    }
    else if(j==6){
        a[0][0]=1;
        a[0][1]=1;
        a[0][2]=0;
    }
    else{
        a[0][0]=1;
        a[0][1]=1;
        a[0][2]=1;
    }
    if(p==0){
        a[1][0]=0;
        a[1][1]=0;
        a[1][2]=0;
    }
    else if(p==1){
        a[1][0]=0;
        a[1][1]=0;
        a[1][2]=0;
    }
    else if(p==2){
        a[1][0]=0;
        a[1][1]=1;
        a[1][2]=0;
    }
    else if(p==3){
        a[1][0]=0;
        a[1][1]=1;
        a[1][2]=1;
    }
    else if(p==4){
        a[1][0]=1;
        a[1][1]=0;
        a[1][2]=0;
    }
    else if(p==5){
        a[1][0]=1;
        a[1][1]=0;
        a[1][2]=1;
    }
    else if(p==6){
        a[1][0]=1;
        a[1][1]=1;
        a[1][2]=0;
    }
    else{
        a[1][0]=1;
        a[1][1]=1;
        a[1][2]=1;
    }
    int x =a[0][0]+a[0][1]+a[1][1]+a[1][0];
    int y = a[0][1]+a[0][2]+a[1][1]+a[1][2];
    if(x%2==0||y%2==0)return 0;
    else return 1;
}
//----------------------------------------------------------------------
int main(int argc, char * argv[]){
    cin.tie(0);
    ios::sync_with_stdio(false);
    //-------------------------------
    //ll begin_t=clock();
    //freopen("big.txt", "r", stdin);
    //freopen("out3.txt", "w", stdout);
    //-----------------------------
    int n,m;
    scanf("%d %d",&n,&m);
    if(n==1||m==1){
        cout<<0<<Endl;
        return 0;
    }
    if(n>=4&&m>=4){
        cout<<-1<<endl;
        return 0;
    }

    if(n<=m){
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                scanf("%1d",&c[i][j]);
            }
        }
    }
    else{
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                scanf("%1d",&c[i][j]);
            }
        }
        swap(n,m);
    }

    for(ll i=0;i<1000010;i++){
        for(ll j=0;j<8;j++){
            dp[i][j]=INF;
        }
    }
    for(ll i=0;i<8;i++){
        dp[0][i]=0;
        bool x = OK(i,i);
        for(int q=0;q<n;q++){
            if(c[0][q]!=a[0][q])dp[0][i]++;
        }
    }
    for(int i=1;i<m;i++){
        for(int j=0;j<8;j++){
            for(int p=0;p<8;p++){
                if(!OK(p,j))continue;
                int res=0;
                for(int q = 0;q<n;q++){
                    if(c[i][q]!=a[1][q])res++;
                }
                chmin(dp[i][j],dp[i-1][p]+res);
            }
        }
    }
    ll ans=INF;
    for(ll i=0;i<8;i++){
        //cout<<dp[m-1][i]<<Endl;
        chmin(ans,dp[m-1][i]);
    }
    cout<<ans<<Endl;
    //------------------------------
    //fclose(stdin);
    //fclose(stdout);
    //ll end_t=clock();cout<<"time="<<end_t-begin_t<<"ms"<<endl;
    //-------------------------------
    return 0;
}
//----------------------------------------------------------------------


#pragma GCC optimize ("O3")
#include <iostream>
#include <iomanip>
#include <istream>
#include <ostream>
#include <sstream>
#include <iterator>
#include <vector>
#include <algorithm>
#include <queue>
#include <deque>
#include <list>
#include <stack>
#include <map>
#include <unordered_map>
#include <set>
#include <bitset>
#include <utility>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <string>
#include <ctime>
#include <cctype>
#include <cstdlib>
#include <numeric>
#define IINF 1000000000
#define INF 3223372036854775807
#define MOD 1000000007
#define mod 1000000007
#define INT_MAX_ 2147483647
#define EPS (1e-10)
#define REP(i, a, n) fo-r (ll i = a; i < (ll)(n); i++)
#define REPE(i, a, n) for (ll i = a; i <= (ll)(n); i++)
//#define rep(i,n)for (ll i = 0; i < (ll)(n); i++)
#define rep(i,l,r)for(ll i=(l);i<(r);i++)
#define rep1(i,n) for(int i=1;i<=(int)(n);i++)
#define Endl endl
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define mt make_tuple
#define eb emplace_back
#define mmax(x,y)(x>y?x:y)
#define mmin(x,y)(x<y?x:y)
#define chmax(x,y) x=mmax(x,y)
#define chmin(x,y) x=mmin(x,y)
#define all(x) (x).begin(),(x).end()
#define siz(x) (ll)(x).size()
#define PI acos(-1.0)
#define me memset
#define bit(n,k) ((n>>k)&1)
#define lg length()
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;
typedef long double ld;
typedef pair<int,int>Pin;
typedef pair<ll,ll>Pll;
template<class T> using V=vector<T>;
//template<typename T> using min_priority_queue = priority_queue<T, vector<T>, greater<T> >;
long long GCD(long long a, long long b) {return b?GCD(b,a%b):a;}
long long LCM(long long a, long long b) {return a/GCD(a,b)*b;}
ll pom(ll a,ll n,int m){ll x=1;for(a%=m;n;n/=2)n&1?x=x*a%m:0,a=a*a%m;return x;}
#define invp(a,p)pom(a,p-2,p)
int dx[4]={-1,0,1,0};
int dy[4]={0,-1,0,1};
int ddx[8]={-1,0,1,0,1,1,-1,-1};
int ddy[8]={0,-1,0,1,1,-1,1,-1};
ll cmp1(pair<Pll,ll> a,pair<Pll,ll> b){
        return a.fi.se>b.fi.se;
}
ll cmp2(pair<Pll,ll> a,pair<Pll,ll> b){
        return a.se<b.se;
}
//----------------------------------------------------------------------
int c[1000010][3];
int a[2][3];
ll dp[1000010][8];
bool OK(int j,int p){
    if(j==0){
        a[0][0]=0;
        a[0][1]=0;
        a[0][2]=0;
    }
    else if(j==1){
        a[0][0]=0;
        a[0][1]=0;
        a[0][2]=0;
    }
    else if(j==2){
        a[0][0]=0;
        a[0][1]=1;
        a[0][2]=0;
    }
    else if(j==3){
        a[0][0]=0;
        a[0][1]=1;
        a[0][2]=1;
    }
    else if(j==4){
        a[0][0]=1;
        a[0][1]=0;
        a[0][2]=0;
    }
    else if(j==5){
        a[0][0]=1;
        a[0][1]=0;
        a[0][2]=1;
    }
    else if(j==6){
        a[0][0]=1;
        a[0][1]=1;
        a[0][2]=0;
    }
    else{
        a[0][0]=1;
        a[0][1]=1;
        a[0][2]=1;
    }
    if(p==0){
        a[1][0]=0;
        a[1][1]=0;
        a[1][2]=0;
    }
    else if(p==1){
        a[1][0]=0;
        a[1][1]=0;
        a[1][2]=0;
    }
    else if(p==2){
        a[1][0]=0;
        a[1][1]=1;
        a[1][2]=0;
    }
    else if(p==3){
        a[1][0]=0;
        a[1][1]=1;
        a[1][2]=1;
    }
    else if(p==4){
        a[1][0]=1;
        a[1][1]=0;
        a[1][2]=0;
    }
    else if(p==5){
        a[1][0]=1;
        a[1][1]=0;
        a[1][2]=1;
    }
    else if(p==6){
        a[1][0]=1;
        a[1][1]=1;
        a[1][2]=0;
    }
    else{
        a[1][0]=1;
        a[1][1]=1;
        a[1][2]=1;
    }
    int x =a[0][0]+a[0][1]+a[1][1]+a[1][0];
    int y = a[0][1]+a[0][2]+a[1][1]+a[1][2];
    if(x%2==0||y%2==0)return 0;
    else return 1;
}
//----------------------------------------------------------------------
int main(int argc, char * argv[]){
    cin.tie(0);
    ios::sync_with_stdio(false);
    //-------------------------------
    //ll begin_t=clock();
    //freopen("big.txt", "r", stdin);
    //freopen("out3.txt", "w", stdout);
    //-----------------------------
    int n,m;
    scanf("%d %d",&n,&m);
    if(n==1||m==1){
        cout<<0<<Endl;
        return 0;
    }
    if(n>=4&&m>=4){
        cout<<-1<<endl;
        return 0;
    }

    if(n<=m){
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                scanf("%1d",&c[i][j]);
            }
        }
    }
    else{
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                scanf("%1d",&c[i][j]);
            }
        }
        swap(n,m);
    }

    for(ll i=0;i<1000010;i++){
        for(ll j=0;j<8;j++){
            dp[i][j]=INF;
        }
    }
    for(ll i=0;i<8;i++){
        dp[0][i]=0;
        bool x = OK(i,i);
        for(int q=0;q<n;q++){
            if(c[0][q]!=a[1][q])dp[0][i]++;
        }
    }
    for(int i=1;i<m;i++){
        for(int j=0;j<8;j++){
            for(int p=0;p<8;p++){
                if(!OK(p,j))continue;
                ll res=0;
                for(int q = 0;q<n;q++){
                    if(c[i][q]!=a[1][q])res++;
                }
                chmin(dp[i][j],dp[i-1][p]+res);
            }
        }
    }
    ll ans=INF;
    for(ll i=0;i<8;i++){
        //cout<<dp[m-1][i]<<Endl;
        chmin(ans,dp[m-1][i]);
    }
    cout<<ans<<Endl;
    //------------------------------
    //fclose(stdin);
    //fclose(stdout);
    //ll end_t=clock();cout<<"time="<<end_t-begin_t<<"ms"<<endl;
    //-------------------------------
    return 0;
}
//----------------------------------------------------------------------


#pragma GCC optimize ("O3")
#include <iostream>
#include <iomanip>
#include <istream>
#include <ostream>
#include <sstream>
#include <iterator>
#include <vector>
#include <algorithm>
#include <queue>
#include <deque>
#include <list>
#include <stack>
#include <map>
#include <unordered_map>
#include <set>
#include <bitset>
#include <utility>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <string>
#include <ctime>
#include <cctype>
#include <cstdlib>
#include <numeric>
#define IINF 1000000000
#define INF 3223372036854775807
#define MOD 1000000007
#define mod 1000000007
#define INT_MAX_ 2147483647
#define EPS (1e-10)
#define REP(i, a, n) fo-r (ll i = a; i < (ll)(n); i++)
#define REPE(i, a, n) for (ll i = a; i <= (ll)(n); i++)
//#define rep(i,n)for (ll i = 0; i < (ll)(n); i++)
#define rep(i,l,r)for(ll i=(l);i<(r);i++)
#define rep1(i,n) for(int i=1;i<=(int)(n);i++)
#define Endl endl
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define mt make_tuple
#define eb emplace_back
#define mmax(x,y)(x>y?x:y)
#define mmin(x,y)(x<y?x:y)
#define chmax(x,y) x=mmax(x,y)
#define chmin(x,y) x=mmin(x,y)
#define all(x) (x).begin(),(x).end()
#define siz(x) (ll)(x).size()
#define PI acos(-1.0)
#define me memset
#define bit(n,k) ((n>>k)&1)
#define lg length()
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;
typedef long double ld;
typedef pair<int,int>Pin;
typedef pair<ll,ll>Pll;
template<class T> using V=vector<T>;
//template<typename T> using min_priority_queue = priority_queue<T, vector<T>, greater<T> >;
long long GCD(long long a, long long b) {return b?GCD(b,a%b):a;}
long long LCM(long long a, long long b) {return a/GCD(a,b)*b;}
ll pom(ll a,ll n,int m){ll x=1;for(a%=m;n;n/=2)n&1?x=x*a%m:0,a=a*a%m;return x;}
#define invp(a,p)pom(a,p-2,p)
int dx[4]={-1,0,1,0};
int dy[4]={0,-1,0,1};
int ddx[8]={-1,0,1,0,1,1,-1,-1};
int ddy[8]={0,-1,0,1,1,-1,1,-1};
ll cmp1(pair<Pll,ll> a,pair<Pll,ll> b){
        return a.fi.se>b.fi.se;
}
ll cmp2(pair<Pll,ll> a,pair<Pll,ll> b){
        return a.se<b.se;
}
//----------------------------------------------------------------------

//----------------------------------------------------------------------
int main(int argc, char * argv[]){
    cin.tie(0);
    ios::sync_with_stdio(false);
    //-------------------------------
    //ll begin_t=clock();
    //freopen("big.txt", "r", stdin);
    //freopen("out3.txt", "w", stdout);
    //-----------------------------
    ll n,m;
    cin>>n>>m;
    char a[n+1][m+1];
    int b[n+1][m+1];
    ll sum[n+1][m+1];
    for(ll i=0;i<n;i++){
        for(ll j=0;j<m;j++){
            cin>>a[i][j];
            b[i][j]=a[i][j]-'0';
            sum[i][j]=0;
        }
    }
    if(n<2||m<2){
        cout<<0<<endl;
        return 0;
    }
    if(mmin(n,m)>=4){
        cout<<-1<<endl;
        return 0;
    }
    ll ans=0;
    /*
    ll e=0;
    for(ll i=0;i<n-1;i++){
        for(ll j=0;j<m-1;j++){
            ll a1 = a[i][j]-'0';
            ll a2 = a[i+1][j]-'0';
            ll a3 = a[i+1][j+1]-'0';
            ll a4 = a[i][j+1]-'0';
            ll x = a1+a2+a3+a4;
            if(x%2==0)e++;
        }
    }
    ans=e/2;
    if(e%2!=0)ans++;
    cout<<ans<<Endl;
    */
    bool color[n+1][m+1];
    me(color,0,sizeof(color));

        ll e2=0,e4=0;
        for(ll i=0;i<n-2;i++){
            for(ll j=0;j<m-2;j++){
                if(color[i][j]||color[i+1][j]||color[i][j+1]||color[i+1][j+1])continue;
                ll a1 = b[i][j]+b[i+1][j]+b[i+1][j+1]+b[i][j+1];
                ll a2 = b[i+1][j]+b[i+2][j]+b[i+2][j+1]+b[i+1][j+1];
                ll a3 = b[i][j+1]+b[i+1][j+1]+b[i+1][j+2]+b[i][j+2];
                ll a4 = b[i+1][j+1]+b[i+2][j+1]+b[i+2][j+2]+b[i+1][j+2];
                if(a1%2==0&&a2%2==0&&a3%2==0&&a4%2==0){e4++;
                color[i][j]=1;
                color[i+1][j]=1;
                color[i][j+1]=1;
                color[i+1][j+1]=1;}
            }
        }

        ans+=e4;
        for(ll i=0;i<n-1;i++){
            for(ll j=0;j<m-2;j++){
                if(color[i][j]||color[i][j+1])continue;
                ll a1 = b[i][j]+b[i+1][j]+b[i+1][j+1]+b[i][j+1];
                ll a3 = b[i][j+1]+b[i+1][j+1]+b[i+1][j+2]+b[i][j+2];
                if(a1%2==0&&a3%2==0){e2++;
                color[i][j]=1;
                color[i][j+1]=1;}
            }
        }
        for(ll i=0;i<n-2;i++){
            for(ll j=0;j<m-1;j++){
                if(color[i][j]||color[i+1][j])continue;
                ll a2 = b[i+1][j]+b[i+2][j]+b[i+2][j+1]+b[i+1][j+1];
                ll a1 = b[i][j]+b[i+1][j]+b[i+1][j+1]+b[i][j+1];
                if(a2%2==0&&a1%2==0)
                    {e2++;
                color[i][j]=1;
                color[i+1][j]=1;}
            }
        }
        ll e=0;
        //cout<<e2<<endl;
        ans+=e2;
        for(ll i=0;i<n-1;i++){
            for(ll j=0;j<m-1;j++){
                if(color[i][j])continue;
                ll a1 = a[i][j]-'0';
                ll a2 = a[i+1][j]-'0';
                ll a3 = a[i+1][j+1]-'0';
                ll a4 = a[i][j+1]-'0';
                ll x = a1+a2+a3+a4;
                if(x%2==0)e++;
            }
        }
        ans+=e;

    cout<<ans<<endl;
    //------------------------------
    //fclose(stdin);
    //fclose(stdout);
    //ll end_t=clock();cout<<"time="<<end_t-begin_t<<"ms"<<endl;
    //-------------------------------
    return 0;
}
//----------------------------------------------------------------------


#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define all(v) v.begin(), v.end()
#define vll vector<ll>
#define pb push_back
#define ff first
#define ss
const int N=100005;
bool wor[8][8];
bool work()
{
    int foo=0;
    for(int i=0;i<8;i++)
    {
        for(int j=0;j<8;j++)
        {
            for(int k=0;k<2;k++)
        {
            int b=0;
            b=(bool)(i&(1<<k))+(bool)(i&(1<<(k+1)));
            b+=(bool)(j&(1<<k))+(bool)(j&(1<<(k+1)));
            if(b%2==0) foo=1;
        }
            if(!foo)wor[i][j]=1;
        }
    }
}
void solve()
{
    ll n,k=0,val=0,m=1,i=0,j=0,l=-1,x,y,z;
    ll ans=0;
    bool a[105][105];
    string sa[105];
    bool s[105][105];
    cin>>n>>m;
    for(i=0;i<n;i++) cin>>sa[i];
    for(i=0;i<n;i++)
        for(j=0;j<m;j++)
            s[i][j]=sa[i][j]-'0';
    if(n==1)
        ans = 0;
    if(n>=4)
        ans=-1;
    if(n==2)
    {
        ll ee=0,oo=0;
        for(i=0;i<m;i++)
        {
            val=s[0][i]=='0'^s[1][i]=='0';
            if(val==i%2) ee++;
            else oo++;
        }
        ans=min(ee,oo);
    }
    if(n==3)
    {
        work();
        ll dp[105][8]={};
        for(i=1;i<=m;i++)
        {
		    int mask=s[0][i-1]+2*s[1][i-1]+4*s[2][i-1];
		    for(j=0;j<8;j++)
            {
			    dp[i][j]=INT32_MAX;
                for(k=0;k<8;k++)
                if(wor[j,k])
                    dp[i][j]=min(dp[i][j],dp[i-1][k]+__builtin_popcount(j^mask));
		    }
	    }
        ans=*min_element(dp[m],dp[m]+8);
    }
    cout<<ans<<endl;
}
int main()
{
    #ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin) ;
    freopen("output.txt", "w", stdout) ;
    #endif
    ios::sync_with_stdio(0),cin.tie(NULL),cout.tie(NULL);
    int t=1;
    //cin>>t;
    while(t--)solve();
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define all(v) v.begin(), v.end()
#define vll vector<ll>
#define pb push_back
#define ff first
#define ss
const int N=100005;
bool wor[8][8]={};
bool work()
{
    for(int i=0;i<8;i++)
    {
        for(int j=0;j<8;j++)
        {
            int foo=0;
            for(int k=0;k<2;k++)
            {
                int b=0;
                b=(bool)(i&(1<<k))+(bool)(i&(1<<(k+1)));
                b+=(bool)(j&(1<<k))+(bool)(j&(1<<(k+1)));
                if(b%2==0) foo=1;
            }
            if(!foo)wor[i][j]=1;
        }
    }
}
void solve()
{
    ll n,k=0,val=0,m=1,i=0,j=0,l=-1,x,y,z;
    ll ans=0;
    bool a[105][105];
    string sa[105];
    bool s[105][105];
    cin>>n>>m;
    for(i=0;i<n;i++) cin>>sa[i];
    for(i=0;i<n;i++)
        for(j=0;j<m;j++)
            s[i][j]=sa[i][j]-'0';
    if(n==1)
        ans = 0;
    if(n>=4)
        ans=-1;
    if(n==2)
    {
        ll ee=0,oo=0;
        for(i=0;i<m;i++)
        {
            val=s[0][i]=='0'^s[1][i]=='0';
            if(val==i%2) ee++;
            else oo++;
        }
        ans=min(ee,oo);
    }
    if(n==3)
    {
        work();
        ll dp[105][8]={};
        for(i=1;i<=m;i++)
        {
		    int mask=s[0][i-1]+2*s[1][i-1]+4*s[2][i-1];
		    for(j=0;j<8;j++)
            {
			    dp[i][j]=1e9;
                for(k=0;k<8;k++)
                {
                if(!wor[j][k])continue;
                    dp[i][j]=min(dp[i][j],dp[i-1][k]+__builtin_popcount(j^mask));
		        }
            }
	    }
        ans=*min_element(dp[m]+1,dp[m]+8);
    }
    cout<<ans<<endl;
}
int main()
{
    /* #ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin) ;
    freopen("output.txt", "w", stdout) ;
    #endif  */
    ios::sync_with_stdio(0),cin.tie(NULL),cout.tie(NULL);
    int t=1;
    //cin>>t;
    while(t--)solve();
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define all(v) v.begin(), v.end()
#define vll vector<ll>
#define pb push_back
#define ff first
#define ss
const int N=1000005;
bool wor[8][8]={};
ll dp[N][8]{};
bool s[4][N]{};
bool work()
{
    for(int i=0;i<8;i++)
    {
        for(int j=0;j<8;j++)
        {
            int foo=0;
            for(int k=0;k<2;k++)
            {
                int b=0;
                b=(bool)(i&(1<<k))+(bool)(i&(1<<(k+1)));
                b+=(bool)(j&(1<<k))+(bool)(j&(1<<(k+1)));
                if(b%2==0) foo=1;
            }
            if(!foo)wor[i][j]=1;
        }
    }
}
void solve()
{
    ll n,k=0,val=0,m=1,i=0,j=0,l=-1,x,y,z;
    ll ans=0;
    string sa[105];
    cin>>n>>m;
    for(i=0;i<n;i++) cin>>sa[i];
    if(n>=4)
    {
        cout<<"-1\n";
        return;
    }
    for(i=0;i<n;i++)
        for(j=0;j<m;j++)
            s[i][j]=sa[i][j]-'0';
    if(n==1)
        ans = 0;
    if(n==2)
    {
        ll ee=0,oo=0;
        for(i=0;i<m;i++)
        {
            val=s[0][i]=='0'^s[1][i]=='0';
            if(val==i%2) ee++;
            else oo++;
        }
        ans=min(ee,oo);
    }
    if(n==3)
    {
        work();
        for(i=1;i<=m;i++)
        {
		    int mask=s[0][i-1]+2*s[1][i-1]+4*s[2][i-1];
		    for(j=0;j<8;j++)
            {
			    dp[i][j]=1e9;
                for(k=0;k<8;k++)
                {
                if(wor[j][k])
                    dp[i][j]=min(dp[i][j],dp[i-1][k]+__builtin_popcount(j^mask));
		        }
            }
	    }
        ans=*min_element(dp[m]+1,dp[m]+8);
    }
    cout<<ans<<endl;
}
int main()
{
    #ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin) ;
    freopen("output.txt", "w", stdout) ;
    #endif
    ios::sync_with_stdio(0),cin.tie(NULL),cout.tie(NULL);
    int t=1;
    //cin>>t;
    while(t--)solve();
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define all(v) v.begin(), v.end()
#define vll vector<ll>
#define pb push_back
#define ff first
#define ss
const int N=1000005;
bool wor[8][8]={};
ll dp[4][N]{};
bool s[4][N]{};
bool work()
{
    for(int i=0;i<8;i++)
    {
        for(int j=0;j<8;j++)
        {
            int foo=0;
            for(int k=0;k<2;k++)
            {
                int b=0;
                b=(bool)(i&(1<<k))+(bool)(i&(1<<(k+1)));
                b+=(bool)(j&(1<<k))+(bool)(j&(1<<(k+1)));
                if(b%2==0) foo=1;
            }
            if(!foo)wor[i][j]=1;
        }
    }
}
void solve()
{
    ll n,k=0,val=0,m=1,i=0,j=0,l=-1,x,y,z;
    ll ans=0;
    string sa[105];
    cin>>n>>m;
    for(i=0;i<n;i++) cin>>sa[i];
    if(n>=4)
    {
        cout<<"-1\n";
        return;
    }
    for(i=0;i<n;i++)
        for(j=0;j<m;j++)
            s[i][j]=sa[i][j]-'0';
    if(n==1)
        ans = 0;
    if(n==2)
    {
        ll ee=0,oo=0;
        for(i=0;i<m;i++)
        {
            val=s[0][i]=='0'^s[1][i]=='0';
            if(val==i%2) ee++;
            else oo++;
        }
        ans=min(ee,oo);
    }
    if(n==3)
    {
        work();
        for(i=1;i<=m;i++)
        {
		    int mask=s[0][i-1]+2*s[1][i-1]+4*s[2][i-1];
		    for(j=0;j<8;j++)
            {
			    dp[i][j]=1e9;
                for(k=0;k<8;k++)
                {
                if(!wor[j][k])continue;
                    dp[i][j]=min(dp[i][j],dp[i-1][k]+__builtin_popcount(j^mask));
		        }
            }
	    }
        ans=*min_element(dp[m]+1,dp[m]+8);
    }
    cout<<ans<<endl;
}
int main()
{
    #ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin) ;
    freopen("output.txt", "w", stdout) ;
    #endif
    ios::sync_with_stdio(0),cin.tie(NULL),cout.tie(NULL);
    int t=1;
    //cin>>t;
    while(t--)solve();
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define all(v) v.begin(), v.end()
#define vll vector<ll>
#define pb push_back
#define ff first
#define ss
const int N=1000005;
bool wor[8][8]={};
ll dp[4][N]{};
bool s[4][N]{};
bool work()
{
    for(int i=0;i<8;i++)
    {
        for(int j=0;j<8;j++)
        {
            int foo=0;
            for(int k=0;k<2;k++)
            {
                int b=0;
                b=(bool)(i&(1<<k))+(bool)(i&(1<<(k+1)));
                b+=(bool)(j&(1<<k))+(bool)(j&(1<<(k+1)));
                if(b%2==0) foo=1;
            }
            if(!foo)wor[i][j]=1;
        }
    }
}
void solve()
{
    ll n,k=0,val=0,m=1,i=0,j=0,l=-1,x,y,z;
    ll ans=0;
    string sa[105];
    cin>>n>>m;
    for(i=0;i<n;i++) cin>>sa[i];
    if(n>=4)
    {
        cout<<"-1\n";
        return;
    }
    if(n==1)
        ans = 0;
    if(n==2)
    {
        for(i=0;i<n;i++)
        for(j=0;j<m;j++)
            s[i][j]=sa[i][j]-'0';
        ll ee=0,oo=0;
        for(i=0;i<m;i++)
        {
            val=s[0][i]=='0'^s[1][i]=='0';
            if(val==i%2) ee++;
            else oo++;
        }
        ans=min(ee,oo);
    }
    if(n==3)
    {
        work();
        for(i=1;i<=m;i++)
        {
		    int mask=s[0][i-1]+2*s[1][i-1]+4*s[2][i-1];
		    for(j=0;j<8;j++)
            {
			    dp[i][j]=1e9;
                for(k=0;k<8;k++)
                {
                if(!wor[j][k])continue;
                    dp[i][j]=min(dp[i][j],dp[i-1][k]+__builtin_popcount(j^mask));
		        }
            }
	    }
        ans=*min_element(dp[m]+1,dp[m]+8);
    }
    cout<<ans<<endl;
}
int main()
{
    #ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin) ;
    freopen("output.txt", "w", stdout) ;
    #endif
    ios::sync_with_stdio(0),cin.tie(NULL),cout.tie(NULL);
    int t=1;
    //cin>>t;
    while(t--)solve();
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define all(v) v.begin(), v.end()
#define vll vector<ll>
#define pb push_back
#define ff first
#define ss
const int N=1000005;
bool wor[8][8]={};
ll dp[N][8]{};
bool s[4][N]{};
bool work()
{
    for(int i=0;i<8;i++)
    {
        for(int j=0;j<8;j++)
        {
            int foo=0;
            for(int k=0;k<2;k++)
            {
                int b=0;
                b=(bool)(i&(1<<k))+(bool)(i&(1<<(k+1)));
                b+=(bool)(j&(1<<k))+(bool)(j&(1<<(k+1)));
                if(b%2==0) foo=1;
            }
            if(!foo)wor[i][j]=1;
        }
    }
}
void solve()
{
    ll n,k=0,val=0,m=1,i=0,j=0,l=-1,x,y,z;
    ll ans=0;
    string sa[105];
    cin>>n>>m;
    for(i=0;i<n;i++) cin>>sa[i];
    if(n>=4)
    {
        cout<<"-1\n";
        return;
    }
    for(i=0;i<n;i++)
        for(j=0;j<m;j++)
            s[i][j]=sa[i][j]-'0';
    if(n==1)
        ans = 0;
    if(n==2)
    {
        ll ee=0,oo=0;
        for(i=0;i<m;i++)
        {
            val=s[0][i]=='0'^s[1][i]=='0';
            if(val==i%2) ee++;
            else oo++;
        }
        ans=min(ee,oo);
    }
    if(n==3)
    {
        work();
        for(i=1;i<=m;i++)
        {
		    int mask=s[0][i-1]+2*s[1][i-1]+4*s[2][i-1];
		    for(j=0;j<8;j++)
            {
			    dp[i][j]=1e9;
                for(k=0;k<8;k++)
                if(wor[j][k])
                    dp[i][j]=min(dp[i][j],dp[i-1][k]+__builtin_popcount(j^mask));
            }
	    }
        ans=*min_element(dp[m],dp[m]+8);
    }
    cout<<ans<<endl;
}
int main()
{
    #ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin) ;
    freopen("output.txt", "w", stdout) ;
    #endif
    ios::sync_with_stdio(0),cin.tie(NULL),cout.tie(NULL);
    int t=1;
    //cin>>t;
    while(t--)solve();
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define all(v) v.begin(), v.end()
#define vll vector<ll>
#define pb push_back
#define ff first
#define ss
const int N=1000005;
bool wor[8][8]={};
ll dp[N][8]{};
bool s[4][N]{};
bool work()
{
    for(int i=0;i<8;i++)
    {
        for(int j=0;j<8;j++)
        {
            int foo=0;
            for(int k=0;k<2;k++)
            {
                int b=0;
                b=(bool)(i&(1<<k))+(bool)(i&(1<<(k+1)));
                b+=(bool)(j&(1<<k))+(bool)(j&(1<<(k+1)));
                if(b%2==0) foo=1;
            }
            if(!foo)wor[i][j]=1;
        }
    }
}
void solve()
{
    ll n,k=0,val=0,m=1,i=0,j=0,l=-1,x,y,z;
    ll ans=0;
    string sa[105];
    cin>>n>>m;
    for(i=0;i<n;i++) cin>>sa[i];
    if(n>=4)
    {
        cout<<"-1\n";
        return;
    }
    for(i=0;i<n;i++)
        for(j=0;j<m;j++)
            s[i][j]=sa[i][j]-'0';
    if(n==1)
        ans = 0;
    if(n==2)
    {
        ll ee=0,oo=0;
        for(i=0;i<m;i++)
        {
            val=s[0][i]^s[1][i];
            if(val==i%2) ee++;
            else oo++;
        }
        ans=min(ee,oo);
    }
    if(n==3)
    {
        work();
        for(i=1;i<=m;i++)
        {
		    int mask=s[0][i-1]+2*s[1][i-1]+4*s[2][i-1];
		    for(j=0;j<8;j++)
            {
			    dp[i][j]=1e9;
                for(k=0;k<8;k++)
                if(wor[j][k])
                    dp[i][j]=min(dp[i][j],dp[i-1][k]+__builtin_popcount(j^mask));
            }
	    }
        ans=*min_element(dp[m],dp[m]+8);
    }
    cout<<ans<<endl;
}
int main()
{
    #ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin) ;
    freopen("output.txt", "w", stdout) ;
    #endif
    ios::sync_with_stdio(0),cin.tie(NULL),cout.tie(NULL);
    int t=1;
    //cin>>t;
    while(t--)solve();
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define all(v) v.begin(), v.end()
#define vll vector<ll>
#define pb push_back
#define ff first
#define ss
const int N=100005;
bool wor[8][8]={};
bool work()
{
    for(int i=0;i<8;i++)
    {
        for(int j=0;j<8;j++)
        {
            int foo=0;
            for(int k=0;k<2;k++)
            {
                int b=0;
                b=(bool)(i&(1<<k))+(bool)(i&(1<<(k+1)));
                b+=(bool)(j&(1<<k))+(bool)(j&(1<<(k+1)));
                if(b%2==0) foo=1;
            }
            if(!foo)wor[i][j]=1;
        }
    }
}
void solve()
{
    ll n,k=0,val=0,m=1,i=0,j=0,l=-1,x,y,z;
    ll ans=0;
    bool a[105][105];
    string sa[105];
    bool s[105][105];
    cin>>n>>m;
    for(i=0;i<n;i++) cin>>sa[i];
    for(i=0;i<n;i++)
        for(j=0;j<m;j++)
            s[i][j]=sa[i][j]-'0';
    if(n==1)
        ans = 0;
    if(n>=4)
        ans=-1;
    if(n==2)
    {
        ll ee=0,oo=0;
        for(i=0;i<m;i++)
        {
            val=s[0][i]=='0'^s[1][i]=='0';
            if(val==i%2) ee++;
            else oo++;
        }
        ans=min(ee,oo);
    }
    if(n==3)
    {
        work();
        ll dp[105][8]={};
        for(i=1;i<=m;i++)
        {
		    int mask=s[0][i-1]+2*s[1][i-1]+4*s[2][i-1];
		    for(j=0;j<8;j++)
            {
			    dp[i][j]=1e9;
                for(k=0;k<8;k++)
                if(wor[j][k])
                    dp[i][j]=min(dp[i][j],dp[i-1][k]+__builtin_popcount(j^mask));
		    }
	    }
        ans=*min_element(dp[m]+1,dp[m]+8);
    }
    cout<<ans<<endl;
}
int main()
{
    #ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin) ;
    freopen("output.txt", "w", stdout) ;
    #endif
    ios::sync_with_stdio(0),cin.tie(NULL),cout.tie(NULL);
    int t=1;
    //cin>>t;
    while(t--)solve();
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define all(v) v.begin(), v.end()
#define vll vector<ll>
#define pb push_back
#define ff first
#define ss
const int N=100005;
bool work(ll i, ll j)
{
    for(int k=0;k<2;k++)
    {
        int b=0;
        b=(bool)(i&(1<<k))+(bool)(i&(1<<(k+1)));
        b+=(bool)(j&(1<<k))+(bool)(j&(1<<(k+1)));
        if(b%2==0) return 0;
    }
    return 1;
}
void solve()
{
    ll n,k=0,val=0,m=1,i=0,j=0,l=-1,x,y,z;
    ll ans=0;
    bool a[105][105];
    string sa[105];
    bool s[105][105];
    cin>>n>>m;
    for(i=0;i<n;i++) cin>>sa[i];
    for(i=0;i<n;i++)
        for(j=0;j<m;j++)
            s[i][j]=sa[i][j]-'0';
    if(n==1)
        ans = 0;
    if(n>=4)
        ans=-1;
    if(n==2)
    {
        ll ee=0,oo=0;
        for(i=0;i<m;i++)
        {
            val=s[0][i]=='0'^s[1][i]=='0';
            if(val==i%2) ee++;
            else oo++;
        }
        ans=min(ee,oo);
    }
    if(n==3)
    {
        ll dp[105][8]={};
        for(i=1;i<=m;i++)
        {
		    int mask=s[0][i-1]+2*s[1][i-1]+4*s[2][i-1];
		    for(j=0;j<8;j++)
            {
			    dp[i][j]=INT32_MAX;
                for(k=0;k<8;k++)
                if(work(j,k))
                    dp[i][j]=min(dp[i][j],dp[i-1][k]+__builtin_popcount(j^mask));
		    }
	    }
        ans=*min_element(dp[m],dp[m]+8);
    }
    cout<<ans<<endl;
}
int main()
{
    #ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin) ;
    freopen("output.txt", "w", stdout) ;
    #endif
    ios::sync_with_stdio(0),cin.tie(NULL),cout.tie(NULL);
    int t=1;
    //cin>>t;
    while(t--)solve();
    return 0;
}


/**
 *    author:  otera
**/
#include<iostream>
#include<string>
#include<cstdio>
#include<cstring>
#include<vector>
#include<cmath>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<queue>
#include<deque>
#include<ciso646>
#include<random>
#include<map>
#include<set>
#include<complex>
#include<bitset>
#include<stack>
#include<unordered_map>
#include<utility>
#include<cassert>
using namespace std;

//#define int long long
typedef long long ll;
typedef unsigned long long ul;
typedef unsigned int ui;
typedef long double ld;
const int inf=1e9+7;
const ll INF=1LL<<60 ;
const ll mod=1e9+7 ;
#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define Rep(i,sta,n) for(int i=sta;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define per1(i,n) for(int i=n;i>=1;i--)
#define Rep1(i,sta,n) for(int i=sta;i<=n;i++)
typedef complex<ld> Point;
const ld eps = 1e-8;
const ld pi = acos(-1.0);
typedef pair<int, int> P;
typedef pair<ld, ld> LDP;
typedef pair<ll, ll> LP;
#define fr first
#define sc second
#define all(c) c.begin(),c.end()
#define pb push_back
#define debug(x)  cerr << #x << " = " << (x) << endl;
template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }

int n, m;
vector<vector<char>> a;

void solve() {
	cin >> n >> m;
    a.assign(n, vector<char>(m));
    rep(i, n) {
        rep(j, m) {
            cin >> a[i][j];
        }
    }
    // n >= m
    if(m > n) {
        swap(n, m);
        vector<vector<char>> b(n, vector<char>(m));
        rep(i, n) {
            rep(j, m) {
                b[i][j] = a[j][i];
            }
        }
        swap(a, b);
    }
    if(m >= 4) {
        cout << -1 << endl;
        return;
    }
    vector<vector<int>> dp(m, vector<int>((1<<n), inf));
    vector<vector<int>> to((1<<n));
    rep(bit, (1<<n)) {
        rep(bit2, (1<<n)) {
            bool check = 1;
            rep(j, n - 1) {
                int c = 0;
                c += (1 & (bit>>(j + 1)));
                c += (1 & (bit>>j));
                c += (1 & (bit2>>(j + 1)));
                c += (1 & (bit2>>j));
                if(c % 2 == 0) check = 0;
            }
            if(check) to[bit].pb(bit2);
        }
    }
    rep(i, (1<<n)) {
        int co = 0;
        rep(j, n) {
            if(i & (1<<j)) {if(a[0][j] == '0') ++ co;}
            else {if(a[0][j] == '1') ++ co;}
        }
        dp[0][i] = co;
    }
    for(int i = 1; i < m; ++ i) {
        rep(bit, (1<<n)) {
            for(int bit2: to[bit]) {
                int co = 0;
                rep(j, n) {
                    if(bit2 & (1<<j)) {if(a[i][j] == '0') ++ co;}
                    else {if(a[i][j] == '1') ++ co;}
                }
                chmin(dp[i][bit2], dp[i - 1][bit] + co);
            }
        }
    }
    int ret = inf;
    rep(i, (1<<n)) {
        chmin(ret, dp[m - 1][i]);
    }
    if(ret == inf) cout << -1 << endl;
    else cout << ret << endl;
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	//cout << fixed << setprecision(10);
	//int t; cin >> t; rep(i, t)solve();
	solve();
    return 0;
}


/**
 *    author:  otera
**/
#include<iostream>
#include<string>
#include<cstdio>
#include<cstring>
#include<vector>
#include<cmath>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<queue>
#include<deque>
#include<ciso646>
#include<random>
#include<map>
#include<set>
#include<complex>
#include<bitset>
#include<stack>
#include<unordered_map>
#include<utility>
#include<cassert>
using namespace std;

//#define int long long
typedef long long ll;
typedef unsigned long long ul;
typedef unsigned int ui;
typedef long double ld;
const int inf=1e9+7;
const ll INF=1LL<<60 ;
const ll mod=1e9+7 ;
#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define Rep(i,sta,n) for(int i=sta;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define per1(i,n) for(int i=n;i>=1;i--)
#define Rep1(i,sta,n) for(int i=sta;i<=n;i++)
typedef complex<ld> Point;
const ld eps = 1e-8;
const ld pi = acos(-1.0);
typedef pair<int, int> P;
typedef pair<ld, ld> LDP;
typedef pair<ll, ll> LP;
#define fr first
#define sc second
#define all(c) c.begin(),c.end()
#define pb push_back
#define debug(x)  cerr << #x << " = " << (x) << endl;
template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }

int n, m;
vector<vector<char>> a;

void solve() {
	cin >> n >> m;
    a.assign(n, vector<char>(m));
    rep(i, n) {
        rep(j, m) {
            cin >> a[i][j];
        }
    }
    if(n >= 4) {
        cout << -1 << endl;
        return;
    }
    vector<vector<int>> dp(m, vector<int>((1<<n), inf));
    vector<vector<int>> to((1<<n));
    rep(bit, (1<<n)) {
        rep(bit2, (1<<n)) {
            bool check = 1;
            rep(j, n - 1) {
                int c = 0;
                c += (1 & (bit>>(j + 1)));
                c += (1 & (bit>>j));
                c += (1 & (bit2>>(j + 1)));
                c += (1 & (bit2>>j));
                if(c % 2 == 0) check = 0;
            }
            if(check) to[bit].pb(bit2);
        }
    }
    rep(i, (1<<n)) {
        int co = 0;
        rep(j, n) {
            if(i & (1<<j)) {if(a[j][0] == '0') ++ co;}
            else {if(a[j][0] == '1') ++ co;}
        }
        dp[0][i] = co;
    }
    for(int i = 1; i < m; ++ i) {
        rep(bit, (1<<n)) {
            for(int bit2: to[bit]) {
                int co = 0;
                rep(j, n) {
                    if(bit2 & (1<<j)) {if(a[j][i] == '0') ++ co;}
                    else if(!(bit2 & (1<<j))) {if(a[j][i] == '1') ++ co;}
                }
                chmin(dp[i][bit2], dp[i - 1][bit] + co);
            }
        }
    }
    int ret = inf;
    rep(i, (1<<n)) {
        chmin(ret, dp[m - 1][i]);
    }
    if(ret == inf) cout << -1 << endl;
    else cout << ret << endl;
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	//cout << fixed << setprecision(10);
	//int t; cin >> t; rep(i, t)solve();
	solve();
    return 0;
}


/**
 *    author:  otera
**/
#include<iostream>
#include<string>
#include<cstdio>
#include<cstring>
#include<vector>
#include<cmath>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<queue>
#include<deque>
#include<ciso646>
#include<random>
#include<map>
#include<set>
#include<complex>
#include<bitset>
#include<stack>
#include<unordered_map>
#include<utility>
#include<cassert>
using namespace std;

//#define int long long
typedef long long ll;
typedef unsigned long long ul;
typedef unsigned int ui;
typedef long double ld;
const int inf=1e9+7;
const ll INF=1LL<<60 ;
const ll mod=1e9+7 ;
#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define Rep(i,sta,n) for(int i=sta;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define per1(i,n) for(int i=n;i>=1;i--)
#define Rep1(i,sta,n) for(int i=sta;i<=n;i++)
typedef complex<ld> Point;
const ld eps = 1e-8;
const ld pi = acos(-1.0);
typedef pair<int, int> P;
typedef pair<ld, ld> LDP;
typedef pair<ll, ll> LP;
#define fr first
#define sc second
#define all(c) c.begin(),c.end()
#define pb push_back
#define debug(x)  cerr << #x << " = " << (x) << endl;
template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }

int n, m;
vector<vector<char>> a;

void solve() {
	cin >> n >> m;
    a.assign(n, vector<char>(m));
    rep(i, n) {
        rep(j, m) {
            cin >> a[i][j];
        }
    }
    if(n >= 4 || m >= 4) {
        cout << -1 << endl;
        return;
    }
    int ans = inf;
    for(int bit = 0; bit < (1<<(n * m)); ++ bit) {
        vector<vector<char>> b(n, vector<char>(m, '0'));
        rep(i, n * m) {
            if(bit & (1<<i)) {
                int x = i / n, y = i % n;
                b[x][y] = '1';
            }
        }
        int cnt = 0;
        rep(i, n) {
            rep(j, m) {
                if(a[i][j] != b[i][j]) ++ cnt;
            }
        }
        bool check = 1;
        rep(i, 2) {
            rep(j, 2) {
                if(i + 1 < n && j + 1 < m) {
                    int co = 0;
                    rep(x, 2) {
                        rep(y, 2) {
                            if(b[i + x][j + y] == '1') ++ co;
                        }
                    }
                    if(co % 2 == 0) check = 0;
                }
            }
        }
        if(check) chmin(ans, cnt);
    }
    if(ans == inf) cout << -1 << endl;
    else cout << ans << endl;
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	//cout << fixed << setprecision(10);
	//int t; cin >> t; rep(i, t)solve();
	solve();
    return 0;
}


/**
 *    author:  otera
**/
#include<iostream>
#include<string>
#include<cstdio>
#include<cstring>
#include<vector>
#include<cmath>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<queue>
#include<deque>
#include<ciso646>
#include<random>
#include<map>
#include<set>
#include<complex>
#include<bitset>
#include<stack>
#include<unordered_map>
#include<utility>
#include<cassert>
using namespace std;

//#define int long long
typedef long long ll;
typedef unsigned long long ul;
typedef unsigned int ui;
typedef long double ld;
const int inf=1e9+7;
const ll INF=1LL<<60 ;
const ll mod=1e9+7 ;
#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define Rep(i,sta,n) for(int i=sta;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define per1(i,n) for(int i=n;i>=1;i--)
#define Rep1(i,sta,n) for(int i=sta;i<=n;i++)
typedef complex<ld> Point;
const ld eps = 1e-8;
const ld pi = acos(-1.0);
typedef pair<int, int> P;
typedef pair<ld, ld> LDP;
typedef pair<ll, ll> LP;
#define fr first
#define sc second
#define all(c) c.begin(),c.end()
#define pb push_back
#define debug(x)  cerr << #x << " = " << (x) << endl;
template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }

int n, m;
vector<vector<char>> a;

void solve() {
	cin >> n >> m;
    a.assign(n, vector<char>(m));
    rep(i, n) {
        rep(j, m) {
            cin >> a[i][j];
        }
    }
    // n >= m
    if(m > n) {
        swap(n, m);
        vector<vector<char>> b(n, vector<char>(m));
        rep(i, n) {
            rep(j, m) {
                b[i][j] = a[j][i];
            }
        }
        swap(a, b);
    }
    if(m >= 4) {
        cout << -1 << endl;
        return;
    }
    vector<vector<int>> dp(m, vector<int>((1<<n), inf));
    vector<vector<int>> to((1<<n));
    vector<int> co((1<<n), 0);
    rep(bit, (1<<n)) {
        rep(bit2, (1<<n)) {
            bool check = 1;
            rep(j, n - 1) {
                int c = 0;
                c += (1 & (bit>>(j + 1)));
                c += (1 & (bit>>j));
                c += (1 & (bit2>>(j + 1)));
                c += (1 & (bit2>>j));
                if(c % 2 == 0) check = 0;
            }
            if(check) to[bit].pb(bit2);
        }
    }
    rep(i, (1<<n)) {
        int co = 0;
        rep(j, n) {
            if(i & (1<<j)) {if(a[0][j] == '0') ++ co;}
            else {if(a[0][j] == '1') ++ co;}
        }
        dp[0][i] = co;
    }
    for(int i = 1; i < m; ++ i) {
        rep(bit, (1<<n)) {
            for(int bit2: to[bit]) {
                int co = 0;
                chmin(dp[i][bit2], dp[i - 1][bit] + co);
            }
        }
    }
    int ret = inf;
    rep(i, (1<<n)) {
        chmin(ret, dp[m - 1][i]);
    }
    if(ret == inf) cout << -1 << endl;
    else cout << 2 << endl;
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	//cout << fixed << setprecision(10);
	//int t; cin >> t; rep(i, t)solve();
	solve();
    return 0;
}


/**
 *    author:  otera
**/
#include<iostream>
#include<string>
#include<cstdio>
#include<cstring>
#include<vector>
#include<cmath>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<queue>
#include<deque>
#include<ciso646>
#include<random>
#include<map>
#include<set>
#include<complex>
#include<bitset>
#include<stack>
#include<unordered_map>
#include<utility>
#include<cassert>
using namespace std;

//#define int long long
typedef long long ll;
typedef unsigned long long ul;
typedef unsigned int ui;
typedef long double ld;
const int inf=1e9+7;
const ll INF=1LL<<60 ;
const ll mod=1e9+7 ;
#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define Rep(i,sta,n) for(int i=sta;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define per1(i,n) for(int i=n;i>=1;i--)
#define Rep1(i,sta,n) for(int i=sta;i<=n;i++)
typedef complex<ld> Point;
const ld eps = 1e-8;
const ld pi = acos(-1.0);
typedef pair<int, int> P;
typedef pair<ld, ld> LDP;
typedef pair<ll, ll> LP;
#define fr first
#define sc second
#define all(c) c.begin(),c.end()
#define pb push_back
#define debug(x)  cerr << #x << " = " << (x) << endl;
template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }

int n, m;
vector<vector<char>> a;

void solve() {
	cin >> n >> m;
    a.assign(n, vector<char>(m));
    rep(i, n) {
        rep(j, m) {
            cin >> a[i][j];
        }
    }
    // n >= m
    if(m > n) {
        swap(n, m);
        vector<vector<char>> b(n, vector<char>(m));
        rep(i, n) {
            rep(j, m) {
                b[i][j] = a[j][i];
            }
        }
        swap(a, b);
    }
    if(m >= 4) {
        cout << -1 << endl;
        return;
    }
    vector<vector<int>> dp(m, vector<int>((1<<n), inf));
    rep(i, (1<<n)) {
        int co = 0;
        rep(j, n) {
            if(i & (1<<j)) {if(a[0][j] == '0') ++ co;}
            else {if(a[0][j] == '1') ++ co;}
        }
        dp[0][i] = co;
    }
    for(int i = 1; i < m; ++ i) {
        rep(bit, (1<<n)) {
            rep(bit2, (1<<n)) {
                int co = 0;
                rep(j, n) {
                    if(bit2 & (1<<j)) {if(a[i][j] == '0') ++ co;}
                    else {if(a[i][j] == '1') ++ co;}
                }
                bool check = 1;
                rep(j, n - 1) {
                    int c = 0;
                    c += (1 & (bit>>(j + 1)));
                    c += (1 & (bit>>j));
                    c += (1 & (bit2>>(j + 1)));
                    c += (1 & (bit2>>j));
                    if(c % 2 == 0) check = 0;
                }
                if(check) chmin(dp[i][bit2], dp[i - 1][bit] + co);
            }
        }
    }
    int ret = inf;
    rep(i, (1<<n)) {
        chmin(ret, dp[m - 1][i]);
    }
    if(ret == inf) cout << -1 << endl;
    else cout << ret << endl;
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	//cout << fixed << setprecision(10);
	//int t; cin >> t; rep(i, t)solve();
	solve();
    return 0;
}


/**
 *    author:  otera
**/
#include<iostream>
#include<string>
#include<cstdio>
#include<cstring>
#include<vector>
#include<cmath>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<queue>
#include<deque>
#include<ciso646>
#include<random>
#include<map>
#include<set>
#include<complex>
#include<bitset>
#include<stack>
#include<unordered_map>
#include<utility>
#include<cassert>
using namespace std;

//#define int long long
typedef long long ll;
typedef unsigned long long ul;
typedef unsigned int ui;
typedef long double ld;
const int inf=1e9+7;
const ll INF=1LL<<60 ;
const ll mod=1e9+7 ;
#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define Rep(i,sta,n) for(int i=sta;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define per1(i,n) for(int i=n;i>=1;i--)
#define Rep1(i,sta,n) for(int i=sta;i<=n;i++)
typedef complex<ld> Point;
const ld eps = 1e-8;
const ld pi = acos(-1.0);
typedef pair<int, int> P;
typedef pair<ld, ld> LDP;
typedef pair<ll, ll> LP;
#define fr first
#define sc second
#define all(c) c.begin(),c.end()
#define pb push_back
#define debug(x)  cerr << #x << " = " << (x) << endl;
template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }

int n, m;
vector<vector<char>> a;

void solve() {
	cin >> n >> m;
    a.assign(n, vector<char>(m));
    rep(i, n) {
        rep(j, m) {
            cin >> a[i][j];
        }
    }
    // n >= m
    if(m > n) {
        swap(n, m);
        vector<vector<char>> b(n, vector<char>(m));
        rep(i, n) {
            rep(j, m) {
                b[i][j] = a[j][i];
            }
        }
        swap(a, b);
    }
    if(n >= 4) {
        cout << -1 << endl;
        return;
    }
    vector<vector<int>> dp(m, vector<int>((1<<n), inf));
    rep(i, (1<<n)) {
        int co = 0;
        rep(j, n) {
            if(i & (1<<j)) {if(a[0][j] == '0') ++ co;}
            else {if(a[0][j] == '1') ++ co;}
        }
        dp[0][i] = co;
    }
    for(int i = 1; i < m; ++ i) {
        rep(bit, (1<<n)) {
            rep(bit2, (1<<n)) {
                int co = 0;
                rep(j, n) {
                    if(bit2 & (1<<j)) {if(a[i][j] == '0') ++ co;}
                    else {if(a[i][j] == '1') ++ co;}
                }
                bool check = 1;
                rep(j, n - 1) {
                    int c = 0;
                    c += (1 & (bit>>(j + 1)));
                    c += (1 & (bit>>j));
                    c += (1 & (bit2>>(j + 1)));
                    c += (1 & (bit2>>j));
                    if(c % 2 == 0) check = 0;
                }
                if(check) chmin(dp[i][bit2], dp[i - 1][bit] + co);
            }
        }
    }
    int ret = inf;
    rep(i, (1<<n)) {
        chmin(ret, dp[m - 1][i]);
    }
    if(ret == inf) cout << -1 << endl;
    else cout << ret << endl;
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	//cout << fixed << setprecision(10);
	//int t; cin >> t; rep(i, t)solve();
	solve();
    return 0;
}


/**
 *    author:  otera
**/
#include<iostream>
#include<string>
#include<cstdio>
#include<cstring>
#include<vector>
#include<cmath>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<queue>
#include<deque>
#include<ciso646>
#include<random>
#include<map>
#include<set>
#include<complex>
#include<bitset>
#include<stack>
#include<unordered_map>
#include<utility>
#include<cassert>
using namespace std;

//#define int long long
typedef long long ll;
typedef unsigned long long ul;
typedef unsigned int ui;
typedef long double ld;
const int inf=1e9+7;
const ll INF=1LL<<60 ;
const ll mod=1e9+7 ;
#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define Rep(i,sta,n) for(int i=sta;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define per1(i,n) for(int i=n;i>=1;i--)
#define Rep1(i,sta,n) for(int i=sta;i<=n;i++)
typedef complex<ld> Point;
const ld eps = 1e-8;
const ld pi = acos(-1.0);
typedef pair<int, int> P;
typedef pair<ld, ld> LDP;
typedef pair<ll, ll> LP;
#define fr first
#define sc second
#define all(c) c.begin(),c.end()
#define pb push_back
#define debug(x)  cerr << #x << " = " << (x) << endl;
template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }

int n, m;
vector<vector<char>> a;

void solve() {
	cin >> n >> m;
    a.assign(n, vector<char>(m));
    rep(i, n) {
        rep(j, m) {
            cin >> a[i][j];
        }
    }
    // n >= m
    if(m > n) {
        swap(n, m);
        vector<vector<char>> b(n, vector<char>(m));
        rep(i, n) {
            rep(j, m) {
                b[i][j] = a[j][i];
            }
        }
        swap(a, b);
    }
    if(m >= 4) {
        cout << -1 << endl;
        return;
    }
    vector<vector<int>> dp(m, vector<int>((1<<n), inf));
    vector<vector<int>> to((1<<n));
    vector<int> co((1<<n), 0);
    rep(bit, (1<<n)) {
        rep(bit2, (1<<n)) {
            bool check = 1;
            rep(j, n - 1) {
                int c = 0;
                c += (1 & (bit>>(j + 1)));
                c += (1 & (bit>>j));
                c += (1 & (bit2>>(j + 1)));
                c += (1 & (bit2>>j));
                if(c % 2 == 0) check = 0;
            }
            if(check) to[bit].pb(bit2);
        }
    }
    rep(i, (1<<n)) {
        int co = 0;
        rep(j, n) {
            if(i & (1<<j)) {if(a[0][j] == '0') ++ co;}
            else {if(a[0][j] == '1') ++ co;}
        }
        dp[0][i] = co;
    }
    for(int i = 1; i < m; ++ i) {
        rep(bit, (1<<n)) {
            for(int bit2: to[bit]) {
                int co = 0;
                rep(j, n) {
                    if(bit2 & (1<<j)) {if(a[i][j] == '0') ++ co;}
                    else {if(a[i][j] == '1') ++ co;}
                }
                chmin(dp[i][bit2], dp[i - 1][bit] + co);
            }
        }
    }
    int ret = inf;
    rep(i, (1<<n)) {
        chmin(ret, dp[m - 1][i]);
    }
    if(ret == inf) cout << -1 << endl;
    else cout << 2 << endl;
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	//cout << fixed << setprecision(10);
	//int t; cin >> t; rep(i, t)solve();
	solve();
    return 0;
}


/**
 *    author:  otera
**/
#include<iostream>
#include<string>
#include<cstdio>
#include<cstring>
#include<vector>
#include<cmath>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<queue>
#include<deque>
#include<ciso646>
#include<random>
#include<map>
#include<set>
#include<complex>
#include<bitset>
#include<stack>
#include<unordered_map>
#include<utility>
#include<cassert>
using namespace std;

//#define int long long
typedef long long ll;
typedef unsigned long long ul;
typedef unsigned int ui;
typedef long double ld;
const int inf=1e9+7;
const ll INF=1LL<<60 ;
const ll mod=1e9+7 ;
#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define Rep(i,sta,n) for(int i=sta;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define per1(i,n) for(int i=n;i>=1;i--)
#define Rep1(i,sta,n) for(int i=sta;i<=n;i++)
typedef complex<ld> Point;
const ld eps = 1e-8;
const ld pi = acos(-1.0);
typedef pair<int, int> P;
typedef pair<ld, ld> LDP;
typedef pair<ll, ll> LP;
#define fr first
#define sc second
#define all(c) c.begin(),c.end()
#define pb push_back
#define debug(x)  cerr << #x << " = " << (x) << endl;
template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }

int n, m;
vector<vector<char>> a;

void solve() {
	cin >> n >> m;
    a.assign(n, vector<char>(m));
    rep(i, n) {
        rep(j, m) {
            cin >> a[i][j];
        }
    }
    if(m < n) {
        swap(n, m);
        vector<vector<char>> b(n, vector<char>(m));
        rep(i, n) {
            rep(j, m) {
                b[i][j] = a[j][i];
            }
        }
        swap(a, b);
    }
    if(n >= 4) {
        cout << -1 << endl;
        return;
    }
    vector<vector<int>> dp(m, vector<int>((1<<n), inf));
    vector<vector<int>> to((1<<n));
    vector<int> co((1<<n), 0);
    rep(bit, (1<<n)) {
        rep(bit2, (1<<n)) {
            bool check = 1;
            rep(j, n - 1) {
                int c = 0;
                c += (1 & (bit>>(j + 1)));
                c += (1 & (bit>>j));
                c += (1 & (bit2>>(j + 1)));
                c += (1 & (bit2>>j));
                if(c % 2 == 0) check = 0;
            }
            if(check) to[bit].pb(bit2);
        }
    }
    rep(i, (1<<n)) {
        int co = 0;
        rep(j, n) {
            if(i & (1<<j)) {if(a[0][j] == '0') ++ co;}
            else {if(a[0][j] == '1') ++ co;}
        }
        dp[0][i] = co;
    }
    for(int i = 1; i < m; ++ i) {
        rep(bit, (1<<n)) {
            for(int bit2: to[bit]) {
                int co = 0;
                rep(j, n) {
                    if(bit2 & (1<<j)) {if(a[i][j] == '0') ++ co;}
                    else {if(a[i][j] == '1') ++ co;}
                }
                chmin(dp[i][bit2], dp[i - 1][bit] + co);
            }
        }
    }
    int ret = inf;
    rep(i, (1<<n)) {
        chmin(ret, dp[m - 1][i]);
    }
    if(ret == inf) cout << -1 << endl;
    else cout << ret << endl;
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	//cout << fixed << setprecision(10);
	//int t; cin >> t; rep(i, t)solve();
	solve();
    return 0;
}


/**
 *    author:  otera
**/
#include<iostream>
#include<string>
#include<cstdio>
#include<cstring>
#include<vector>
#include<cmath>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<queue>
#include<deque>
#include<ciso646>
#include<random>
#include<map>
#include<set>
#include<complex>
#include<bitset>
#include<stack>
#include<unordered_map>
#include<utility>
#include<cassert>
using namespace std;

//#define int long long
typedef long long ll;
typedef unsigned long long ul;
typedef unsigned int ui;
typedef long double ld;
const int inf=1e9+7;
const ll INF=1LL<<60 ;
const ll mod=1e9+7 ;
#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define Rep(i,sta,n) for(int i=sta;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define per1(i,n) for(int i=n;i>=1;i--)
#define Rep1(i,sta,n) for(int i=sta;i<=n;i++)
typedef complex<ld> Point;
const ld eps = 1e-8;
const ld pi = acos(-1.0);
typedef pair<int, int> P;
typedef pair<ld, ld> LDP;
typedef pair<ll, ll> LP;
#define fr first
#define sc second
#define all(c) c.begin(),c.end()
#define pb push_back
#define debug(x)  cerr << #x << " = " << (x) << endl;
template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }

int n, m;
vector<vector<char>> a;

void solve() {
	cin >> n >> m;
    a.assign(n, vector<char>(m));
    rep(i, n) {
        rep(j, m) {
            cin >> a[i][j];
        }
    }
    if(n >= 4) {
        cout << -1 << endl;
        return;
    }
    vector<vector<int>> dp(m, vector<int>((1<<n), inf));
    vector<vector<int>> to((1<<n));
    rep(bit, (1<<n)) {
        rep(bit2, (1<<n)) {
            bool check = 1;
            rep(j, n - 1) {
                int c = 0;
                c += (1 & (bit>>(j + 1)));
                c += (1 & (bit>>j));
                c += (1 & (bit2>>(j + 1)));
                c += (1 & (bit2>>j));
                if(c % 2 == 0) check = 0;
            }
            if(check) to[bit].pb(bit2);
        }
    }
    rep(i, (1<<n)) {
        int co = 0;
        rep(j, n) {
            if(i & (1<<j)) {if(a[0][j] == '0') ++ co;}
            else {if(a[0][j] == '1') ++ co;}
        }
        dp[0][i] = co;
    }
    for(int i = 1; i < m; ++ i) {
        rep(bit, (1<<n)) {
            for(int bit2: to[bit]) {
                int co = 0;
                rep(j, n) {
                    if(bit2 & (1<<j)) {if(a[i][j] == '0') ++ co;}
                    else {if(a[i][j] == '1') ++ co;}
                }
                chmin(dp[i][bit2], dp[i - 1][bit] + co);
            }
        }
    }
    int ret = inf;
    rep(i, (1<<n)) {
        chmin(ret, dp[m - 1][i]);
    }
    if(ret == inf) cout << -1 << endl;
    else cout << ret << endl;
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	//cout << fixed << setprecision(10);
	//int t; cin >> t; rep(i, t)solve();
	solve();
    return 0;
}


/**
 *    author:  otera
**/
#include<iostream>
#include<string>
#include<cstdio>
#include<cstring>
#include<vector>
#include<cmath>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<queue>
#include<deque>
#include<ciso646>
#include<random>
#include<map>
#include<set>
#include<complex>
#include<bitset>
#include<stack>
#include<unordered_map>
#include<utility>
#include<cassert>
using namespace std;

//#define int long long
typedef long long ll;
typedef unsigned long long ul;
typedef unsigned int ui;
typedef long double ld;
const int inf=1e9+7;
const ll INF=1LL<<60 ;
const ll mod=1e9+7 ;
#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define Rep(i,sta,n) for(int i=sta;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define per1(i,n) for(int i=n;i>=1;i--)
#define Rep1(i,sta,n) for(int i=sta;i<=n;i++)
typedef complex<ld> Point;
const ld eps = 1e-8;
const ld pi = acos(-1.0);
typedef pair<int, int> P;
typedef pair<ld, ld> LDP;
typedef pair<ll, ll> LP;
#define fr first
#define sc second
#define all(c) c.begin(),c.end()
#define pb push_back
#define debug(x)  cerr << #x << " = " << (x) << endl;
template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }

int n, m;
vector<vector<char>> a;

void solve() {
	cin >> n >> m;
    a.assign(n, vector<char>(m));
    rep(i, n) {
        rep(j, m) {
            cin >> a[i][j];
        }
    }
    if(n >= 4 || m >= 4) {
        cout << -1 << endl;
        return;
    }
    if(n == 1 || m == 1) {
        cout << 0 << endl;
        return;
    }
    int ans = inf;
    for(int bit = 0; bit < (1<<(n * m)); ++ bit) {
        vector<vector<char>> b(n, vector<char>(m, '0'));
        rep(i, n * m) {
            if(bit & (1<<i)) {
                int x = i / n, y = i % n;
                b[x][y] = '1';
            }
        }
        int cnt = 0;
        rep(i, n) {
            rep(j, m) {
                if(a[i][j] != b[i][j]) ++ cnt;
            }
        }
        bool check = 1;
        rep(i, 2) {
            rep(j, 2) {
                if(i + 1 < n && j + 1 < m) {
                    int co = 0;
                    rep(x, 2) {
                        rep(y, 2) {
                            if(b[i + x][j + y] == '1') ++ co;
                        }
                    }
                    if(co % 2 == 0) check = 0;
                }
            }
        }
        if(check) chmin(ans, cnt);
    }
    if(ans == inf) cout << -1 << endl;
    else cout << ans << endl;
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	//cout << fixed << setprecision(10);
	//int t; cin >> t; rep(i, t)solve();
	solve();
    return 0;
}


#include <bits/stdc++.h>
using namespace std;

#define pr(x) cout<< # x<< " = " << x <<endl

typedef long long  ll;
typedef long double ld;

const int N = 100005;
ll MOD = 1e9 + 7;

#define forn(i, n) for(int i = 0; i < (n); i++)

#define pb push_back
#define mp make_pair

#define max(a,b) ((a > b) ? a : b)
#define min(a,b) ((a < b) ? a : b)

vector<int> a2[2];
vector<int> a3[3];

vector<int> g[7];

void init(){
	int a[3];
	int b[3];
	for(int i = 0;i < 8;++i){
		for(int j = 0;j < 8;j++){
			int x = i;
			forn(pos,3){
				int d = x % 2;
				a[pos] = d;
				x = x / 2;
			}

			x = j;
			forn(pos,3){
				int d = x % 2;
				b[pos] = d;
				x = x / 2;
			}

			int sum0 = a[0] + a[1] + b[0] + b[1];
			int sum1 = a[1] + a[2] + b[1] + b[2];

			if(sum0 % 2 == 1){
				if(sum1 % 2 == 1){
					g[i].push_back(j);
				}
				//cout<<i<<" "<<j<<endl;
			}
		}

	}

}

int calc(int mask, const vector<int> &arr,int n){
	int ans = 0;
	for(int i = 0;i < n;++i){
		int d = mask % 2;
		mask /= 2;

		if(d != arr[i]){
			ans++;
		}
	}
	return ans;
}
void solve1(const vector<int> & a,int n){
		char c;
		cout<<0<<endl;
		return;
		int ans = 0;
		for(int i = 0;i < n;++i){
			int c = a[i];

			if(c == 0){
				ans++;
			}
		}
		cout<<ans<<endl;
}

void solve2(int m){

	ll dp [4][1000005];

	vector<int> g2[4];

	g2[0].push_back(1);
	g2[0].push_back(2);

	g2[1].push_back(3);
	g2[1].push_back(0);

	g2[2].push_back(3);
	g2[2].push_back(0);

	g2[3].push_back(1);
	g2[3].push_back(2);
	for(int i = 0;i < 4;++i){
		dp[i][0] = calc(i,{a2[0][0],a2[1][0]},2);
	}

	for(int i = 1;i < m;++i){
		for(int mask = 0;mask < 4;mask++){
			dp[mask][i] = calc(mask, {a2[0][i],a2[1][i]},2);

			int mn = 1e9;

			for(int v : g2[mask]){
				mn = min(mn,dp[v][i - 1]);
			}
			dp[mask][i] += mn;
		}
	}

	int mn = 1e9;

	for(int i = 0;i < 4;++i){
		mn = min(mn,dp[i][m - 1]);
	}

	cout<<mn<<endl;

}

void solve3(int m){
	ll dp [8][1000005];

	for(int i = 0;i < 8;++i){
		dp[i][0] = calc(i,{a3[0][0],a3[1][0],a3[2][0]},3);

	}

	for(int i = 1;i < m;++i){
		for(int mask = 0;mask < 8;mask++){
			dp[mask][i] = calc(mask, {a3[0][i],a3[1][i],a3[2][i]},3);

			int mn = 1e9;

			for(int v : g[mask]){
				mn = min(mn,dp[v][i - 1]);
			}
			dp[mask][i] += mn;
		}
	}

	int mn = 1e9;

	for(int i = 0;i < 8;++i){
		mn = min(mn,dp[i][m - 1]);
	}

	cout<<mn<<endl;
}

void solve(){
	int n,m;
	init();
	cin>>n>>m;

	if(n  >= 4 && m >= 4){
		cout<<-1<<endl;
		return;
	}

	char c;
	if(n == 1){
		vector<int> a(m);

		char c = 0;
		for(int i = 0;i < m;++i){
			cin>>c;

			if(c == '0'){
				a[i] = 0;

			}
			else{
				a[i] = 1;
			}
		}

		solve1(a, m);
		return;
	}

	if(m == 1){
		vector<int> a(n);

		char c = 0;
		for(int i = 0;i < n;++i){
			cin>>c;

			if(c == '0'){
				a[i] = 0;

			}
			else{
				a[i] = 1;
			}
		}

		solve1(a, n);
		return;
	}

	if(n == 2){
		char c;
		for(int i = 0;i < m;++i){
			cin>>c;
			if(c == '0'){
				a2[0].push_back(0);
			}
			else{
				a2[0].push_back(1);
			}
		}
		for(int i = 0;i < m;++i){
			cin>>c;
			if(c == '0'){
				a2[1].push_back(0);
			}
			else{
				a2[1].push_back(1);
			}
		}

		solve2(m);

		return;

	}

	if(m == 2){
		char c;

		for(int i = 0;i < n;++i){
			cin>>c;

			if(c == '0'){
				a2[0].push_back(0);
			}
			else{
				a2[0].push_back(1);
			}

			cin>>c;

			if(c == '0'){
				a2[1].push_back(0);
			}
			else{
				a2[1].push_back(1);
			}

		}

		solve2(n);

		return;

	}

	if(n == 3){
		char c;

		for(int i = 0;i < m;++i){
			cin>>c;
			if(c == '0'){
				a3[0].push_back(0);
			}
			else{
				a3[0].push_back(1);

			}
		}
		for(int i = 0;i < m;++i){
			cin>>c;
			if(c == '0'){
				a3[1].push_back(0);
			}
			else{
				a3[1].push_back(1);
			}
		}

		for(int i = 0;i < m;++i){
			cin>>c;
			if(c == '0'){
				a3[2].push_back(0);
			}
			else{
				a3[2].push_back(1);
			}
		}

		solve3(m);

		return;

	}

	if(m == 3){
		char c;

		for(int i = 0;i < n;++i){
			cin>>c;

			if(c == '0'){
				a3[0].push_back(0);
			}
			else{
				a3[0].push_back(1);
			}

			cin>>c;

			if(c == '0'){
				a3[1].push_back(0);
			}
			else{
				a3[1].push_back(1);
			}

			cin>>c;

			if(c == '0'){
				a3[2].push_back(0);
			}
			else{
				a3[2].push_back(1);
			}

		}

		solve3(n);

		return;

	}

}

int main(){
    //freopen("a.in", "r", stdin);
	//freopen("a.out", "w", stdout);
	ios_base::sync_with_stdio(0);
	cin.tie();
	cout.tie();

    int t = 1;

    while(t--){
        solve();
   }
}


#include <bits/stdc++.h>
using namespace std;

#define pr(x) cout<< # x<< " = " << x <<endl

typedef long long  ll;
typedef long double ld;

const int N = 100005;
ll MOD = 1e9 + 7;

#define forn(i, n) for(int i = 0; i < (n); i++)

#define pb push_back
#define mp make_pair

#define max(a,b) ((a > b) ? a : b)
#define min(a,b) ((a < b) ? a : b)

vector<int> a2[2];
vector<int> a3[3];

vector<int> g[7];

void init(){
	int a[3];
	int b[3];
	for(int i = 0;i < 8;++i){
		for(int j = 0;j < 8;j++){
			int x = i;
			forn(pos,3){
				int d = x % 2;
				a[pos] = d;
				x = x / 2;
			}

			x = j;
			forn(pos,3){
				int d = x % 2;
				b[pos] = d;
				x = x / 2;
			}

			int sum0 = a[0] + a[1] + b[0] + b[1];
			int sum1 = a[1] + a[2] + b[1] + b[2];

			if(sum0 % 2 == 1){
				if(sum1 % 2 == 1){
					g[i].push_back(j);
				}
				//cout<<i<<" "<<j<<endl;
			}
		}

	}

}

int calc(int mask, const vector<int> &arr,int n){
	int ans = 0;
	for(int i = 0;i < n;++i){
		int d = mask % 2;
		mask /= 2;

		if(d != arr[i]){
			ans++;
		}
	}
	return ans;
}
void solve1(const vector<int> & a,int n){
		char c;
		int ans = 0;
		for(int i = 0;i < n;++i){
			int c = a[i];

			if(c == 0){
				ans++;
			}
		}
		cout<<ans<<endl;
}

void solve2(int m){

	ll dp [4][1000005];

	vector<int> g2[4];

	g2[0].push_back(1);
	g2[0].push_back(2);

	g2[1].push_back(3);

	g2[2].push_back(3);

	g2[3].push_back(1);
	g2[3].push_back(2);
	for(int i = 0;i < 4;++i){
		dp[i][0] = calc(i,{a2[0][0],a2[1][0]},2);
	}

	for(int i = 1;i < m;++i){
		for(int mask = 0;mask < 4;mask++){
			dp[mask][i] = calc(mask, {a2[0][i],a2[1][i]},2);

			int mn = 1e9;

			for(int v : g2[mask]){
				mn = min(mn,dp[v][i - 1]);
			}
			dp[mask][i] += mn;
		}
	}

	int mn = 1e9;

	for(int i = 0;i < 4;++i){
		mn = min(mn,dp[i][m - 1]);
	}

	cout<<mn<<endl;

}

void solve3(int m){
	ll dp [8][1000005];

	for(int i = 0;i < 8;++i){
		dp[i][0] = calc(i,{a3[0][0],a3[1][0],a3[2][0]},3);

	}

	for(int i = 1;i < m;++i){
		for(int mask = 0;mask < 8;mask++){
			dp[mask][i] = calc(mask, {a3[0][i],a3[1][i],a3[2][i]},3);

			int mn = 1e9;

			for(int v : g[mask]){
				mn = min(mn,dp[v][i - 1]);
			}
			dp[mask][i] += mn;
		}
	}

	int mn = 1e9;

	for(int i = 0;i < 8;++i){
		mn = min(mn,dp[i][m - 1]);
	}

	cout<<mn<<endl;
}

void solve(){
	int n,m;
	init();
	cin>>n>>m;

	if(n  > 4 || m > 4){
		cout<<-1<<endl;
		return;
	}

	char c;
	if(n == 1){
		vector<int> a(m);

		char c = 0;
		for(int i = 0;i < m;++i){
			cin>>c;

			if(c == '0'){
				a[i] = 0;

			}
			else{
				a[i] = 1;
			}
		}

		solve1(a, m);
		return;
	}

	if(m == 1){
		vector<int> a(n);

		char c = 0;
		for(int i = 0;i < n;++i){
			cin>>c;

			if(c == '0'){
				a[i] = 0;

			}
			else{
				a[i] = 1;
			}
		}

		solve1(a, n);
		return;
	}

	if(n == 2){
		char c;
		for(int i = 0;i < m;++i){
			cin>>c;
			if(c == '0'){
				a2[0].push_back(0);
			}
			else{
				a2[0].push_back(1);
			}
		}
		for(int i = 0;i < m;++i){
			cin>>c;
			if(c == '0'){
				a2[1].push_back(0);
			}
			else{
				a2[1].push_back(1);
			}
		}

		solve2(m);

		return;

	}

	if(m == 2){
		char c;

		for(int i = 0;i < n;++i){
			cin>>c;

			if(c == '0'){
				a2[0].push_back(0);
			}
			else{
				a2[0].push_back(1);
			}

			cin>>c;

			if(c == '0'){
				a2[1].push_back(0);
			}
			else{
				a2[1].push_back(1);
			}

		}

		solve2(n);

		return;

	}

	if(n == 3){
		char c;

		for(int i = 0;i < m;++i){
			cin>>c;
			if(c == '0'){
				a3[0].push_back(0);
			}
			else{
				a3[0].push_back(1);

			}
		}
		for(int i = 0;i < m;++i){
			cin>>c;
			if(c == '0'){
				a3[1].push_back(0);
			}
			else{
				a3[1].push_back(1);
			}
		}

		for(int i = 0;i < m;++i){
			cin>>c;
			if(c == '0'){
				a3[2].push_back(0);
			}
			else{
				a3[2].push_back(1);
			}
		}

		solve3(m);

		return;

	}

	if(m == 3){
		char c;

		for(int i = 0;i < n;++i){
			cin>>c;

			if(c == '0'){
				a3[0].push_back(0);
			}
			else{
				a3[0].push_back(1);
			}

			cin>>c;

			if(c == '0'){
				a3[1].push_back(0);
			}
			else{
				a3[1].push_back(1);
			}

			cin>>c;

			if(c == '0'){
				a3[2].push_back(0);
			}
			else{
				a3[2].push_back(1);
			}

		}

		solve3(n);

		return;

	}

}

int main(){
    //freopen("a.in", "r", stdin);
	//freopen("a.out", "w", stdout);
	ios_base::sync_with_stdio(0);
	cin.tie();
	cout.tie();

    int t = 1;

    while(t--){
        solve();
   }
}


#include <bits/stdc++.h>
using namespace std;

#define pr(x) cout<< # x<< " = " << x <<endl

typedef long long  ll;
typedef long double ld;

const int N = 100005;
ll MOD = 1e9 + 7;

#define forn(i, n) for(int i = 0; i < (n); i++)

#define pb push_back
#define mp make_pair

#define max(a,b) ((a > b) ? a : b)
#define min(a,b) ((a < b) ? a : b)

vector<int> a2[2];
vector<int> a3[3];

vector<int> g[8];

void init(){
	int a[3];
	int b[3];
	for(int i = 0;i < 8;++i){
		for(int j = 0;j < 8;j++){
			int x = i;
			forn(pos,3){
				int d = x % 2;
				a[pos] = d;
				x = x / 2;
			}

			x = j;
			forn(pos,3){
				int d = x % 2;
				b[pos] = d;
				x = x / 2;
			}

			int sum0 = a[0] + a[1] + b[0] + b[1];
			int sum1 = a[1] + a[2] + b[1] + b[2];

			if(sum0 % 2 == 1){
				if(sum1 % 2 == 1){
					g[i].push_back(j);
				}
				//cout<<i<<" "<<j<<endl;
			}
		}

	}

}

int calc(int mask, const vector<int> &arr,int n){
	int ans = 0;
	for(int i = 0;i < n;++i){
		int d = mask % 2;
		mask /= 2;

		if(d != arr[i]){
			ans++;
		}
	}
	return ans;
}
void solve1(const vector<int> & a,int n){
		char c;
		int ans = 0;
		for(int i = 0;i < n;++i){
			int c = a[i];

			if(c == 0){
				ans++;
			}
		}
		cout<<ans<<endl;
}

void solve2(int m){

	ll dp [4][1000005];

	vector<int> g2[4];

	g2[0].push_back(1);
	g2[0].push_back(2);

	g2[1].push_back(3);
	g2[1].push_back(0);

	g2[2].push_back(3);
	g2[2].push_back(0);

	g2[3].push_back(1);
	g2[3].push_back(2);
	for(int i = 0;i < 4;++i){
		dp[i][0] = calc(i,{a2[0][0],a2[1][0]},2);
	}

	for(int i = 1;i < m;++i){
		for(int mask = 0;mask < 4;mask++){
			dp[mask][i] = calc(mask, {a2[0][i],a2[1][i]},2);

			int mn = 1e9;

			for(int v : g2[mask]){
				mn = min(mn,dp[v][i - 1]);
			}
			dp[mask][i] += mn;
		}
	}

	int mn = 1e9;

	for(int i = 0;i < 4;++i){
		mn = min(mn,dp[i][m - 1]);
	}

	cout<<mn<<endl;

}

void solve3(int m){
	ll dp [8][1000005];

	for(int i = 0;i < 8;++i){
		dp[i][0] = calc(i,{a3[0][0],a3[1][0],a3[2][0]},3);

	}

	for(int i = 1;i < m;++i){
		for(int mask = 0;mask < 8;mask++){
			dp[mask][i] = calc(mask, {a3[0][i],a3[1][i],a3[2][i]},3);

			int mn = 1e9;

			for(int v : g[mask]){
				mn = min(mn,dp[v][i - 1]);
			}
			dp[mask][i] += mn;
		}
	}

	int mn = 1e9;

	for(int i = 0;i < 8;++i){
		mn = min(mn,dp[i][m - 1]);
	}

	cout<<mn<<endl;
}

void solve(){
	int n,m;
	init();
	cin>>n>>m;

	if(n  >= 4 && m >= 4){
		cout<<-1<<endl;
		return;
	}

	char c;
	if(n == 1){
		vector<int> a(m);

		char c = 0;
		for(int i = 0;i < m;++i){
			cin>>c;

			if(c == '0'){
				a[i] = 0;

			}
			else{
				a[i] = 1;
			}
		}

		solve1(a, m);
		return;
	}

	if(m == 1){
		vector<int> a(n);

		char c = 0;
		for(int i = 0;i < n;++i){
			cin>>c;

			if(c == '0'){
				a[i] = 0;

			}
			else{
				a[i] = 1;
			}
		}

		solve1(a, n);
		return;
	}

	if(n == 2){
		char c;
		for(int i = 0;i < m;++i){
			cin>>c;
			if(c == '0'){
				a2[0].push_back(0);
			}
			else{
				a2[0].push_back(1);
			}
		}
		for(int i = 0;i < m;++i){
			cin>>c;
			if(c == '0'){
				a2[1].push_back(0);
			}
			else{
				a2[1].push_back(1);
			}
		}

		solve2(m);

		return;

	}

	if(m == 2){
		char c;

		for(int i = 0;i < n;++i){
			cin>>c;

			if(c == '0'){
				a2[0].push_back(0);
			}
			else{
				a2[0].push_back(1);
			}

			cin>>c;

			if(c == '0'){
				a2[1].push_back(0);
			}
			else{
				a2[1].push_back(1);
			}

		}

		solve2(n);

		return;

	}

	if(n == 3){
		char c;

		for(int i = 0;i < m;++i){
			cin>>c;
			if(c == '0'){
				a3[0].push_back(0);
			}
			else{
				a3[0].push_back(1);

			}
		}
		for(int i = 0;i < m;++i){
			cin>>c;
			if(c == '0'){
				a3[1].push_back(0);
			}
			else{
				a3[1].push_back(1);
			}
		}

		for(int i = 0;i < m;++i){
			cin>>c;
			if(c == '0'){
				a3[2].push_back(0);
			}
			else{
				a3[2].push_back(1);
			}
		}

		solve3(m);

		return;

	}

	if(m == 3){
		char c;

		for(int i = 0;i < n;++i){
			cin>>c;

			if(c == '0'){
				a3[0].push_back(0);
			}
			else{
				a3[0].push_back(1);
			}

			cin>>c;

			if(c == '0'){
				a3[1].push_back(0);
			}
			else{
				a3[1].push_back(1);
			}

			cin>>c;

			if(c == '0'){
				a3[2].push_back(0);
			}
			else{
				a3[2].push_back(1);
			}

		}

		solve3(n);

		return;

	}

}

int main(){
    //freopen("a.in", "r", stdin);
	//freopen("a.out", "w", stdout);
	ios_base::sync_with_stdio(0);
	cin.tie();
	cout.tie();

    int t = 1;

    while(t--){
        solve();
   }
}


#include <bits/stdc++.h>
using namespace std;

#define pr(x) cout<< # x<< " = " << x <<endl

typedef long long  ll;
typedef long double ld;

const int N = 100005;
ll MOD = 1e9 + 7;

#define forn(i, n) for(int i = 0; i < (n); i++)

#define pb push_back
#define mp make_pair

#define max(a,b) ((a > b) ? a : b)
#define min(a,b) ((a < b) ? a : b)

vector<int> a2[2];
vector<int> a3[3];

vector<int> g[7];

void init(){
	int a[3];
	int b[3];
	for(int i = 0;i < 8;++i){
		for(int j = 0;j < 8;j++){
			int x = i;
			forn(pos,3){
				int d = x % 2;
				a[pos] = d;
				x = x / 2;
			}

			x = j;
			forn(pos,3){
				int d = x % 2;
				b[pos] = d;
				x = x / 2;
			}

			int sum0 = a[0] + a[1] + b[0] + b[1];
			int sum1 = a[1] + a[2] + b[1] + b[2];

			if(sum0 % 2 == 1){
				if(sum1 % 2 == 1){
					g[i].push_back(j);
				}
				//cout<<i<<" "<<j<<endl;
			}
		}

	}

}

int calc(int mask, const vector<int> &arr,int n){
	int ans = 0;
	for(int i = 0;i < n;++i){
		int d = mask % 2;
		mask /= 2;

		if(d != arr[i]){
			ans++;
		}
	}
	return ans;
}
void solve1(const vector<int> & a,int n){
		char c;
		int ans = 0;
		for(int i = 0;i < n;++i){
			int c = a[i];

			if(c == 0){
				ans++;
			}
		}
		cout<<ans<<endl;
}

void solve2(int m){

	ll dp [4][1000005];

	vector<int> g2[4];

	g2[0].push_back(1);
	g2[0].push_back(2);

	g2[1].push_back(3);

	g2[2].push_back(3);

	g2[3].push_back(1);
	g2[3].push_back(2);
	for(int i = 0;i < 4;++i){
		dp[i][0] = calc(i,{a2[0][0],a2[1][0]},2);
	}

	for(int i = 1;i < m;++i){
		for(int mask = 0;mask < 4;mask++){
			dp[mask][i] = calc(mask, {a2[0][i],a2[1][i]},2);

			int mn = 1e9;

			for(int v : g2[mask]){
				mn = min(mn,dp[v][i - 1]);
			}
			dp[mask][i] += mn;
		}
	}

	int mn = 1e9;

	for(int i = 0;i < 4;++i){
		mn = min(mn,dp[i][m - 1]);
	}

	cout<<mn<<endl;

}

void solve3(int m){
	ll dp [8][1000005];

	for(int i = 0;i < 8;++i){
		dp[i][0] = calc(i,{a3[0][0],a3[1][0],a3[2][0]},3);

	}

	for(int i = 1;i < m;++i){
		for(int mask = 0;mask < 8;mask++){
			dp[mask][i] = calc(mask, {a3[0][i],a3[1][i],a3[2][i]},3);

			int mn = 1e9;

			for(int v : g[mask]){
				mn = min(mn,dp[v][i - 1]);
			}
			dp[mask][i] += mn;
		}
	}

	int mn = 1e9;

	for(int i = 0;i < 8;++i){
		mn = min(mn,dp[i][m - 1]);
	}

	cout<<mn<<endl;
}

void solve(){
	int n,m;
	init();
	cin>>n>>m;

	if(n  >= 4 && m >= 4){
		cout<<-1<<endl;
		return;
	}

	char c;
	if(n == 1){
		vector<int> a(m);

		char c = 0;
		for(int i = 0;i < m;++i){
			cin>>c;

			if(c == '0'){
				a[i] = 0;

			}
			else{
				a[i] = 1;
			}
		}

		solve1(a, m);
		return;
	}

	if(m == 1){
		vector<int> a(n);

		char c = 0;
		for(int i = 0;i < n;++i){
			cin>>c;

			if(c == '0'){
				a[i] = 0;

			}
			else{
				a[i] = 1;
			}
		}

		solve1(a, n);
		return;
	}

	if(n == 2){
		char c;
		for(int i = 0;i < m;++i){
			cin>>c;
			if(c == '0'){
				a2[0].push_back(0);
			}
			else{
				a2[0].push_back(1);
			}
		}
		for(int i = 0;i < m;++i){
			cin>>c;
			if(c == '0'){
				a2[1].push_back(0);
			}
			else{
				a2[1].push_back(1);
			}
		}

		solve2(m);

		return;

	}

	if(m == 2){
		char c;

		for(int i = 0;i < n;++i){
			cin>>c;

			if(c == '0'){
				a2[0].push_back(0);
			}
			else{
				a2[0].push_back(1);
			}

			cin>>c;

			if(c == '0'){
				a2[1].push_back(0);
			}
			else{
				a2[1].push_back(1);
			}

		}

		solve2(n);

		return;

	}

	if(n == 3){
		char c;

		for(int i = 0;i < m;++i){
			cin>>c;
			if(c == '0'){
				a3[0].push_back(0);
			}
			else{
				a3[0].push_back(1);

			}
		}
		for(int i = 0;i < m;++i){
			cin>>c;
			if(c == '0'){
				a3[1].push_back(0);
			}
			else{
				a3[1].push_back(1);
			}
		}

		for(int i = 0;i < m;++i){
			cin>>c;
			if(c == '0'){
				a3[2].push_back(0);
			}
			else{
				a3[2].push_back(1);
			}
		}

		solve3(m);

		return;

	}

	if(m == 3){
		char c;

		for(int i = 0;i < n;++i){
			cin>>c;

			if(c == '0'){
				a3[0].push_back(0);
			}
			else{
				a3[0].push_back(1);
			}

			cin>>c;

			if(c == '0'){
				a3[1].push_back(0);
			}
			else{
				a3[1].push_back(1);
			}

			cin>>c;

			if(c == '0'){
				a3[2].push_back(0);
			}
			else{
				a3[2].push_back(1);
			}

		}

		solve3(n);

		return;

	}

}

int main(){
    //freopen("a.in", "r", stdin);
	//freopen("a.out", "w", stdout);
	ios_base::sync_with_stdio(0);
	cin.tie();
	cout.tie();

    int t = 1;

    while(t--){
        solve();
   }
}


#include <bits/stdc++.h>
using namespace std;

#define pr(x) cout<< # x<< " = " << x <<endl

typedef long long  ll;
typedef long double ld;

const int N = 100005;
ll MOD = 1e9 + 7;

#define forn(i, n) for(int i = 0; i < (n); i++)

#define pb push_back
#define mp make_pair

#define max(a,b) ((a > b) ? a : b)
#define min(a,b) ((a < b) ? a : b)

vector<int> a2[2];
vector<int> a3[3];

vector<int> g[7];

void init(){
	int a[3];
	int b[3];
	for(int i = 0;i < 8;++i){
		for(int j = 0;j < 8;j++){
			int x = i;
			forn(pos,3){
				int d = x % 2;
				a[pos] = d;
				x = x / 2;
			}

			x = j;
			forn(pos,3){
				int d = x % 2;
				b[pos] = d;
				x = x / 2;
			}

			int sum0 = a[0] + a[1] + b[0] + b[1];
			int sum1 = a[1] + a[2] + b[1] + b[2];

			if(sum0 % 2 == 1){
				if(sum1 % 2 == 1){
					g[i].push_back(j);
				}
				//cout<<i<<" "<<j<<endl;
			}
		}

	}

}

int calc(int mask, const vector<int> &arr,int n){
	int ans = 0;
	for(int i = 0;i < n;++i){
		int d = mask % 2;
		mask /= 2;

		if(d != arr[i]){
			ans++;
		}
	}
	return ans;
}
void solve1(const vector<int> & a,int n){
		char c;
		int ans = 0;
		for(int i = 0;i < n;++i){
			int c = a[i];

			if(c == 0){
				ans++;
			}
		}
		cout<<ans<<endl;
}

void solve2(int m){

	ll dp [4][1000005];

	vector<int> g2[4];

	g2[0].push_back(1);
	g2[0].push_back(2);

	g2[1].push_back(3);
	g2[1].push_back(0);

	g2[2].push_back(3);
	g2[2].push_back(0);

	g2[3].push_back(1);
	g2[3].push_back(2);
	for(int i = 0;i < 4;++i){
		dp[i][0] = calc(i,{a2[0][0],a2[1][0]},2);
	}

	for(int i = 1;i < m;++i){
		for(int mask = 0;mask < 4;mask++){
			dp[mask][i] = calc(mask, {a2[0][i],a2[1][i]},2);

			int mn = 1e9;

			for(int v : g2[mask]){
				mn = min(mn,dp[v][i - 1]);
			}
			dp[mask][i] += mn;
		}
	}

	int mn = 1e9;

	for(int i = 0;i < 4;++i){
		mn = min(mn,dp[i][m - 1]);
	}

	cout<<mn<<endl;

}

void solve3(int m){
	ll dp [8][1000005];

	for(int i = 0;i < 8;++i){
		dp[i][0] = calc(i,{a3[0][0],a3[1][0],a3[2][0]},3);

	}

	for(int i = 1;i < m;++i){
		for(int mask = 0;mask < 8;mask++){
			dp[mask][i] = calc(mask, {a3[0][i],a3[1][i],a3[2][i]},3);

			int mn = 1e9;

			for(int v : g[mask]){
				mn = min(mn,dp[v][i - 1]);
			}
			dp[mask][i] += mn;
		}
	}

	int mn = 1e9;

	for(int i = 0;i < 8;++i){
		mn = min(mn,dp[i][m - 1]);
	}

	cout<<mn<<endl;
}

void solve(){
	int n,m;
	init();
	cin>>n>>m;

	if(n  >= 4 && m >= 4){
		cout<<-1<<endl;
		return;
	}

	char c;
	if(n == 1){
		vector<int> a(m);

		char c = 0;
		for(int i = 0;i < m;++i){
			cin>>c;

			if(c == '0'){
				a[i] = 0;

			}
			else{
				a[i] = 1;
			}
		}

		solve1(a, m);
		return;
	}

	if(m == 1){
		vector<int> a(n);

		char c = 0;
		for(int i = 0;i < n;++i){
			cin>>c;

			if(c == '0'){
				a[i] = 0;

			}
			else{
				a[i] = 1;
			}
		}

		solve1(a, n);
		return;
	}

	if(n == 2){
		char c;
		for(int i = 0;i < m;++i){
			cin>>c;
			if(c == '0'){
				a2[0].push_back(0);
			}
			else{
				a2[0].push_back(1);
			}
		}
		for(int i = 0;i < m;++i){
			cin>>c;
			if(c == '0'){
				a2[1].push_back(0);
			}
			else{
				a2[1].push_back(1);
			}
		}

		solve2(m);

		return;

	}

	if(m == 2){
		char c;

		for(int i = 0;i < n;++i){
			cin>>c;

			if(c == '0'){
				a2[0].push_back(0);
			}
			else{
				a2[0].push_back(1);
			}

			cin>>c;

			if(c == '0'){
				a2[1].push_back(0);
			}
			else{
				a2[1].push_back(1);
			}

		}

		solve2(n);

		return;

	}

	if(n == 3){
		char c;

		for(int i = 0;i < m;++i){
			cin>>c;
			if(c == '0'){
				a3[0].push_back(0);
			}
			else{
				a3[0].push_back(1);

			}
		}
		for(int i = 0;i < m;++i){
			cin>>c;
			if(c == '0'){
				a3[1].push_back(0);
			}
			else{
				a3[1].push_back(1);
			}
		}

		for(int i = 0;i < m;++i){
			cin>>c;
			if(c == '0'){
				a3[2].push_back(0);
			}
			else{
				a3[2].push_back(1);
			}
		}

		solve3(m);

		return;

	}

	if(m == 3){
		char c;

		for(int i = 0;i < n;++i){
			cin>>c;

			if(c == '0'){
				a3[0].push_back(0);
			}
			else{
				a3[0].push_back(1);
			}

			cin>>c;

			if(c == '0'){
				a3[1].push_back(0);
			}
			else{
				a3[1].push_back(1);
			}

			cin>>c;

			if(c == '0'){
				a3[2].push_back(0);
			}
			else{
				a3[2].push_back(1);
			}

		}

		solve3(n);

		return;

	}

}

int main(){
    //freopen("a.in", "r", stdin);
	//freopen("a.out", "w", stdout);
	ios_base::sync_with_stdio(0);
	cin.tie();
	cout.tie();

    int t = 1;

    while(t--){
        solve();
   }
}


#include <bits/stdc++.h>
using namespace std;

#define pr(x) cout<< # x<< " = " << x <<endl

typedef long long  ll;
typedef long double ld;

const int N = 100005;
ll MOD = 1e9 + 7;

#define forn(i, n) for(int i = 0; i < (n); i++)

#define pb push_back
#define mp make_pair

#define max(a,b) ((a > b) ? a : b)
#define min(a,b) ((a < b) ? a : b)

vector<int> a2[2];
vector<int> a3[3];

vector<int> g[7];

void init(){
	int a[3];
	int b[3];
	for(int i = 0;i < 8;++i){
		for(int j = 0;j < 8;j++){
			int x = i;
			forn(pos,3){
				int d = x % 2;
				a[pos] = d;
				x = x / 2;
			}

			x = j;
			forn(pos,3){
				int d = x % 2;
				b[pos] = d;
				x = x / 2;
			}

			int sum0 = a[0] + a[1] + b[0] + b[1];
			int sum1 = a[1] + a[2] + b[1] + b[2];

			if(sum0 % 2 == 1){
				if(sum1 % 2 == 1){
					g[i].push_back(j);
				}
				//cout<<i<<" "<<j<<endl;
			}
		}

	}

}

int calc(int mask, const vector<int> &arr,int n){
	int ans = 0;
	for(int i = 0;i < n;++i){
		int d = mask % 2;
		mask /= 2;

		if(d != arr[i]){
			ans++;
		}
	}
	return ans;
}
void solve1(const vector<int> & a,int n){
		char c;
		int ans = 0;
		for(int i = 0;i < n;++i){
			int c = a[i];

			if(c == 0){
				ans++;
			}
		}
		cout<<ans<<endl;
}

void solve2(int m){

	ll dp [4][100005];

	vector<int> g2[4];

	g2[0].push_back(1);
	g2[0].push_back(2);

	g2[1].push_back(3);

	g2[2].push_back(3);

	g2[3].push_back(1);
	g2[3].push_back(2);
	for(int i = 0;i < 4;++i){
		dp[i][0] = calc(i,{a2[0][0],a2[1][0]},2);
	}

	for(int i = 1;i < m;++i){
		for(int mask = 0;mask < 4;mask++){
			dp[mask][i] = calc(mask, {a2[0][i],a2[1][i]},2);

			int mn = 1e9;

			for(int v : g2[mask]){
				mn = min(mn,dp[v][i - 1]);
			}
			dp[mask][i] += mn;
		}
	}

	int mn = 1e9;

	for(int i = 0;i < 4;++i){
		mn = min(mn,dp[i][m - 1]);
	}

	cout<<mn<<endl;

}

void solve3(int m){
	ll dp [8][100005];

	for(int i = 0;i < 8;++i){
		dp[i][0] = calc(i,{a3[0][0],a3[1][0],a3[2][0]},3);

	}

	for(int i = 1;i < m;++i){
		for(int mask = 0;mask < 8;mask++){
			dp[mask][i] = calc(mask, {a3[0][i],a3[1][i],a3[2][i]},3);

			int mn = 1e9;

			for(int v : g[mask]){
				mn = min(mn,dp[v][i - 1]);
			}
			dp[mask][i] += mn;
		}
	}

	int mn = 1e9;

	for(int i = 0;i < 8;++i){
		mn = min(mn,dp[i][m - 1]);
	}

	cout<<mn<<endl;
}

void solve(){
	int n,m;
	init();
	cin>>n>>m;

	if(n  > 4 || m > 4){
		cout<<-1<<endl;
		return;
	}

	char c;
	if(n == 1){
		vector<int> a(m);

		char c = 0;
		for(int i = 0;i < m;++i){
			cin>>c;

			if(c == '0'){
				a[i] = 0;

			}
			else{
				a[i] = 1;
			}
		}

		solve1(a, m);
		return;
	}

	if(m == 1){
		vector<int> a(n);

		char c = 0;
		for(int i = 0;i < n;++i){
			cin>>c;

			if(c == '0'){
				a[i] = 0;

			}
			else{
				a[i] = 1;
			}
		}

		solve1(a, n);
		return;
	}

	if(n == 2){
		char c;
		for(int i = 0;i < m;++i){
			cin>>c;
			if(c == '0'){
				a2[0].push_back(0);
			}
			else{
				a2[0].push_back(1);
			}
		}
		for(int i = 0;i < m;++i){
			cin>>c;
			if(c == '0'){
				a2[1].push_back(0);
			}
			else{
				a2[1].push_back(1);
			}
		}

		solve2(m);

		return;

	}

	if(m == 2){
		char c;

		for(int i = 0;i < n;++i){
			cin>>c;

			if(c == '0'){
				a2[0].push_back(0);
			}
			else{
				a2[0].push_back(1);
			}

			cin>>c;

			if(c == '0'){
				a2[1].push_back(0);
			}
			else{
				a2[1].push_back(1);
			}

		}

		solve2(n);

		return;

	}

	if(n == 3){
		char c;

		for(int i = 0;i < m;++i){
			cin>>c;
			if(c == '0'){
				a3[0].push_back(0);
			}
			else{
				a3[0].push_back(1);

			}
		}
		for(int i = 0;i < m;++i){
			cin>>c;
			if(c == '0'){
				a3[1].push_back(0);
			}
			else{
				a3[1].push_back(1);
			}
		}

		for(int i = 0;i < m;++i){
			cin>>c;
			if(c == '0'){
				a3[2].push_back(0);
			}
			else{
				a3[2].push_back(1);
			}
		}

		solve3(m);

		return;

	}

	if(m == 3){
		char c;

		for(int i = 0;i < n;++i){
			cin>>c;

			if(c == '0'){
				a3[0].push_back(0);
			}
			else{
				a3[0].push_back(1);
			}

			cin>>c;

			if(c == '0'){
				a3[1].push_back(0);
			}
			else{
				a3[1].push_back(1);
			}

			cin>>c;

			if(c == '0'){
				a3[2].push_back(0);
			}
			else{
				a3[2].push_back(1);
			}

		}

		solve3(n);

		return;

	}

}

int main(){
    //freopen("a.in", "r", stdin);
	//freopen("a.out", "w", stdout);
	ios_base::sync_with_stdio(0);
	cin.tie();
	cout.tie();

    int t = 1;

    while(t--){
        solve();
   }
}