#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for(ll i=0; i<(ll)n; i++)
#define ALL(obj) begin(obj), end(obj)
typedef long long ll;
int n, m, a, b, cnt;
vector<vector<int> > G(22);
vector<int> color(22, -1), ts;
vector<bool> vit(22, 0);

void dfs(int now){
	ts.push_back(now);
	vit[now]=1;
	
	for(int i : G[now]){
		if(!vit[i])
		    dfs(i);
	}
}

ll DFS(int i){
	if(i==ts.size())
	    return 1;
	    
	ll ret=0;
	rep(j, 3){
		bool f=1;
		for(int v:G[ts[i]]){
			if(color[v]==j)
			    f=0;
		} 
		
		if(!f)
		    continue;
		    
		color[ts[i]]=j;
		ret+=DFS(i+1);
		color[ts[i]]=-1;
	}
	
	return ret;
}

int main()
{
	cin>>n>>m;
	ll ans=1;
	rep(i, m){
		cin>>a>>b;
		a--;
		b--;
		
		G[a].push_back(b);
		G[b].push_back(a);
	}
	
	rep(i, n){
		if(vit[i])
		    continue;
		    
		dfs(i);
		fill(ALL(color), -1);
		ans*=DFS(0);
		ts.clear();
	}
	
	cout<<ans<<endl;
	return 0;
}

#pragma GCC optimize("O3")
#include <bits/stdc++.h>
using namespace std;
#include <ext/pb_ds/assoc_container.hpp> 
#include <ext/pb_ds/tree_policy.hpp> 
using namespace __gnu_pbds; 
#define ordered_set tree<int,null_type,less<int>, rb_tree_tag,tree_order_statistics_node_update> 
#define ordered_set_pair tree<pair<int,int>,null_type,less<pair<int,int>>, rb_tree_tag,tree_order_statistics_node_update> 
#define ordered_set_mutiset tree<int,null_type,less_equal<int>, rb_tree_tag,tree_order_statistics_node_update>
typedef long long int ll;
typedef long double ld;
typedef unsigned long long int ull;
typedef pair<int,int> pi; 
#define PI 3.1415926535897932384
#define FOR(i,vv,n) for(ll i=vv;i<n;i++)
#define FORR(i,n,vv) for(ll i=n-1;i>=vv;i--)
#define ve vector 
#define maxind(v) (max_element(v.begin(),v.end())-v.begin())
#define minind(v) (min_element(v.begin(),v.end())-v.begin())
#define maxe(v) *max_element(v.begin(),v.end())
#define mine(v) *min_element(v.begin(),v.end())
#define pb push_back
#define pf push_front
#define ppb pop_back
#define ppf pop_front
#define eb emplace_back
#define FAST ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define mp make_pair
#define M 1000000007ll
#define INF 1000000000000000000ll
#define PRECISE cout.precision(18);
#define BS(v,n) binary_search(v.begin(),v.end(),n)
#define srt(v) sort(v.begin(),v.end())
#define rsrt(v) sort(v.begin(),v.end(),greater <ll>())
#define uni(v) v.resize(unique(v.begin(),v.end())-v.begin())
#define F first
#define S second
#define GET(i,p) get<p>(i)


int main(){


    #ifndef ONLINE_JUDGE
    // for getting input from input.txt 
    freopen("input.txt", "r", stdin);
    // for writing output to output.txt
    freopen("output.txt", "w", stdout);
     #endif

    FAST		

    ll n;cin>>n;
    string s,t;
    cin>>s>>t;
    ll ans = 0;
    ll k1 = 0,k2 = 0;
    FOR(i,0,n){
    	if(s[i]-'0'==0)k1++;
    	if(t[i]-'0'==0)k2++;
    }
    if(k1!=k2)ans=-1;
    else{
	    ve <ll> z(2);
	    ll don  = 0;
	    FOR(i,0,n){
	    	ll x1 = s[i]-'0';
	    	ll x2 = t[i]-'0';
	    	if(z[x2]>0){
	    		z[x2]--;
	    	}
	    	else{
	    		
	    		ll c1 = 0;
	    		while(s[don]-'0'!=x2){
	    			c1++;don++;
	    		}
	    		don++;
	    		z[1-x2]+=c1;
	    		if(x2==0){
	    			if(c1!=0||(c1==0&&z[1]!=0))ans++;
	    		}
	    		else{
	    			if(c1!=0)ans+=c1;
	    		}
	    	}
	    }
	}
    cout<<ans;


    return 0;
}