#include <bits/stdc++.h>
inline long long read(){char c = getchar();long long x = 0,s = 1;
while(c < '0' || c > '9') {if(c == '-') s = -1;c = getchar();}
while(c >= '0' && c <= '9') {x = x*10 + c -'0';c = getchar();}
return x*s;}
using namespace std;
#define NewNode (TreeNode *)malloc(sizeof(TreeNode))
#define Mem(a,b) memset(a,b,sizeof(a))
#define lowbit(x) (x)&(-x)
const int N = 1e5 + 10;
const long long INFINF = 0x7f7f7f7f7f7f7f;
const int INF = 0x3f3f3f3f;
const double EPS = 1e-5;
const int mod = 1e9+7;
const double II = acos(-1);
const double PP = (II*1.0)/(180.00);
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll,ll> piil;
signed main()
{
    std::ios::sync_with_stdio(false);
    cin.tie(0),cout.tie(0);
    //    freopen("input.txt","r",stdin);
    //    freopen("output.txt","w",stdout);
    int n;
    cin >> n;
    map<ll,ll> mp;
    ll sum[n+5] = {0},arr[n+5],ans = 0,flag = -1;
    for(int i = 1;i <= n;i++) cin >> arr[i];
    for(int i = 1;i <= n;i++)
    {
        sum[i] = arr[i]+sum[i-1];
        if((mp[sum[i]] || sum[i] == 0) && mp[sum[i]] >= flag-1)
            ans++,flag = i;
        mp[sum[i]] = 1;
    }
    cout << ans << endl;
}


#include <bits/stdc++.h>
inline long long read(){char c = getchar();long long x = 0,s = 1;
while(c < '0' || c > '9') {if(c == '-') s = -1;c = getchar();}
while(c >= '0' && c <= '9') {x = x*10 + c -'0';c = getchar();}
return x*s;}
using namespace std;
#define NewNode (TreeNode *)malloc(sizeof(TreeNode))
#define Mem(a,b) memset(a,b,sizeof(a))
#define lowbit(x) (x)&(-x)
const int N = 1e5 + 10;
const long long INFINF = 0x7f7f7f7f7f7f7f;
const int INF = 0x3f3f3f3f;
const double EPS = 1e-5;
const int mod = 1e9+7;
const double II = acos(-1);
const double PP = (II*1.0)/(180.00);
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll,ll> piil;
signed main()
{
    std::ios::sync_with_stdio(false);
    cin.tie(0),cout.tie(0);
    //    freopen("input.txt","r",stdin);
    //    freopen("output.txt","w",stdout);
    int n;
    cin >> n;
    map<ll,ll> mp;
    ll sum[n+5] = {0},arr[n+5],ans = 0,flag = -1;
    for(int i = 1;i <= n;i++) cin >> arr[i];
    for(int i = 1;i <= n;i++)
    {
        sum[i] = arr[i]+sum[i-1];
        if(mp[sum[i]])
        {
            if(mp[sum[i]] >= flag-1)
                ans++,flag = i;
        }
        else
        {
            if(sum[i] == 0)
                ans++,flag = i;
        }
        mp[sum[i]] = i;
    }
    cout << ans << endl;
}


#include <bits/stdc++.h>
inline long long read(){char c = getchar();long long x = 0,s = 1;
while(c < '0' || c > '9') {if(c == '-') s = -1;c = getchar();}
while(c >= '0' && c <= '9') {x = x*10 + c -'0';c = getchar();}
return x*s;}
using namespace std;
#define NewNode (TreeNode *)malloc(sizeof(TreeNode))
#define Mem(a,b) memset(a,b,sizeof(a))
#define lowbit(x) (x)&(-x)
const int N = 2e5 + 10;
const long long INFINF = 0x7f7f7f7f7f7f7f;
const int INF = 0x3f3f3f3f;
const double EPS = 1e-5;
const int mod = 1e9+7;
const double II = acos(-1);
const double PP = (II*1.0)/(180.00);
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll,ll> piil;
signed main()
{
    std::ios::sync_with_stdio(false);
    cin.tie(0),cout.tie(0);
    //    freopen("input.txt","r",stdin);
    //    freopen("output.txt","w",stdout);
    ll n;
    cin >> n;
    map<ll,ll> mp;
    ll arr[n+5],sum = 0,ans = 0;
    for(int i = 1;i <= n;i++) cin >> arr[i];
    for(int i = 1;i <= n;i++)
    {
        sum += arr[i];
        if(mp[sum[i]] || sum == 0)
        {
            ans++;
            mp.clear();
            sum = arr[i];
        }
        mp[sum[i]] = 1;
    }
    cout << ans << endl;
}


#include <bits/stdc++.h>
#include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<map>
#include <queue>
#include<sstream>
#include <stack>
#include <set>
#include <bitset>
#include<vector>
#define FAST ios::sync_with_stdio(false)
#define abs(a) ((a)>=0?(a):-(a))
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(),(x).end()
#define mem(a,b) memset(a,b,sizeof(a))
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define rep(i,a,n) for(int i=a;i<=n;++i)
#define per(i,n,a) for(int i=n;i>=a;--i)
#define endl '\n'
#define pb push_back
#define mp make_pair
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef pair<ll,ll> PII;
const int maxn = 2e5+200;
const int inf=0x3f3f3f3f;
const double eps = 1e-7;
const double pi=acos(-1.0);
const int mod = 1e9+7;
inline int lowbit(int x){return x&(-x);}
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
void ex_gcd(ll a,ll b,ll &d,ll &x,ll &y){if(!b){d=a,x=1,y=0;}else{ex_gcd(b,a%b,d,y,x);y-=x*(a/b);}}//x=(x%(b/d)+(b/d))%(b/d);
inline ll qpow(ll a,ll b,ll MOD=mod){ll res=1;a%=MOD;while(b>0){if(b&1)res=res*a%MOD;a=a*a%MOD;b>>=1;}return res;}
inline ll inv(ll x,ll p){return qpow(x,p-2,p);}
inline ll Jos(ll n,ll k,ll s=1){ll res=0;rep(i,1,n+1) res=(res+k)%i;return (res+s)%n;}
inline ll read(){ ll f = 1; ll x = 0;char ch = getchar();while(ch>'9'||ch<'0') {if(ch=='-') f=-1; ch = getchar();}while(ch>='0'&&ch<='9') x = (x<<3) + (x<<1) + ch - '0',  ch = getchar();return x*f; }
int dir[4][2] = { {1,0}, {-1,0},{0,1},{0,-1} };

ll sum[maxn];
ll a[maxn];
map<ll,ll> Map;

int main()
{
    ll n = read();
    ll L = -1;
    ll ans = 0;
    Map[0] = 1;
    sum[1] = 0;
    rep(i,2,n+1)
    {
        a[i] = read(), sum[i] = sum[i-1] + a[i];
        if(Map[sum[i]]&&Map[sum[i]]>=L-1)  ans++, L = i;
        Map[sum[i]] = i;
    }
    cout<<ans<<endl;
    return 0;
}


#include <bits/stdc++.h>
inline long long read(){char c = getchar();long long x = 0,s = 1;
while(c < '0' || c > '9') {if(c == '-') s = -1;c = getchar();}
while(c >= '0' && c <= '9') {x = x*10 + c -'0';c = getchar();}
return x*s;}
using namespace std;
#define NewNode (TreeNode *)malloc(sizeof(TreeNode))
#define Mem(a,b) memset(a,b,sizeof(a))
#define lowbit(x) (x)&(-x)
const int N = 1e5 + 10;
const long long INFINF = 0x7f7f7f7f7f7f7f;
const int INF = 0x3f3f3f3f;
const double EPS = 1e-5;
const int mod = 1e9+7;
const double II = acos(-1);
const double PP = (II*1.0)/(180.00);
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll,ll> piil;
signed main()
{
    std::ios::sync_with_stdio(false);
    cin.tie(0),cout.tie(0);
    //    freopen("input.txt","r",stdin);
    //    freopen("output.txt","w",stdout);
    int n;
    cin >> n;
    map<ll,ll> mp;
    ll sum[n+5] = {0},arr[n+5],ans = 0,flag = -1;
    for(int i = 1;i <= n;i++) cin >> arr[i];
    for(int i = 1;i <= n;i++)
    {
        sum[i] = arr[i]+sum[i-1];
        if(mp[sum[i]] && mp[sum[i]] >= flag-1)
            ans++,flag = i;
        else if(sum[i] == 0)
            ans++,flag = i;
        mp[sum[i]] = i;
    }
    cout << ans << endl;
}


#include <bits/stdc++.h>
inline long long read(){char c = getchar();long long x = 0,s = 1;
while(c < '0' || c > '9') {if(c == '-') s = -1;c = getchar();}
while(c >= '0' && c <= '9') {x = x*10 + c -'0';c = getchar();}
return x*s;}
using namespace std;
#define NewNode (TreeNode *)malloc(sizeof(TreeNode))
#define Mem(a,b) memset(a,b,sizeof(a))
#define lowbit(x) (x)&(-x)
const int N = 2e5 + 10;
const long long INFINF = 0x7f7f7f7f7f7f7f;
const int INF = 0x3f3f3f3f;
const double EPS = 1e-5;
const int mod = 1e9+7;
const double II = acos(-1);
const double PP = (II*1.0)/(180.00);
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll,ll> piil;
signed main()
{
    std::ios::sync_with_stdio(false);
    cin.tie(0),cout.tie(0);
    //    freopen("input.txt","r",stdin);
    //    freopen("output.txt","w",stdout);
    ll n;
    cin >> n;
    map<ll,ll> mp;
    ll arr[n+5],sum[n+5] = {0},ans = 0;
    for(int i = 1;i <= n;i++) cin >> arr[i];
    for(int i = 1;i <= n;i++)
    {
        sum[i] = arr[i] + sum[i-1];
        if(mp[sum[i]])
        {
            ans++;
            mp.clear();
            sum[i] = arr[i];
        }
        mp[sum[i]] = 1;
    }
    cout << ans << endl;
}


#include <bits/stdc++.h>
inline long long read(){char c = getchar();long long x = 0,s = 1;
while(c < '0' || c > '9') {if(c == '-') s = -1;c = getchar();}
while(c >= '0' && c <= '9') {x = x*10 + c -'0';c = getchar();}
return x*s;}
using namespace std;
#define NewNode (TreeNode *)malloc(sizeof(TreeNode))
#define Mem(a,b) memset(a,b,sizeof(a))
#define lowbit(x) (x)&(-x)
const int N = 1e5 + 10;
const long long INFINF = 0x7f7f7f7f7f7f7f;
const int INF = 0x3f3f3f3f;
const double EPS = 1e-5;
const int mod = 1e9+7;
const double II = acos(-1);
const double PP = (II*1.0)/(180.00);
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll,ll> piil;
signed main()
{
    std::ios::sync_with_stdio(false);
    cin.tie(0),cout.tie(0);
    //    freopen("input.txt","r",stdin);
    //    freopen("output.txt","w",stdout);
    int n;
    cin >> n;
    map<ll,ll> mp;
    mp[0] = 0;
    ll sum[n+5] = {0},arr[n+5],ans = 0,flag = -1;
    for(int i = 1;i <= n;i++) cin >> arr[i];
    for(int i = 1;i <= n;i++)
    {
        sum[i] = arr[i]+sum[i-1];
        if(mp[sum[i]] && mp[sum[i]] >= flag-1)
            flag = i,ans++;
        mp[sum[i]] = i;
    }
    cout << ans << endl;
}


#include <bits/stdc++.h>
inline long long read(){char c = getchar();long long x = 0,s = 1;
while(c < '0' || c > '9') {if(c == '-') s = -1;c = getchar();}
while(c >= '0' && c <= '9') {x = x*10 + c -'0';c = getchar();}
return x*s;}
using namespace std;
#define NewNode (TreeNode *)malloc(sizeof(TreeNode))
#define Mem(a,b) memset(a,b,sizeof(a))
#define lowbit(x) (x)&(-x)
const int N = 1e5 + 10;
const long long INFINF = 0x7f7f7f7f7f7f7f;
const int INF = 0x3f3f3f3f;
const double EPS = 1e-5;
const int mod = 1e9+7;
const double II = acos(-1);
const double PP = (II*1.0)/(180.00);
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll,ll> piil;
signed main()
{
    std::ios::sync_with_stdio(false);
    cin.tie(0),cout.tie(0);
    //    freopen("input.txt","r",stdin);
    //    freopen("output.txt","w",stdout);
    int n;
    cin >> n;
    map<ll,ll> mp;
    mp[0] = 0;
    ll sum[n+5] = {0},arr[n+5],ans = 0,flag = -1;
    for(int i = 2;i <= n+1;i++) cin >> arr[i];
    for(int i = 2;i <= n;i++)
    {
        sum[i] = arr[i]+sum[i-1];
        if(mp[sum[i]] && mp[sum[i]] >= flag-1)
            ans++,flag = i;
        mp[sum[i]] = i;
    }
    cout << ans << endl;
}


 #include<bits/stdc++.h>
 #include<algorithm>
 using namespace std;
 #include<string.h>
 #define boost ios_base::sync_with_stdio(false); cin.tie(NULL);
 #define vlli vector<long long int>
 #define lli long long int

 #define M 1000000007
 #define NM 600006
 #define rep(i,a,b) for(lli i=a;i<b;i++)
 #define repi(i,a,b) for(lli i=a;i>b;i--)
 #define pb push_back
 #define mp make_pair
const long double PI = acos(-1);
vector<lli> vx[100001];
map<lli,lli> vis;

/*
  ######  #   #   #####   #   #  #         #      |
     # #  #   #   #   #   #  #   #        # #     |
=====#@#==#@@@#===#@@@#===#@#====#=======#@@@#=====
     # #  #   #   #   #   #  #   #      #     #   |
  ######  #   #   #####   #   #  ##### #       #  |
*/

//set<pair<lli,lli> > dp,u1;
//set<pair<lli,lli> >::iterator it;
//set<lli>::reverse_iterator jt;
 //map<lli,vector<lli> > ukj;

//map<lli,lli >::iterator it;
//vector<lli> v;
//pair<lli,lli> it;
//////////////////////////

vector< pair<lli,lli> > findSubArrays(lli arr[],lli n)
{

    unordered_map<lli, vector<lli> > map;
    vector <pair<lli, lli>> out;

    int sum = 0;

    for (lli i = 0; i < n; i++)
    {

        sum += arr[i];

        if (sum == 0)
            out.push_back(make_pair(0, i));

        if (map.find(sum) != map.end())
        {
            // map[sum] stores starting index of all subarrays
            vector<lli> vc = map[sum];
            for (auto it = vc.begin(); it != vc.end(); it++)
                out.push_back(make_pair(*it + 1, i));
        }

        // Important - no else
        map[sum].push_back(i);
    }

    // return output vector
    return out;
}

void print(vector<pair<lli, lli>> out)
{
    for (auto it = out.begin(); it != out.end(); it++)
        cout << "Subarray found from Index " <<
            it->first << " to " << it->second << endl;
}

void Its_time_to_go_in_loop()
{
    lli n;cin>>n;
    lli arr[n];
    rep(i,0,n){cin>>arr[i];}
     vector<pair<lli, lli> > out = findSubArrays(arr, n);
    lli ans=out.size(),i=0,j=0;
    for(auto it = out.begin(); it != out.end(); it++ )
    {   j=i+1;
        if(vis[i]){i++;continue;}
        auto jt=it ; jt++;
        for(jt ; jt!=out.end();jt++)
        {
            if(
               (it->second>jt->first)&&(vis[j]!=1)){ans--;vis[j]=1;}
            j++;
        }
        i++;

    }
    cout<<ans<<"\n";
}

int main()
{
    boost;
    lli t=1;
    //cin>>t;
    //#ifdef NCR
      //  initialize();
    //#endif NCR

    while(t--)
    {
      Its_time_to_go_in_loop();
    }
   return 0;
}


 #include<bits/stdc++.h>
 #include<algorithm>
 using namespace std;
 #include<string.h>
 #define boost ios_base::sync_with_stdio(false); cin.tie(NULL);
 #define vlli vector<long long int>
 #define lli long long int

 #define M 1000000007
 #define NM 600006
 #define rep(i,a,b) for(lli i=a;i<b;i++)
 #define repi(i,a,b) for(lli i=a;i>b;i--)
 #define pb push_back
 #define mp make_pair
const long double PI = acos(-1);
vector<lli> vx[100001];
map<lli,lli> vis;

/*
  ######  #   #   #####   #   #  #         #      |
     # #  #   #   #   #   #  #   #        # #     |
=====#@#==#@@@#===#@@@#===#@#====#=======#@@@#=====
     # #  #   #   #   #   #  #   #      #     #   |
  ######  #   #   #####   #   #  ##### #       #  |
*/

//set<pair<lli,lli> > dp,u1;
//set<pair<lli,lli> >::iterator it;
//set<lli>::reverse_iterator jt;
 //map<lli,vector<lli> > ukj;

//map<lli,lli >::iterator it;
//vector<lli> v;
//pair<lli,lli> it;
//////////////////////////

void Its_time_to_go_in_loop()
{
    lli n;cin>>n;
    lli arr[n];
    map<lli,lli>dp;
    lli sum=0,ans=0;
    rep(i,0,n)
    {
        cin>>arr[i];
        sum+=arr[i];

        if(dp[sum]&&(sum!=0)){ans++;
                          sum=a[i];
                          dp.clear();
                          dp[arr[i]]=1;
                          }
        else if(sum==0)
        {
            ans++;dp.clear();dp[arr[i]]=1;sum=arr[i];
        }
        dp[sum]=1;
    }
    cout<<ans;

}

int main()
{
    boost;
    lli t=1;
    //cin>>t;
    //#ifdef NCR
      //  initialize();
    //#endif NCR

    while(t--)
    {
      Its_time_to_go_in_loop();
    }
   return 0;
}


 #include<bits/stdc++.h>
 #include<algorithm>
 using namespace std;
 #include<string.h>
 #define boost ios_base::sync_with_stdio(false); cin.tie(NULL);
 #define vlli vector<long long int>
 #define lli long long int

 #define M 1000000007
 #define NM 600006
 #define rep(i,a,b) for(lli i=a;i<b;i++)
 #define repi(i,a,b) for(lli i=a;i>b;i--)
 #define pb push_back
 #define mp make_pair
const long double PI = acos(-1);
vector<lli> vx[100001];
lli vis[100000005]={0};

/*
  ######  #   #   #####   #   #  #         #      |
     # #  #   #   #   #   #  #   #        # #     |
=====#@#==#@@@#===#@@@#===#@#====#=======#@@@#=====
     # #  #   #   #   #   #  #   #      #     #   |
  ######  #   #   #####   #   #  ##### #       #  |
*/

//set<pair<lli,lli> > dp,u1;
//set<pair<lli,lli> >::iterator it;
//set<lli>::reverse_iterator jt;
 //map<lli,vector<lli> > ukj;

//map<lli,lli >::iterator it;
//vector<lli> v;
//pair<lli,lli> it;
//////////////////////////

vector< pair<lli,lli> > findSubArrays(lli arr[],lli n)
{

    unordered_map<lli, vector<lli> > map;
    vector <pair<lli, lli>> out;

    int sum = 0;

    for (lli i = 0; i < n; i++)
    {

        sum += arr[i];

        if (sum == 0)
            out.push_back(make_pair(0, i));

        if (map.find(sum) != map.end())
        {
            // map[sum] stores starting index of all subarrays
            vector<lli> vc = map[sum];
            for (auto it = vc.begin(); it != vc.end(); it++)
                out.push_back(make_pair(*it + 1, i));
        }

        // Important - no else
        map[sum].push_back(i);
    }

    // return output vector
    return out;
}

void print(vector<pair<lli, lli>> out)
{
    for (auto it = out.begin(); it != out.end(); it++)
        cout << "Subarray found from Index " <<
            it->first << " to " << it->second << endl;
}

void Its_time_to_go_in_loop()
{
    lli n;cin>>n;
    lli arr[n];
    rep(i,0,n){cin>>arr[i];}
     vector<pair<lli, lli> > out = findSubArrays(arr, n);
    lli ans=out.size(),i=0,j=0;
    for(auto it = out.begin(); it != out.end(); it++ )
    {   j=i+1;
        if(vis[i]){i++;continue;}
        auto jt=it ; jt++;
        for(jt ; jt!=out.end();jt++)
        {
            if(
               (it->second>jt->first)&&(vis[j]!=1)){ans--;vis[j]=1;}
            j++;
        }
        i++;

    }
    cout<<ans<<"\n";
}

int main()
{
    boost;
    lli t=1;
    //cin>>t;
    //#ifdef NCR
      //  initialize();
    //#endif NCR

    while(t--)
    {
      Its_time_to_go_in_loop();
    }
   return 0;
}


 #include<bits/stdc++.h>
 #include<algorithm>
 using namespace std;
 #include<string.h>
 #define boost ios_base::sync_with_stdio(false); cin.tie(NULL);
 #define vlli vector<long long int>
 #define lli long long int

 #define M 1000000007
 #define NM 600006
 #define rep(i,a,b) for(lli i=a;i<b;i++)
 #define repi(i,a,b) for(lli i=a;i>b;i--)
 #define pb push_back
 #define mp make_pair
const long double PI = acos(-1);
vector<lli> vx[100001];
map<lli,lli> vis;

/*
  ######  #   #   #####   #   #  #         #      |
     # #  #   #   #   #   #  #   #        # #     |
=====#@#==#@@@#===#@@@#===#@#====#=======#@@@#=====
     # #  #   #   #   #   #  #   #      #     #   |
  ######  #   #   #####   #   #  ##### #       #  |
*/

//set<pair<lli,lli> > dp,u1;
//set<pair<lli,lli> >::iterator it;
//set<lli>::reverse_iterator jt;
 //map<lli,vector<lli> > ukj;

//map<lli,lli >::iterator it;
//vector<lli> v;
//pair<lli,lli> it;
//////////////////////////

void Its_time_to_go_in_loop()
{
    lli n;cin>>n;
    lli arr[n];
    map<lli,lli>dp;
    lli sum=0,ans=0;
    rep(i,0,n)
    {
        cin>>arr[i];
        sum+=arr[i];

        if(dp[sum]&&(sum!=0)){ans++;
                          sum=arr[i];
                          dp.clear();
                          dp[arr[i]]=1;
                          }
        else if(sum==0)
        {
            ans++;dp.clear();dp[arr[i]]=1;sum=arr[i];
        }
        dp[sum]=1;
    }
    cout<<ans;

}

int main()
{
    boost;
    lli t=1;
    //cin>>t;
    //#ifdef NCR
      //  initialize();
    //#endif NCR

    while(t--)
    {
      Its_time_to_go_in_loop();
    }
   return 0;
}


 #include<bits/stdc++.h>
 #include<algorithm>
 using namespace std;
 #include<string.h>
 #define boost ios_base::sync_with_stdio(false); cin.tie(NULL);
 #define vlli vector<long long int>
 #define lli long long int

 #define M 1000000007
 #define NM 600006
 #define rep(i,a,b) for(lli i=a;i<b;i++)
 #define repi(i,a,b) for(lli i=a;i>b;i--)
 #define pb push_back
 #define mp make_pair
const long double PI = acos(-1);
vector<lli> vx[100001];
map<lli,lli> vis;

/*
  ######  #   #   #####   #   #  #         #      |
     # #  #   #   #   #   #  #   #        # #     |
=====#@#==#@@@#===#@@@#===#@#====#=======#@@@#=====
     # #  #   #   #   #   #  #   #      #     #   |
  ######  #   #   #####   #   #  ##### #       #  |
*/

//set<pair<lli,lli> > dp,u1;
//set<pair<lli,lli> >::iterator it;
//set<lli>::reverse_iterator jt;
 //map<lli,vector<lli> > ukj;

//map<lli,lli >::iterator it;
//vector<lli> v;
//pair<lli,lli> it;
//////////////////////////

void Its_time_to_go_in_loop()
{
    lli n;cin>>n;
    lli arr[n];
    map<lli,lli>dp;
    lli sum=0,ans=0;
    rep(i,0,n)
    {
        cin>>arr[i];
        sum+=arr[i];

        if(dp[sum]&&(sum!=0)){ans++;
                          sum=0;
                          dp.clear();
                          }
        else if(sum==0)
        {
            ans++;dp.clear();dp[arr[i]]=1;sum=arr[i];
        }
        dp[sum]=1;
    }
    cout<<ans;

}

int main()
{
    boost;
    lli t=1;
    //cin>>t;
    //#ifdef NCR
      //  initialize();
    //#endif NCR

    while(t--)
    {
      Its_time_to_go_in_loop();
    }
   return 0;
}


 #include<bits/stdc++.h>
 #include<algorithm>
 using namespace std;
 #include<string.h>
 #define boost ios_base::sync_with_stdio(false); cin.tie(NULL);
 #define vlli vector<long long int>
 #define lli long long int

 #define M 1000000007
 #define NM 600006
 #define rep(i,a,b) for(lli i=a;i<b;i++)
 #define repi(i,a,b) for(lli i=a;i>b;i--)
 #define pb push_back
 #define mp make_pair
const long double PI = acos(-1);
vector<lli> vx[100001];
lli vis[100005]={0};

/*
  ######  #   #   #####   #   #  #         #      |
     # #  #   #   #   #   #  #   #        # #     |
=====#@#==#@@@#===#@@@#===#@#====#=======#@@@#=====
     # #  #   #   #   #   #  #   #      #     #   |
  ######  #   #   #####   #   #  ##### #       #  |
*/

//set<pair<lli,lli> > dp,u1;
//set<pair<lli,lli> >::iterator it;
//set<lli>::reverse_iterator jt;
 //map<lli,vector<lli> > ukj;

//map<lli,lli >::iterator it;
//vector<lli> v;
//pair<lli,lli> it;
//////////////////////////

vector< pair<lli,lli> > findSubArrays(lli arr[],lli n)
{

    unordered_map<lli, vector<lli> > map;
    vector <pair<lli, lli>> out;

    int sum = 0;

    for (lli i = 0; i < n; i++)
    {

        sum += arr[i];

        if (sum == 0)
            out.push_back(make_pair(0, i));

        if (map.find(sum) != map.end())
        {
            // map[sum] stores starting index of all subarrays
            vector<lli> vc = map[sum];
            for (auto it = vc.begin(); it != vc.end(); it++)
                out.push_back(make_pair(*it + 1, i));
        }

        // Important - no else
        map[sum].push_back(i);
    }

    // return output vector
    return out;
}

void print(vector<pair<lli, lli>> out)
{
    for (auto it = out.begin(); it != out.end(); it++)
        cout << "Subarray found from Index " <<
            it->first << " to " << it->second << endl;
}

void Its_time_to_go_in_loop()
{
    lli n;cin>>n;
    lli arr[n];
    rep(i,0,n){cin>>arr[i];}
     vector<pair<lli, lli> > out = findSubArrays(arr, n);
    lli ans=out.size(),i=0,j=0;
    for(auto it = out.begin(); it != out.end(); it++ )
    {   j=i+1;
        if(vis[i]){i++;continue;}
        auto jt=it ; jt++;
        for(jt ; jt!=out.end();jt++)
        {
            if(
               (it->second>jt->first)&&(vis[j]!=1)){ans--;vis[j]=1;}
            j++;
        }
        i++;

    }
    cout<<ans<<"\n";
}

int main()
{
    boost;
    lli t=1;
    //cin>>t;
    //#ifdef NCR
      //  initialize();
    //#endif NCR

    while(t--)
    {
      Its_time_to_go_in_loop();
    }
   return 0;
}


 #include<bits/stdc++.h>
 #include<algorithm>
 using namespace std;
 #include<string.h>
 #define boost ios_base::sync_with_stdio(false); cin.tie(NULL);
 #define vlli vector<long long int>
 #define lli long long int

 #define M 1000000007
 #define NM 600006
 #define rep(i,a,b) for(lli i=a;i<b;i++)
 #define repi(i,a,b) for(lli i=a;i>b;i--)
 #define pb push_back
 #define mp make_pair
const long double PI = acos(-1);
vector<lli> vx[100001];
map<lli,lli> vis;

/*
  ######  #   #   #####   #   #  #         #      |
     # #  #   #   #   #   #  #   #        # #     |
=====#@#==#@@@#===#@@@#===#@#====#=======#@@@#=====
     # #  #   #   #   #   #  #   #      #     #   |
  ######  #   #   #####   #   #  ##### #       #  |
*/

//set<pair<lli,lli> > dp,u1;
//set<pair<lli,lli> >::iterator it;
//set<lli>::reverse_iterator jt;
 //map<lli,vector<lli> > ukj;

//map<lli,lli >::iterator it;
//vector<lli> v;
//pair<lli,lli> it;
//////////////////////////

vector< pair<lli,lli> > findSubArrays(lli arr[],lli n)
{

    unordered_map<lli, vector<lli> > map;
    vector <pair<lli, lli>> out;

    int sum = 0;

    for (lli i = 0; i < n; i++)
    {

        sum += arr[i];

        if (sum == 0)
            out.push_back(make_pair(0, i));

        if (map.find(sum) != map.end())
        {

            vector<lli> vc = map[sum];
            for (auto it = vc.begin(); it != vc.end(); it++)
                out.push_back(make_pair(*it + 1, i));
        }

        map[sum].push_back(i);
    }

    return out;
}

void Its_time_to_go_in_loop()
{
    lli n;cin>>n;
    lli arr[n];
    rep(i,0,n){cin>>arr[i];}
     vector<pair<lli, lli> > out = findSubArrays(arr, n);
    lli ans=out.size(),mx=0,i=0;
    for(auto it = out.begin(); it != out.end(); it++ )
    {
        if(it->first<mx){ans--;}
        else mx=max(mx,it->second);

       i++;
    }
    cout<<ans<<"\n";
}

int main()
{
    boost;
    lli t=1;
    //cin>>t;
    //#ifdef NCR
      //  initialize();
    //#endif NCR

    while(t--)
    {
      Its_time_to_go_in_loop();
    }
   return 0;
}


 #include<bits/stdc++.h>
 #include<algorithm>
 using namespace std;
 #include<string.h>
 #define boost ios_base::sync_with_stdio(false); cin.tie(NULL);
 #define vlli vector<long long int>
 #define lli long long int

 #define M 1000000007
 #define NM 600006
 #define rep(i,a,b) for(lli i=a;i<b;i++)
 #define repi(i,a,b) for(lli i=a;i>b;i--)
 #define pb push_back
 #define mp make_pair
const long double PI = acos(-1);
vector<lli> vx[100001];
map<lli,lli> vis;

/*
  ######  #   #   #####   #   #  #         #      |
     # #  #   #   #   #   #  #   #        # #     |
=====#@#==#@@@#===#@@@#===#@#====#=======#@@@#=====
     # #  #   #   #   #   #  #   #      #     #   |
  ######  #   #   #####   #   #  ##### #       #  |
*/

//set<pair<lli,lli> > dp,u1;
//set<pair<lli,lli> >::iterator it;
//set<lli>::reverse_iterator jt;
 //map<lli,vector<lli> > ukj;

//map<lli,lli >::iterator it;
//vector<lli> v;
//pair<lli,lli> it;
//////////////////////////

vector< pair<lli,lli> > findSubArrays(lli arr[],lli n)
{

    unordered_map<lli, vector<lli> > map;
    vector <pair<lli, lli>> out;

    int sum = 0;

    for (lli i = 0; i < n; i++)
    {

        sum += arr[i];

        if (sum == 0)
            out.push_back(make_pair(0, i));

        if (map.find(sum) != map.end())
        {

            vector<lli> vc = map[sum];
            for (auto it = vc.begin(); it != vc.end(); it++)
                out.push_back(make_pair(*it + 1, i));
        }

        map[sum].push_back(i);
    }

    map.clear();
    return out;
}

void Its_time_to_go_in_loop()
{
    lli n;cin>>n;
    lli arr[n];
    rep(i,0,n){cin>>arr[i];}
     vector<pair<lli, lli> > out = findSubArrays(arr, n);
    lli ans=out.size(),mx=0;
    for(auto it = out.begin(); it != out.end(); it++ )
    {
        if(it->first<mx){ans--;}
        else mx=max(mx,it->second);

    }
    cout<<ans<<"\n";
}

int main()
{
    boost;
    lli t=1;
    //cin>>t;
    //#ifdef NCR
      //  initialize();
    //#endif NCR

    while(t--)
    {
      Its_time_to_go_in_loop();
    }
   return 0;
}


#include<iostream>
#include<map>
#define int long long
using namespace std;
map<int,int>mp;
const int maxn=2e5+10;
int arr[maxn];
signed main()
{
    int n,sum=0,ans=0;
    cin>>n;
    mp[0]=1;
    for(int i=0;i<n;i++){
        cin>>arr[i];
        sum+=arr[i];
        if(mp[sum]==0){
            mp[sum]=1;
        }
        else{
            if(sum!=0)  mp[sum]=0;
            ans++;
            sum=arr[i];
            mp[sum]=1;
        }
    }
    cout<<ans<<endl;
}
//子段和为0 -> 前缀和与map


#include<iostream>
#include<map>
#define int long long
using namespace std;
map<int,int>mp;
const int maxn=2e5+10;
int arr[maxn];
signed main()
{
    int n,sum=0,ans=0;
    cin>>n;
    mp[0]=1;
    for(int i=0;i<n;i++){
        cin>>arr[i];
        sum+=arr[i];
        if(mp[sum]==0){
            mp[sum]=1;
        }
        else{
            if(sum!=0)  mp[sum]=0;
            ans++;
            sum=0;
        }
    }
    cout<<ans<<endl;
}
//子段和为0 -> 前缀和与map


#include<iostream>
#include<map>
#define int long long
using namespace std;
map<int,int>mp;
const int maxn=2e5+10;
int arr[maxn];
signed main()
{
    int n,sum=0,ans=0;
    cin>>n;
    mp[0]=1;
    for(int i=0;i<n;i++){
        cin>>arr[i];
        sum+=arr[i];
        if(mp[sum]==0){
            mp[sum]=1;
        }
        else{
            if(sum!=0)  mp[sum]=0;
            ans++;
            sum=arr[i];
        }
    }
    cout<<ans<<endl;
}
//子段和为0 -> 前缀和与map


#include<iostream>
#include<map>
#define int long long
using namespace std;
map<int,int>mp;
const int maxn=2e5+10;
int arr[maxn];
signed main()
{
    int n,sum=0,ans=0,flag=0;
    cin>>n;
    for(int i=0;i<n;i++){
        flag=0;
        cin>>arr[i];
        sum+=arr[i];
        if(mp[sum]==0){
            mp[sum]=1;
        }
        else{
            ans++;
            sum=0;
            flag=1;//末尾判断 见样例4
        }
    }
    if(sum==0&&flag)    ans++;
    cout<<ans<<endl;
}
//子段和为0 -> 前缀和与map


#include<iostream>
#include<map>
#define int long long
using namespace std;
map<int,int>mp;
const int maxn=2e5+10;
int arr[maxn];
signed main()
{
    int n,sum=0,ans=0,flag=0;
    cin>>n;
    for(int i=0;i<n;i++){
        flag=0;
        cin>>arr[i];
        sum+=arr[i];
        if(mp[sum]==0){
            mp[sum]=1;
        }
        else{
            ans++;
            sum=0;
            flag=1;//末尾判断 见样例4
        }
    }
    if(sum==0&&flag==0)    ans++;
    cout<<ans<<endl;
}
//子段和为0 -> 前缀和与map


#include<iostream>
#include<map>
#define int long long
using namespace std;
map<int,int>mp;
const int maxn=2e5+10;
int arr[maxn];
signed main()
{
    int n,sum=0,ans=0;
    cin>>n;
    mp[0]=1;
    for(int i=0;i<n;i++){
        cin>>arr[i];
        sum+=arr[i];
        if(mp[sum]==0){
            mp[sum]=1;
        }
        else{
            mp[sum]=0;
            ans++;
            sum=0;
        }
    }
    if(sum==0)    ans++;
    cout<<ans<<endl;
}
//子段和为0 -> 前缀和与map


#include<iostream>
#include<map>
#define int long long
using namespace std;
map<int,int>mp;
const int maxn=2e5+10;
int arr[maxn];
signed main()
{
    int n,sum=0,ans=0;
    cin>>n;
    mp[0]=1;
    for(int i=0;i<n;i++){
        cin>>arr[i];
        sum+=arr[i];
        if(mp[sum]==0){
            mp[sum]=1;
        }
        else{//mp[sum]==1
            if(sum!=0)  mp[sum]=0;
            mp.clear();
            mp[0]=1;
            ans++;
            sum=arr[i];
            mp[sum]=1;
        }
    }
    cout<<ans<<endl;
}
//子段和为0 -> 前缀和与map


#include<iostream>
#include<map>
#define int long long
using namespace std;
map<int,int>mp;
const int maxn=2e5+10;
int arr[maxn];
signed main()
{
    int n,sum=0,ans=0;
    cin>>n;
    for(int i=0;i<n;i++){
        cin>>arr[i];
        sum+=arr[i];
        if(mp[sum]==0){
            mp[sum]=1;
        }
        else{
            ans++;
            sum=0;
        }
    }
    cout<<ans<<endl;
}


// Problem : D. Non-zero Segments
// Contest : Codeforces - Codeforces Round #674 (Div. 3)
// URL : https://codeforces.com/contest/1426/problem/D
// Memory Limit : 256 MB
// Time Limit : 2000 ms
// Powered by CP Editor (https://github.com/cpeditor/cp-editor)

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
#define vi vector<int>
#define vvi vector<vector<int> >
#define vb vector<bool>
#define vs vector<string>
#define vpii vector<pair<int,int> >
#define pii pair<int,int>
#define mii map<int,int>
#define mod 1000000007
#define pb push_back
#define ff first
#define ss second
#define mkp make_pair
#define all(v) v.begin(),v.end()
#define input(a,b,n) for(i=b;i<n;i++){cin>>a[i];}
#define print(a) for(i=0;i<a.size();i++){cout<<a[i]<<" ";}cout<<endl;
#define trace1(a); cout<<"a="<<a<<endl;
#define trace2(a,b); cout<<"a="<<a<<" b="<<b<<endl;
#define fast ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
const int inf=0x3f3f3f3f3f3f3f3f;
int power(int a, int b){
    int res = 1;
    while(b!=0){
        if(b&1){
            res *= a;
        }
        a = (a * a);
        b = (b / 2);
    }
    return res;
}
int32_t main()
{
	fast;
    int t;
    t=1;
    //cin>>t;
    while(t--)
    {
    	int n;
    	cin>>n;
    	vi a(n);
    	int i;
    	input(a,0,n);
    	vi pre(n,0);
    	pre[0]=a[0];
    	set<int> s;
    	s.insert(pre[0]);
    	int ans=0;
    	int last=-1;
    	mii m;
    	m[pre[0]]=0;
    	for(i=1;i<n;i++)
    	{
    		pre[i]=pre[i-1]+a[i];

    		if(s.find(pre[i])==s.end())
    		{
    			s.insert(pre[i]);
    			if(pre[i]==0)
    			{
    				ans++;
    			}
    			m[pre[i]]=i;
    		}
    		else
    		{
    			if(last<=m[pre[i]]+1)

    			{
    				//cout<<"i="<<i<<endl;
    				ans++;
    				m[pre[i]]=i;
    				last=i;
    			}
    			else
    			{
    				m[pre[i]]=i;
    			}
    		}
    	}
    //	print(a);
    	//print(pre);
    	cout<<ans<<endl;

	}
    return 0;
}


// Problem : D. Non-zero Segments
// Contest : Codeforces - Codeforces Round #674 (Div. 3)
// URL : https://codeforces.com/contest/1426/problem/D
// Memory Limit : 256 MB
// Time Limit : 2000 ms
// Powered by CP Editor (https://github.com/cpeditor/cp-editor)

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
#define vi vector<int>
#define vvi vector<vector<int> >
#define vb vector<bool>
#define vs vector<string>
#define vpii vector<pair<int,int> >
#define pii pair<int,int>
#define mii map<int,int>
#define mod 1000000007
#define pb push_back
#define ff first
#define ss second
#define mkp make_pair
#define all(v) v.begin(),v.end()
#define input(a,b,n) for(i=b;i<n;i++){cin>>a[i];}
#define print(a) for(i=0;i<a.size();i++){cout<<a[i]<<" ";}cout<<endl;
#define trace1(a); cout<<"a="<<a<<endl;
#define trace2(a,b); cout<<"a="<<a<<" b="<<b<<endl;
#define fast ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
const int inf=0x3f3f3f3f3f3f3f3f;
int power(int a, int b){
    int res = 1;
    while(b!=0){
        if(b&1){
            res *= a;
        }
        a = (a * a);
        b = (b / 2);
    }
    return res;
}
int32_t main()
{
	fast;
    int t;
    t=1;
    //cin>>t;
    while(t--)
    {
    	int n;
    	cin>>n;
    	vi a(n);
    	int i;
    	input(a,0,n);
    	vi pre(n,0);
    	pre[0]=a[0];
    	set<int> s;
    	s.insert(pre[0]);
    	int ans=0;
    	int last=-1;
    	mii m;
    	int cur=a[0];
    	m[pre[0]]=0;
    	s.insert(0);
    	m[0]=-1;
    	for(i=1;i<n;i++)
    	{
    		pre[i]=pre[i-1]+a[i];

    		if(s.find(pre[i])!=s.end())
    		{
    			if(m[pre[i]]<last)
    			{
    				m[pre[i]]=i;
    				s.insert(pre[i]);
    			}
    			else
    			{
    				ans++;
    				last=i;
    				m[0]=last;
    				s.insert(0);
    				cur=a[i];
    				m[cur]=i;
    				s.insert(cur);
    			}
    		}
    		else
    		{
    			m[pre[i]]=i;
    			s.insert(pre[i]);
    		}
    	}
    //	print(a);
    	//print(pre);
    	cout<<ans<<endl;

	}
    return 0;
}


// Problem : D. Non-zero Segments
// Contest : Codeforces - Codeforces Round #674 (Div. 3)
// URL : https://codeforces.com/contest/1426/problem/D
// Memory Limit : 256 MB
// Time Limit : 2000 ms
// Powered by CP Editor (https://github.com/cpeditor/cp-editor)

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
#define vi vector<int>
#define vvi vector<vector<int> >
#define vb vector<bool>
#define vs vector<string>
#define vpii vector<pair<int,int> >
#define pii pair<int,int>
#define mii map<int,int>
#define mod 1000000007
#define pb push_back
#define ff first
#define ss second
#define mkp make_pair
#define all(v) v.begin(),v.end()
#define input(a,b,n) for(i=b;i<n;i++){cin>>a[i];}
#define print(a) for(i=0;i<a.size();i++){cout<<a[i]<<" ";}cout<<endl;
#define trace1(a); cout<<"a="<<a<<endl;
#define trace2(a,b); cout<<"a="<<a<<" b="<<b<<endl;
#define fast ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
const int inf=0x3f3f3f3f3f3f3f3f;
int power(int a, int b){
    int res = 1;
    while(b!=0){
        if(b&1){
            res *= a;
        }
        a = (a * a);
        b = (b / 2);
    }
    return res;
}
int32_t main()
{
	fast;
    int t;
    t=1;
    //cin>>t;
    while(t--)
    {
    	int n;
    	cin>>n;
    	vi a(n);
    	int i;
    	input(a,0,n);
    	vi pre(n,0);
    	pre[0]=a[0];
    	set<int> s;
    	s.insert(pre[0]);
    	int ans=0;
    	int last=0;
    	mii m;
    	m[pre[0]]=0;
    	for(i=1;i<n;i++)
    	{
    		pre[i]=pre[i-1]+a[i];
    		if(pre[i]==0)
    		{
    			ans++;
    			last=i;
    		}
    		else
    		{
    			//cout<<"pre="<<pre[i]<<endl;
    			//cout<<"last="<<last<<endl;
    			//cout<<m[pre[i]]<<endl;
    			if(s.find(pre[i])==s.end())
    			{
    				s.insert(pre[i]);
    				m[pre[i]]=i;
    			}
    			else
    			{
    				if(last<=m[pre[i]]+1)
    				{
    					ans++;
    					last=i;
    					m[pre[i]]=i;
    				}
    				else
    				{
   						m[pre[i]]=i;
    				}
    			}
    		}
    	}
    //	print(a);
    //	print(pre);
    	cout<<ans<<endl;

	}
    return 0;
}


// Problem : D. Non-zero Segments
// Contest : Codeforces - Codeforces Round #674 (Div. 3)
// URL : https://codeforces.com/contest/1426/problem/D
// Memory Limit : 256 MB
// Time Limit : 2000 ms
// Powered by CP Editor (https://github.com/cpeditor/cp-editor)

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
#define vi vector<int>
#define vvi vector<vector<int> >
#define vb vector<bool>
#define vs vector<string>
#define vpii vector<pair<int,int> >
#define pii pair<int,int>
#define mii map<int,int>
#define mod 1000000007
#define pb push_back
#define ff first
#define ss second
#define mkp make_pair
#define all(v) v.begin(),v.end()
#define input(a,b,n) for(i=b;i<n;i++){cin>>a[i];}
#define print(a) for(i=0;i<a.size();i++){cout<<a[i]<<" ";}cout<<endl;
#define trace1(a); cout<<"a="<<a<<endl;
#define trace2(a,b); cout<<"a="<<a<<" b="<<b<<endl;
#define fast ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
const int inf=0x3f3f3f3f3f3f3f3f;
int power(int a, int b){
    int res = 1;
    while(b!=0){
        if(b&1){
            res *= a;
        }
        a = (a * a);
        b = (b / 2);
    }
    return res;
}
int32_t main()
{
	fast;
    int t;
    t=1;
    //cin>>t;
    while(t--)
    {
    	int n;
    	cin>>n;
    	vi a(n);
    	int i;
    	input(a,0,n);
    	vi pre(n,0);
    	pre[0]=a[0];
    	for(i=1;i<n;i++)
    	{
    		pre[i]=pre[i-1]+a[i];
    	}
    	//print(pre);
    	set<int> s;
    	vi up;
    	int num=1;
    	for(i=0;i<n;i++)
    	{
    		if(pre[i]!=0)
    		{
    			up.pb(a[i]);
    		}
    		else
    		{
    			up.pb(num);
    			up.pb(a[i]);
    			num++;
    		}
    	}
    	//print(up);
    	vi preup(up.size(),0);
    	preup[0]=up[0];
    	s.insert(preup[0]);
    	for(i=1;i<up.size();i++)
    	{
    		preup[i]=preup[i-1]+up[i];
    		if(s.find(preup[i])==s.end())
    		{
    			s.insert(preup[i]);
    		}
    		else
    		{
    			num++;
    		}
    	}
    //	print(preup);
    	cout<<num-1<<endl;
	}
    return 0;
}


// Problem : D. Non-zero Segments
// Contest : Codeforces - Codeforces Round #674 (Div. 3)
// URL : https://codeforces.com/contest/1426/problem/D
// Memory Limit : 256 MB
// Time Limit : 2000 ms
// Powered by CP Editor (https://github.com/cpeditor/cp-editor)

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
#define vi vector<int>
#define vvi vector<vector<int> >
#define vb vector<bool>
#define vs vector<string>
#define vpii vector<pair<int,int> >
#define pii pair<int,int>
#define mii map<int,int>
#define mod 1000000007
#define pb push_back
#define ff first
#define ss second
#define mkp make_pair
#define all(v) v.begin(),v.end()
#define input(a,b,n) for(i=b;i<n;i++){cin>>a[i];}
#define print(a) for(i=0;i<a.size();i++){cout<<a[i]<<" ";}cout<<endl;
#define trace1(a); cout<<"a="<<a<<endl;
#define trace2(a,b); cout<<"a="<<a<<" b="<<b<<endl;
#define fast ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
const int inf=0x3f3f3f3f3f3f3f3f;
int power(int a, int b){
    int res = 1;
    while(b!=0){
        if(b&1){
            res *= a;
        }
        a = (a * a);
        b = (b / 2);
    }
    return res;
}
int32_t main()
{
	fast;
    int t;
    t=1;
    //cin>>t;
    while(t--)
    {
    	int n;
    	cin>>n;
    	vi a(n);
    	int i;
    	input(a,0,n);
    	int last,cur,cnt;
    	mii m;
    	last=-1;
    	cur=a[0];
    	cnt=0;
    	m[0]=-1;
    	m[a[0]]=0;
    	for(i=1;i<n;i++)
    	{

    		cur=cur+a[i];
    		if(m.find(cur)==m.end())
    		{
    			m[cur]=i;
    		}
    		else
    		{
    			if(m[cur]>=last)
    			{

    				last=i;
    				m[0]=last;
    				cur=a[i];
    				m[cur]=i;
    				cnt++;
    			}
    			else
    			{
    				m[cur]=i;
    			}
    		}
    	}
    	cout<<cnt<<endl;

	}
    return 0;
}


// Problem : D. Non-zero Segments
// Contest : Codeforces - Codeforces Round #674 (Div. 3)
// URL : https://codeforces.com/contest/1426/problem/D
// Memory Limit : 256 MB
// Time Limit : 2000 ms
// Powered by CP Editor (https://github.com/cpeditor/cp-editor)

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
#define vi vector<int>
#define vvi vector<vector<int> >
#define vb vector<bool>
#define vs vector<string>
#define vpii vector<pair<int,int> >
#define pii pair<int,int>
#define mii map<int,int>
#define mod 1000000007
#define pb push_back
#define ff first
#define ss second
#define mkp make_pair
#define all(v) v.begin(),v.end()
#define input(a,b,n) for(i=b;i<n;i++){cin>>a[i];}
#define print(a) for(i=0;i<a.size();i++){cout<<a[i]<<" ";}cout<<endl;
#define trace1(a); cout<<"a="<<a<<endl;
#define trace2(a,b); cout<<"a="<<a<<" b="<<b<<endl;
#define fast ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
const int inf=0x3f3f3f3f3f3f3f3f;
int power(int a, int b){
    int res = 1;
    while(b!=0){
        if(b&1){
            res *= a;
        }
        a = (a * a);
        b = (b / 2);
    }
    return res;
}
int32_t main()
{
	fast;
    int t;
    t=1;
    //cin>>t;
    while(t--)
    {
    	int n;
    	cin>>n;
    	vi a(n);
    	int i;
    	input(a,0,n);
    	vi pre(n,0);
    	pre[0]=a[0];
    	set<int> s;
    	s.insert(pre[0]);
    	int ans=0;
    	int last=0;
    	mii m;
    	m[pre[0]]=0;
    	for(i=1;i<n;i++)
    	{
    		pre[i]=pre[i-1]+a[i];

    		if(s.find(pre[i])==s.end())
    		{
    			s.insert(pre[i]);
    			if(pre[i]==0)
    			{
    				ans++;
    			}
    			m[pre[i]]=i;
    		}
    		else
    		{
    			if(last<=m[pre[i]]+1)

    			{
    				//cout<<"i="<<i<<endl;
    				ans++;
    				m[pre[i]]=i;
    				last=i;
    			}
    		}
    	}
    //	print(a);
    	//print(pre);
    	cout<<ans<<endl;

	}
    return 0;
}


// Problem : D. Non-zero Segments
// Contest : Codeforces - Codeforces Round #674 (Div. 3)
// URL : https://codeforces.com/contest/1426/problem/D
// Memory Limit : 256 MB
// Time Limit : 2000 ms
// Powered by CP Editor (https://github.com/cpeditor/cp-editor)

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
#define vi vector<int>
#define vvi vector<vector<int> >
#define vb vector<bool>
#define vs vector<string>
#define vpii vector<pair<int,int> >
#define pii pair<int,int>
#define mii map<int,int>
#define mod 1000000007
#define pb push_back
#define ff first
#define ss second
#define mkp make_pair
#define all(v) v.begin(),v.end()
#define input(a,b,n) for(i=b;i<n;i++){cin>>a[i];}
#define print(a) for(i=0;i<a.size();i++){cout<<a[i]<<" ";}cout<<endl;
#define trace1(a); cout<<"a="<<a<<endl;
#define trace2(a,b); cout<<"a="<<a<<" b="<<b<<endl;
#define fast ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
const int inf=0x3f3f3f3f3f3f3f3f;
int power(int a, int b){
    int res = 1;
    while(b!=0){
        if(b&1){
            res *= a;
        }
        a = (a * a);
        b = (b / 2);
    }
    return res;
}
int32_t main()
{
	fast;
    int t;
    t=1;
    //cin>>t;
    while(t--)
    {
    	int n;
    	cin>>n;
    	vi a(n);
    	int i;
    	input(a,0,n);
    	vi pre(n,0);
    	pre[0]=a[0];
    	set<int> s;
    	s.insert(pre[0]);
    	int ans=0;
    	int last=0;
    	mii m;
    	m[pre[0]]=0;
    	for(i=1;i<n;i++)
    	{
    		pre[i]=pre[i-1]+a[i];

    		if(s.find(pre[i])==s.end())
    		{
    			s.insert(pre[i]);
    			if(pre[i]==0)
    			{
    				ans++;
    			}
    			m[pre[i]]=i;
    		}
    		else
    		{
    			if(last<=m[pre[i]]+1)

    			{
    				//cout<<"i="<<i<<endl;
    				ans++;
    				m[pre[i]]=i;
    				last=i;
    			}
    			else
    			{
    				m[pre[i]]=i;
    			}
    		}
    	}
    //	print(a);
    	//print(pre);
    	cout<<ans<<endl;

	}
    return 0;
}


// Problem : D. Non-zero Segments
// Contest : Codeforces - Codeforces Round #674 (Div. 3)
// URL : https://codeforces.com/contest/1426/problem/D
// Memory Limit : 256 MB
// Time Limit : 2000 ms
// Powered by CP Editor (https://github.com/cpeditor/cp-editor)

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
#define vi vector<int>
#define vvi vector<vector<int> >
#define vb vector<bool>
#define vs vector<string>
#define vpii vector<pair<int,int> >
#define pii pair<int,int>
#define mii map<int,int>
#define mod 1000000007
#define pb push_back
#define ff first
#define ss second
#define mkp make_pair
#define all(v) v.begin(),v.end()
#define input(a,b,n) for(i=b;i<n;i++){cin>>a[i];}
#define print(a) for(i=0;i<a.size();i++){cout<<a[i]<<" ";}cout<<endl;
#define trace1(a); cout<<"a="<<a<<endl;
#define trace2(a,b); cout<<"a="<<a<<" b="<<b<<endl;
#define fast ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
const int inf=0x3f3f3f3f3f3f3f3f;
int power(int a, int b){
    int res = 1;
    while(b!=0){
        if(b&1){
            res *= a;
        }
        a = (a * a);
        b = (b / 2);
    }
    return res;
}
int32_t main()
{
	fast;
    int t;
    t=1;
    //cin>>t;
    while(t--)
    {
    	int n;
    	cin>>n;
    	vi a(n);
    	int i;
    	input(a,0,n);

    	set<int> s;
    	s.insert(a[0]);
    	int ans=0;
    	int last=-1;
    	mii m;
    	int cur=a[0];
    	m[a[0]]=0;
    	s.insert(0);
    	m[0]=-1;
    	for(i=1;i<n;i++)
    	{
    		cur+=a[i];

    		if(s.find(cur)==s.end())
    		{
    			s.insert(cur);
    			m[cur]=i;
    		}
    		else
    		{
    			if(last<=m[cur])
    			{
    				//cout<<"i="<<i<<endl;
    				last=i;
    				ans++;
    				cur=a[i];
    				m[0]=last;
    				m[cur]=i;

    				s.insert(cur);
    			}
    			else
    			{
    				m[cur]=i;
    				s.insert(cur);
    			}
    		}
    	}
    //	print(a);
    	//print(pre);
    	cout<<ans<<endl;

	}
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define all(v) ((v).begin()),((v).end())
#define fast_IO ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define file_IO freopen("g1.txt","r",stdin);
#define PI 3.14159265358979323
#define vi vector<int>
#define vd vector<double>
#define pii pair<int,int>
#define pLL pair<long long,long long>
#define pdd pair<double,double>
#define pid pair<int,double>
#define pdi pair<double,int>
#define MAXNODES 100000+9

typedef long long ll;
typedef double dd;

int t,n;
int a[200005];
int ans = 0,sum = 0;
map<int,int>mp;

void _clear()
{
    mp.clear();
    mp[0] = 1;
}

int main()
{
#ifndef ONLINE_JUDGE
    file_IO
#else
#endif
    fast_IO;
    cin >> n;
    for(int i=0; i<n; i++)
    {
        cin >> a[i];
    }
    _clear();
    for(int i=0; i<n; i++)
    {
        sum += a[i];
        if(mp.find(sum) != mp.end())
        {
            _clear();
            ans++;
            mp[a[i]]=1;
        }
        else
            mp[sum]=1;
    }
    cout << ans <<'\n';

}


#include <bits/stdc++.h>
using namespace std;
#define all(v) ((v).begin()),((v).end())
#define fast_IO ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define file_IO freopen("g1.txt","r",stdin);
#define PI 3.14159265358979323
#define vi vector<int>
#define vd vector<double>
#define pii pair<int,int>
#define pLL pair<long long,long long>
#define pdd pair<double,double>
#define pid pair<int,double>
#define pdi pair<double,int>
#define MAXNODES 100000+9

typedef long long ll;
typedef double dd;

int t,n;
ll a[200005];
ll ans = 0,sum = 0;
set<ll>s;

void _clear()
{
    s.clear();
    s.insert(0);
}
int main()
{
#ifndef ONLINE_JUDGE
    file_IO
#else
#endif
    fast_IO;
    cin >> n;
    for(int i=0; i<n; i++)
    {
        cin >> a[i];
    }
    _clear();
    for(int i=0; i<n; i++)
    {
        sum += a[i];
        if(s.find(sum) != s.end())
        {
            _clear();
            ans++;
            sum = a[i];
        }
        s.insert(sum);
    }
    cout << ans <<'\n';

}


#include <bits/stdc++.h>
using namespace std;
#define all(v) ((v).begin()),((v).end())
#define fast_IO ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define file_IO freopen("g1.txt","r",stdin);
#define PI 3.14159265358979323
#define vi vector<int>
#define vd vector<double>
#define pii pair<int,int>
#define pLL pair<long long,long long>
#define pdd pair<double,double>
#define pid pair<int,double>
#define pdi pair<double,int>
#define MAXNODES 100000+9

typedef long long ll;
typedef double dd;

int t,n;
int a[200005];
int ans = 0,sum = 0;
set<int>s;

void _clear()
{
    s.clear();
    s.insert(0);
}
int main()
{
#ifndef ONLINE_JUDGE
    file_IO
#else
#endif
    fast_IO;
    cin >> n;
    for(int i=0; i<n; i++)
    {
        cin >> a[i];
    }
    _clear();
    for(int i=0; i<n; i++)
    {
        sum += a[i];
        if(s.find(sum) != s.end())
        {
            _clear();
            ans++;
            sum = a[i];
        }
        s.insert(sum);
    }
    cout << ans <<'\n';

}


#include <bits/stdc++.h>
using namespace std;
#define all(v) ((v).begin()),((v).end())
#define fast_IO ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define file_IO freopen("g1.txt","r",stdin);
#define PI 3.14159265358979323
#define vi vector<int>
#define vd vector<double>
#define pii pair<int,int>
#define pLL pair<long long,long long>
#define pdd pair<double,double>
#define pid pair<int,double>
#define pdi pair<double,int>
#define MAXNODES 100000+9

typedef long long ll;
typedef double dd;

int t,n;
int a[200005];
ll ans = 0,sum = 0;
set<int>s;

void _clear()
{
    s.clear();
    s.insert(0);
}
int main()
{
#ifndef ONLINE_JUDGE
    file_IO
#else
#endif
    fast_IO;
    cin >> n;
    for(int i=0; i<n; i++)
    {
        cin >> a[i];
    }
    _clear();
    for(int i=0; i<n; i++)
    {
        sum += a[i];
        if(s.find(sum) != s.end())
        {
            _clear();
            ans++;
            sum = a[i];
        }
        s.insert(sum);
    }
    cout << ans <<'\n';

}


#include <bits/stdc++.h>
using namespace std;
#define all(v) ((v).begin()),((v).end())
#define fast_IO ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define file_IO freopen("g1.txt","r",stdin);
#define PI 3.14159265358979323
#define vi vector<int>
#define vd vector<double>
#define pii pair<int,int>
#define pLL pair<long long,long long>
#define pdd pair<double,double>
#define pid pair<int,double>
#define pdi pair<double,int>
#define MAXNODES 100000+9

typedef long long ll;
typedef double dd;

int t,n;
ll a[200005];
ll ans = 0,sum = 0;
map<ll,ll>mp;

void _clear()
{
    mp.clear();
    mp[0] = 1;
}

int main()
{
#ifndef ONLINE_JUDGE
    file_IO
#else
#endif
    fast_IO;
    cin >> n;
    for(int i=0; i<n; i++)
    {
        cin >> a[i];
    }
    _clear();
    for(int i=0; i<n; i++)
    {
        sum += a[i];
        if(mp[sum] == 1)
        {
            _clear();
            ans++;
            sum=a[i];
        }
        mp[sum]=1;
    }
    cout << ans <<'\n';

}


#include <bits/stdc++.h>
using namespace std;
#define all(v) ((v).begin()),((v).end())
#define fast_IO ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define file_IO freopen("g1.txt","r",stdin);
#define PI 3.14159265358979323
#define vi vector<int>
#define vd vector<double>
#define pii pair<int,int>
#define pLL pair<long long,long long>
#define pdd pair<double,double>
#define pid pair<int,double>
#define pdi pair<double,int>
#define MAXNODES 100000+9

typedef long long ll;
typedef double dd;

int t,n;
int a[200005];
int ans = 0,sum = 0;
set<int>s;

void _clear()
{
    s.clear();
    s.insert(0);
}
int main()
{
#ifndef ONLINE_JUDGE
    file_IO
#else
#endif
    fast_IO;
    cin >> n;
    for(int i=0; i<n; i++)
    {
        cin >> a[i];
    }
    _clear();
    for(int i=0; i<n; i++)
    {
        sum += a[i];
        if(s.find(sum) != s.end())
        {
            _clear();
            ans++;
            s.insert(a[i]);
        }
        else
            s.insert(sum);
    }
    cout << ans <<'\n';

}


#include <bits/stdc++.h>
using namespace std;
#define all(v) ((v).begin()),((v).end())
#define fast_IO ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define file_IO freopen("g1.txt","r",stdin);
#define PI 3.14159265358979323
#define vi vector<int>
#define vd vector<double>
#define pii pair<int,int>
#define pLL pair<long long,long long>
#define pdd pair<double,double>
#define pid pair<int,double>
#define pdi pair<double,int>
#define MAXNODES 100000+9

typedef long long ll;
typedef double dd;

int t,n;
int a[200005];
int ans = 0,sum = 0;
set<int>s;

void _clear()
{
    s.clear();
    s.insert(0);
}
int main()
{
#ifndef ONLINE_JUDGE
    file_IO
#else
#endif
    fast_IO;
    cin >> n;
    for(int i=0; i<n; i++)
    {
        cin >> a[i];
    }
    _clear();
    for(int i=0; i<n; i++)
    {
        sum += a[i];
        if(s.find(sum) != s.end())
        {
            _clear();
            ans++;
            s.insert(a[i]);
        }
        s.insert(sum);
    }
    cout << ans <<'\n';

}


#include <stdio.h>
#include <string.h>
#define maxn 260
#define q 1000000007

typedef long long LL;

char s[maxn<<2][maxn<<2];
LL f[maxn],g[maxn];
int h[maxn];
int a[maxn][maxn];
int n,m;
int check(int x,int y){
	int num=0;
	for (int i=1;i<4;i++)
		for (int j=1;j<4;j++)
			if (s[x+i][y+j]!='.') num++;
	if (num==0 || num==1 || num==4 || num==5) return 3;
	if (num==2 || num==3) return s[x+1][y+1]=='.' ? 1 : 2;
	return s[x+2][y+2]=='.' ? 1 : 2;
}
inline int ver(int x,int y){return a[x][y]&1;}
inline int hor(int x,int y){return a[x][y]&2;}
int cal1(int y){
	if (n%2==1) return 0;
	for (int i=0;i<n;i++)
		if (!ver(i,y)) return 0;
	return 1;
}
LL cal2(int y){
	LL f[maxn];
	f[0]=1;
	for (int i=0;i<n;i++){
		f[i+1]=0;
		if (hor(i,y) && hor(i,y+1)) f[i+1]=(f[i+1]+f[i])%q;
		if (i>0 && ver(i,y) && ver(i,y+1) && ver(i-1,y) && ver(i-1,y+1)) f[i+1]=(f[i+1]+f[i-1])%q;
	}
	f[n]-=(h[y]&h[y+1]);
	return f[n];
}
int main(){
	int i,j,k;
	scanf("%d %d",&n,&m);
	for (i=0;i<4*n+1;i++) scanf("%s",s[i]);
	for (i=0;i<n;i++)
		for (j=0;j<m;j++) a[i][j]=check(i<<2,j<<2);
	for (i=0;i<m;i++) h[i]=cal1(i);
	for (i=0;i<m-1;i++) g[i]=cal2(i);
	f[0]=1;
	for (i=0;i<m;i++){
		f[i+1]=f[i]*h[i];
		if (i>0) f[i+1]=(f[i+1]+f[i-1]*g[i-1])%q;
	}
	printf("%I64d\n",f[m]);
	return 0;
}


#include <stdio.h>
#include <string.h>
#define maxn 260
#define q 1000000007

typedef long long LL;

char s[maxn<<2][maxn<<2];
LL f[maxn],g[maxn];
int h[maxn];
int a[maxn][maxn];
int n,m;
int check(int x,int y){
	int num=0;
	for (int i=1;i<4;i++)
		for (int j=1;j<4;j++)
			if (s[x+i][y+j]!='.') num++;
	if (num==0 || num==1 || num==4 || num==5) return 3;
	if (num==2 || num==3) return s[x+1][y+1]=='.' ? 1 : 2;
	return s[x+1][y+1]=='.' ? 1 : 2;
}
inline int ver(int x,int y){return a[x][y]&1;}
inline int hor(int x,int y){return a[x][y]&2;}
int cal1(int y){
	if (n%2==1) return 0;
	for (int i=0;i<n;i+=2)
		if (!ver(i,y)) return 0;
	return 1;
}
LL cal2(int y){
	LL f[maxn];
	f[0]=1;
	for (int i=0;i<n;i++){
		f[i+1]=0;
		if (hor(i,y) && hor(i,y+1)>0) f[i+1]=(f[i+1]+f[i])%q;
		if (i>0 && ver(i,y) && ver(i,y+1) && ver(i-1,y) && ver(i-1,y+1)) f[i+1]=(f[i+1]+f[i-1])%q;
	}
	f[n]-=(h[y]&h[y+1]);
	return f[n];
}
int main(){
	int i,j,k;
	scanf("%d %d",&n,&m);
	for (i=0;i<4*n+1;i++) scanf("%s",s[i]);
	for (i=0;i<n;i++)
		for (j=0;j<m;j++) a[i][j]=check(i<<2,j<<2);
	for (i=0;i<m;i++) h[i]=cal1(i);
	for (i=0;i<m-1;i++) g[i]=cal2(i);
	f[0]=1;
	for (i=0;i<m;i++){
		f[i+1]=f[i]*h[i];
		if (i>0) f[i+1]=(f[i+1]+f[i-1]*g[i-1])%q;
	}
	printf("%I64d\n",f[m]);
	return 0;
}


#include <stdio.h>
#include <string.h>
#define maxn 260
#define q 1000000007

typedef long long LL;

char s[maxn<<2][maxn<<2];
LL f[maxn],g[maxn];
int h[maxn];
int a[maxn][maxn];
int n,m;
int check(int x,int y){
    int num=0;
    for (int i=1;i<4;i++)
        for (int j=1;j<4;j++)
            if (s[x+i][y+j]!='.') num++;
    if (num==0 || num==1 || num==4 || num==5) return 3;
    if (num==2 || num==3) return s[x+1][y+1]=='.' ? 1 : 2;
    return s[x+1][y+2]=='.' ? 1 : 2;
}
inline int ver(int x,int y){return a[x][y]&1;}
inline int hor(int x,int y){return a[x][y]&2;}
int cal1(int y){
    if (n%2==1) return 0;
    for (int i=0;i<n;i++)
        if (!ver(i,y)) return 0;
    return 1;
}
LL cal2(int y){
    LL f[maxn];
    f[0]=1;
    for (int i=0;i<n;i++){
        f[i+1]=0;
        if (hor(i,y) && hor(i,y+1)) f[i+1]=(f[i+1]+f[i])%q;
        if (i>0 && ver(i,y) && ver(i,y+1) && ver(i-1,y) && ver(i-1,y+1)) f[i+1]=(f[i+1]+f[i-1])%q;
    }
    f[n]-=(h[y]&h[y+1]);
    return f[n];
}
int main(){
    int i,j,k;
    scanf("%d %d",&n,&m);
    for (i=0;i<4*n+1;i++) scanf("%s",s[i]);
    for (i=0;i<n;i++)
        for (j=0;j<m;j++) a[i][j]=check(i<<2,j<<2);
    for (i=0;i<m;i++) h[i]=cal1(i);
    for (i=0;i<m-1;i++) g[i]=cal2(i);
    f[0]=1;
    for (i=0;i<m;i++){
        f[i+1]=f[i]*h[i];
        if (i>0) f[i+1]=(f[i+1]+f[i-1]*g[i-1])%q;
    }
    printf("%I64d\n",f[m]);
    return 0;
}


#include <stdio.h>
#include <string.h>
#define maxn 260
#define q 1000000007

typedef long long LL;

char s[maxn<<2][maxn<<2];
LL f[maxn],g[maxn];
int h[maxn];
int a[maxn][maxn];
int n,m;
int check(int x,int y){
	int num=0;
	for (int i=1;i<4;i++)
		for (int j=1;j<4;j++)
			if (s[x+i][y+j]!='.') num++;
	if (num==0 || num==1 || num==4 || num==5) return 3;
	if (num==2 || num==3) return s[x+1][y+1]=='.' ? 1 : 2;
	return s[x+1][y+1]=='.' ? 1 : 2;
}
inline int ver(int x,int y){return a[x][y]&1;}
inline int hor(int x,int y){return a[x][y]&2;}
int cal1(int y){
	if (n%2==1) return 0;
	for (int i=0;i<n;i++)
		if (!ver(i,y)) return 0;
	return 1;
}
LL cal2(int y){
	LL f[maxn];
	f[0]=1;
	for (int i=0;i<n;i++){
		f[i+1]=0;
		if (hor(i,y) && hor(i,y+1)>0) f[i+1]=(f[i+1]+f[i])%q;
		if (i>0 && ver(i,y) && ver(i,y+1) && ver(i-1,y) && ver(i-1,y+1)) f[i+1]=(f[i+1]+f[i-1])%q;
	}
	f[n]-=(h[y]&h[y+1]);
	return f[n];
}
int main(){
	int i,j,k;
	scanf("%d %d",&n,&m);
	for (i=0;i<4*n+1;i++) scanf("%s",s[i]);
	for (i=0;i<n;i++)
		for (j=0;j<m;j++) a[i][j]=check(i<<2,j<<2);
	for (i=0;i<m;i++) h[i]=cal1(i);
	for (i=0;i<m-1;i++) g[i]=cal2(i);
	f[0]=1;
	for (i=0;i<m;i++){
		f[i+1]=f[i]*h[i];
		if (i>0) f[i+1]=(f[i+1]+f[i-1]*g[i-1])%q;
	}
	printf("%I64d\n",f[m]);
	return 0;
}


//For Future
//By JFantasy

#include <cstdio>
#include <cstring>

const int maxn = 305;
const int mod = 1000000007;

typedef long long LL;
LL dp[maxn];
int data[maxn][maxn] , n , m;

int getflag( char str[4][maxn*5] , int x ) {
    int st = (x-1)*4+1 , ed = (x-1)*4+3 , tot = 0;
    for ( int i = 1; i <= 3; i++ ) {
        for ( int j = st; j <= ed; j++ ) tot += str[i][j] == 'O';
    }
    if ( tot == 0 || tot == 1 || tot == 4 || tot == 5 ) return 0;
    else if ( tot == 2 || tot == 3 ) return str[3][st] == 'O' ? 1 : 2;
    else return str[1][st+1] == '.' ? 1 : 2;
}

int gettot( int x , int flag ) {
    if ( flag == 1 ) {
        if ( n % 2 ) return 0;
        for ( int i = 2; i <= n; i += 2 ) {
            if ( data[i][x] >= 2 || data[i-1][x] >= 2 ) return 0;
        }
        return 1;
    } else {
        int ret[maxn];
        memset( ret , 0 , sizeof(ret) );
        ret[0] = 1;
        for ( int i = 1; i <= n; i++ ) {
            if ( data[i][x-1] != 1 && data[i][x] != 1 ) ret[i] = ret[i-1];
            if ( i == 1 ) continue;
            if ( data[i][x-1] < 2 && data[i][x] < 2 && data[i-1][x] < 2 && data[i-1][x-1] < 2 ) ret[i] = ( ret[i] + ret[i-2] ) % mod;
        }
        return ret[n]-gettot(x-1,1)*gettot(x,1);
    }
}

void init() {
    scanf( "%d%d" , &n , &m );
    for ( int i = 1; i <= n; i++ ) {
        char str[4][maxn*5];
        for ( int j = 0; j < 4; j++ ) scanf( "%s" , str[j] );
        for ( int j = 1; j <= m; j++ ) {
            data[i][j] = getflag(str,j);
        }
    }
}

void work() {
    dp[0] = 1;
    for ( int i = 1; i <= m; i++ ) {
        if ( i > 1 ) dp[i] = ( (dp[i-1]*gettot(i,1))%mod + (dp[i-2]*gettot(i,2))%mod )%mod;
        else dp[i] = dp[i-1]*gettot(i,1)%mod;
    }
    printf( "%lld\n" , dp[m] );
}

int main() {
    init();
    work();
    return 0;
}


//For Future
//By JFantasy

#include <cstdio>
#include <cstring>

const int maxn = 305;
const int mod = 1000000007;

typedef long long LL;
LL dp[maxn];
int data[maxn][maxn] , n , m;

int getflag( char str[4][maxn*5] , int x ) {
    int st = (x-1)*4+1 , ed = (x-1)*4+3 , tot = 0;
    for ( int i = 1; i <= 3; i++ ) {
        for ( int j = st; j <= ed; j++ ) tot += str[i][j] == 'O';
    }
    if ( tot == 0 || tot == 1 || tot == 4 || tot == 5 ) return 0;
    else if ( tot == 2 || tot == 3 ) return str[3][st] == 'O' ? 1 : 2;
    else return str[1][st+1] == '.' ? 1 : 2;
}

int gettot( int x , int flag ) {
    if ( flag == 1 ) {
        if ( n % 2 ) return 0;
        for ( int i = 2; i <= n; i += 2 ) {
            if ( data[i][x] >= 2 || data[i-1][x] >= 2 ) return 0;
        }
        return 1;
    } else {
        int ret[maxn];
        memset( ret , 0 , sizeof(ret) );
        ret[0] = 1;
        for ( int i = 1; i <= n; i++ ) {
            if ( data[i][x-1] != 1 && data[i][x] != 1 ) ret[i] = ret[i-1];
            if ( i == 1 ) continue;
            if ( data[i][x-1] < 2 && data[i][x] < 2 && data[i-1][x] < 2 && data[i-1][x-1] < 2 ) ret[i] = ( ret[i] + ret[i-2] ) % mod;
        }
        return ret[n]-gettot(x,1);
    }
}

void init() {
    scanf( "%d%d" , &n , &m );
    for ( int i = 1; i <= n; i++ ) {
        char str[4][maxn*5];
        for ( int j = 0; j < 4; j++ ) scanf( "%s" , str[j] );
        for ( int j = 1; j <= m; j++ ) {
            data[i][j] = getflag(str,j);
        }
    }
}

void work() {
    dp[0] = 1;
    for ( int i = 1; i <= m; i++ ) {
        if ( i > 1 ) dp[i] = ( (dp[i-1]*gettot(i,1))%mod + (dp[i-2]*gettot(i,2))%mod )%mod;
        else dp[i] = dp[i-1]*gettot(i,1)%mod;
    }
    printf( "%lld\n" , dp[m] );
}

int main() {
    init();
    work();
    return 0;
}


#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <math.h>
#include <ctype.h>
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
#include <list>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <algorithm>
#include <functional>
using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<int,int> ii;
typedef vector<int> vi;

#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(),(x).end()
#define clr(t,v) memset((t),(v),sizeof(t))

const int inf=1999999999;
const double pi=acos(-1.0);
const double eps=1e-10;
char gc(){char c;while(isspace(c=getchar()));return c;}
int gs(char* s){gets(s);int l=strlen(s);while(l && isspace(s[l-1]))s[--l]=0;return l;}

int tiles[512];
void add(const string& s,int type)
{
    int t=0;
    for(int i=0;i<sz(s);i++)
        t=(2*t)+(s[i]=='O');
    tiles[t]=type;
}
void init()
{
    add(".........",3);
    add("....O....",3);
    add("O.O...O.O",3);
    add("O.O.O.O.O",3);
    add("..O...O..",1);
    add("..O.O.O..",1);
    add("O.OO.OO.O",1);
    add("O.......O",2);
    add("O...O...O",2);
    add("OOO...OOO",2);
}
int n,m;
char str[1010][1010];
void scan()
{
    gets(str[0]);
    sscanf(str[0],"%d%d",&n,&m);
    for(int i=0;i<4*n+1;i++)
        gets(str[i]);
}
bool hori[250][250],vert[250][250];
void gettile(int x,int y)
{
    int tx=4*x+1,ty=4*y+1,t=0;
    for(int i=0;i<3;i++)
        for(int j=0;j<3;j++)
            t=(t*2)+(str[tx+i][ty+j]=='O');
    t=tiles[t];
    vert[x][y]=(t&1);
    hori[x][y]=(t&2);
}
const int MOD=1000000007;
inline void addmod(int& a,int b)
{
    a=(a+b)%MOD;
}
inline void multmod(int& a,int b)
{
    a=(int)(((ll)b*a)%MOD);
}
int dp[251],dp2[251];
int getw1(int j)
{
    if((n%2)!=0)
        return 0;
    for(int i=0;i<n;i++)
        if(!vert[i][j])
            return 0;
    return 1;
}
int getw2(int j)
{
    clr(dp2,0);
    dp2[0]=1;
    for(int i=0;i<n;i++)
    {
        if(i<n-1)
        {
            if(vert[i][j] && vert[i][j+1] && vert[i+1][j] && vert[i+1][j+1])
                addmod(dp2[i+2],dp2[i]);
        }
        if(hori[i][j] && hori[i][j+1])
            addmod(dp2[i+1],dp2[i]);
    }
    bool ok=true;
    for(int i=0;i<n;i++)
        if(!vert[i][j] || !vert[i][j+1])
        {
            ok=false;
            break;
        }
    if(ok)
        dp2[n]--;
    return dp2[n];
}
void solve()
{
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++)
            gettile(i,j);

//  for(int i=0;i<n;i++)
//  {
//      for(int j=0;j<m;j++)
//          if(vert[i][j])
//              putchar('O');
//          else
//              putchar('.');
//      putchar('\n');
//  }
//  for(int i=0;i<n;i++)
//  {
//      for(int j=0;j<m;j++)
//          if(hori[i][j])
//              putchar('O');
//          else
//              putchar('.');
//      putchar('\n');
//  }

    clr(dp,0);
    dp[0]=1;
    for(int j=0;j<m;j++)
    {
//      printf("j %d: %d\n",j,dp[j]);
        if(j<m-1)
        {
            int t=dp[j];
            multmod(t,getw2(j));
            addmod(dp[j+2],t);
        }
        int t=dp[j];
        multmod(t,getw1(j));
        addmod(dp[j+1],t);
    }
    printf("%d\n",dp[m]);
}
int main()
{
//  freopen("i.txt","r",stdin); freopen("o.txt","w",stdout);
    init();
    scan();
    solve();
}


#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <math.h>
#include <ctype.h>
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
#include <list>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <algorithm>
#include <functional>
using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<int,int> ii;
typedef vector<int> vi;

#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(),(x).end()
#define clr(t,v) memset((t),(v),sizeof(t))

const int inf=1999999999;
const double pi=acos(-1.0);
const double eps=1e-10;
char gc(){char c;while(isspace(c=getchar()));return c;}
int gs(char* s){gets(s);int l=strlen(s);while(l && isspace(s[l-1]))s[--l]=0;return l;}

int tiles[512];
void add(const string& s,int type)
{
    int t=0;
    for(int i=0;i<sz(s);i++)
        t=(2*t)+(s[i]=='O');
    tiles[t]=type;
}
void init()
{
    add(".........",3);
    add("....O....",3);
    add("O.O...O.O",3);
    add("O.O.O.O.O",3);
    add("..O...O..",1);
    add("..O.O.O..",1);
    add("O.OO.OO.O",1);
    add("O.......O",2);
    add("O...O...O",2);
    add("OOO...OOO",2);
}
int n,m;
char str[1010][1010];
void scan()
{
    gets(str[0]);
    sscanf(str[0],"%d%d",&n,&m);
    for(int i=0;i<4*n+1;i++)
        gets(str[i]);
}
bool hori[250][250],vert[250][250];
void gettile(int x,int y)
{
    int tx=4*x+1,ty=4*y+1,t=0;
    for(int i=0;i<3;i++)
        for(int j=0;j<3;j++)
            t=(t*2)+(str[tx+i][ty+j]=='O');
    t=tiles[t];
    vert[x][y]=(t&1);
    hori[x][y]=(t&2);
}
const int MOD=1000000007;
inline void addmod(int& a,int b)
{
    a=(a+b)%MOD;
}
inline void multmod(int& a,int b)
{
    a=(int)(((ll)b*a)%MOD);
}
int dp[251],dp2[251];
int getw1(int j)
{
    if((n%2)!=0)
        return 0;
    for(int i=0;i<n;i++)
        if(!vert[i][j])
            return 0;
    return 1;
}
int getw2(int j)
{
    clr(dp2,0);
    dp2[0]=1;
    for(int i=0;i<n;i++)
    {
        if(i<n-1)
        {
            if(vert[i][j] && vert[i][j+1] && vert[i+1][j] && vert[i+1][j+1])
                addmod(dp2[i+2],dp2[i]);
        }
        if(hori[i][j] && hori[i][j+1])
            addmod(dp2[i+1],dp2[i]);
    }
    if((n%2)==0)
    {
        bool ok=true;
        for(int i=0;i<n;i++)
            if(!vert[i][j] || !vert[i][j+1])
            {
                ok=false;
                break;
            }
        if(ok)
            dp2[n]--;
    }
    return dp2[n];
}
void solve()
{
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++)
            gettile(i,j);

//  for(int i=0;i<n;i++)
//  {
//      for(int j=0;j<m;j++)
//          if(vert[i][j])
//              putchar('O');
//          else
//              putchar('.');
//      putchar('\n');
//  }
//  for(int i=0;i<n;i++)
//  {
//      for(int j=0;j<m;j++)
//          if(hori[i][j])
//              putchar('O');
//          else
//              putchar('.');
//      putchar('\n');
//  }

    clr(dp,0);
    dp[0]=1;
    for(int j=0;j<m;j++)
    {
//      printf("j %d: %d\n",j,dp[j]);
        if(j<m-1)
        {
            int t=dp[j];
            multmod(t,getw2(j));
            addmod(dp[j+2],t);
        }
        int t=dp[j];
        multmod(t,getw1(j));
        addmod(dp[j+1],t);
    }
    printf("%d\n",dp[m]);
}
int main()
{
//  freopen("i.txt","r",stdin); freopen("o.txt","w",stdout);
    init();
    scan();
    solve();
}


#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
using namespace std;

#define inf 1000000000
#define pi (2*acos(0.0))
#define rp(i, n) for (int i = 0; (i) < (n); ++(i))
#define rep(i, a, n) for (int i = (a); (i) < (n); ++(i))
#define rept(i, a, b) for (int i = (a); (i) <= (b); ++(i))
#define mp make_pair
#define pb push_back
#define all(a) a.begin(), a.end()
#define foreach(it, c) for(typeof((c).begin()) it=(c).begin(); it!=(c).end(); ++it)
#define vi vector<int>
#define vvi vector< vi >
#define pii pair<int, int>
#define ll long long
#define C(a) memset((a), 0, sizeof((a)))
#define fill(a, v) memset((a), v, sizeof((a)))
#define sz(c) ((int)(c).size())
#define uniq(c) (c).resize(unique(all(c))-(c).begin())
#pragma comment(linker, "/STACK:16777216")

vector<string> hor, ver;

inline bool isHor(string s) {
	rp(i, sz(hor))
		if (hor[i] == s)
			return true;
	return false;
}

inline bool isVer(string s) {
	rp(i, sz(ver))
		if (ver[i] == s)
			return true;
	return false;
}

inline char getClass(string s) {
	if (isHor(s)) return 'h';
	if (isVer(s)) return 'v';
	return 'c';
}

char buf[4][2000], s[10];

char a[300][300];
const int MOD = 1000000007;

int dpf[300], dpg[300][300][2];
int n, m;

int g(int i, int j, bool w) {
	if (j == n) return w;
	if (dpg[i][j][w] != -1) return dpg[i][j][w];

	if (a[j][i] == 'h') {
		if (i == m - 1) return dpg[i][j][w] = 0;
		if (a[j][i+1] == 'v') return dpg[i][j][w] = 0;
		return dpg[i][j][w] = g(i, j + 1, 1);
	}

	if (i == m - 1 && j == n - 1) return 0;
	if (j == n - 1) {
		if (a[j][i] != 'v' && a[j][i+1] != 'v') return dpg[i][j][w] = 1;
		return dpg[i][j][w] = 0;
	}
	if (i == m - 1 && a[j+1][i] != 'h') return dpg[i][j][w] = g(i, j + 2, w);

	if (a[j][i+1] == 'h') {
		if (a[j][i] == 'v') return dpg[i][j][w] = 0;
		return dpg[i][j][w] = g(i, j + 1, 1);
	}
	if (a[j][i+1] == 'v' || a[j][i] == 'v') {
		if (a[j+1][i] != 'h' && a[j+1][i+1] != 'h') return dpg[i][j][w] = g(i, j + 2, w);
		return dpg[i][j][w] = 0;
	}

	if (a[j][i] == 'c') {
		int factor = a[j+1][i+1] != 'h' && a[j+1][i] != 'h';
		return dpg[i][j][w] = ((ll)g(i, j+1, 1) + factor * g(i, j+2, w)) % MOD;
	}
}

int f(int i) {
	if (i == m) return 1;
	if (dpf[i] != -1) return dpf[i];

	bool isH = false, isV = false, isC = false;
	rp(j, n) {
		switch(a[j][i]) {
		case 'h': isH = true; break;
		case 'v': isV = true; break;
		case 'c': isC = true; break;
		}
	}

	if (!isH && !isC) {
		if (n % 2 == 1) return 0;
		return dpf[i] = f(i + 1);
	}

	if (!isH) {
		int factor = 1 - n % 2;
		if (i == m - 1) return dpf[i] = factor * f(i + 1) % MOD;
		return dpf[i] = ((factor * f(i + 1) % MOD) + ((ll)g(i, 0, 0) * f(i + 2))) % MOD;
	}

	if (i == m - 1) return dpf[i] = 0;
	return dpf[i] = ((ll) g(i, 0, 0) * f(i + 2)) % MOD;
}

int main()
{
	hor.pb("O.......O"); hor.pb("O...O...O"); hor.pb("OOO...OOO");
	ver.pb("..O...O.."); ver.pb("..O.O.O.."); ver.pb("O.OO.OO.O");
	memset(dpf, -1, sizeof(dpf));
	memset(dpg, -1, sizeof(dpg));
	s[9] = 0;
	scanf("%d%d\n", &n, &m);
	rp(i, n) {
		rp(j, 4) gets(buf[j]);
		rp(j, m) {
			rept(ibuf, 1, 3) rp(k, 3)
				s[(ibuf-1) * 3 + k] = buf[ibuf][4 * j + 1 + k];
			a[i][j] = getClass(s);
		}
	}

	int ans = f(0);
	cout << ans << endl;
	return 0;
}


#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
using namespace std;

#define inf 1000000000
#define pi (2*acos(0.0))
#define rp(i, n) for (int i = 0; (i) < (n); ++(i))
#define rep(i, a, n) for (int i = (a); (i) < (n); ++(i))
#define rept(i, a, b) for (int i = (a); (i) <= (b); ++(i))
#define mp make_pair
#define pb push_back
#define all(a) a.begin(), a.end()
#define foreach(it, c) for(typeof((c).begin()) it=(c).begin(); it!=(c).end(); ++it)
#define vi vector<int>
#define vvi vector< vi >
#define pii pair<int, int>
#define ll long long
#define C(a) memset((a), 0, sizeof((a)))
#define fill(a, v) memset((a), v, sizeof((a)))
#define sz(c) ((int)(c).size())
#define uniq(c) (c).resize(unique(all(c))-(c).begin())
#pragma comment(linker, "/STACK:16777216")

vector<string> hor, ver;

inline bool isHor(string s) {
	rp(i, sz(hor))
		if (hor[i] == s)
			return true;
	return false;
}

inline bool isVer(string s) {
	rp(i, sz(ver))
		if (ver[i] == s)
			return true;
	return false;
}

inline char getClass(string s) {
	if (isHor(s)) return 'h';
	if (isVer(s)) return 'v';
	return 'c';
}

char buf[4][2000], s[10];

char a[300][300];
const int MOD = 1000000007;

int dpf[300], dpg[300][300];
int n, m;

int g(int i, int j, bool w) {
	if (j == n) return w;
	if (dpg[i][j] != -1) return dpg[i][j];

	if (a[j][i] == 'h') {
		if (i == m - 1) return dpg[i][j] = 0;
		if (a[j][i+1] == 'v') return dpg[i][j] = 0;
		return dpg[i][j] = g(i, j + 1, 1);
	}

	if (i == m - 1 && j == n - 1) return 0;
	if (j == n - 1) {
		if (a[j][i] != 'v' && a[j][i+1] != 'v') return dpg[i][j] = 1;
		return dpg[i][j] = 0;
	}
	if (i == m - 1 && a[j+1][i] != 'h') return dpg[i][j] = g(i, j + 2, w);

	if (a[j][i+1] == 'h') {
		if (a[j][i] == 'v') return dpg[i][j] = 0;
		return dpg[i][j] = g(i, j + 1, 1);
	}
	if (a[j][i+1] == 'v' || a[j][i] == 'v') {
		if (a[j+1][i] != 'h' && a[j+1][i+1] != 'h') return dpg[i][j] = g(i, j + 2, w);
		return dpg[i][j] = 0;
	}

	if (a[j][i] == 'c') {
		int factor = a[j+1][i+1] != 'h' && a[j+1][i] != 'h';
		return dpg[i][j] = ((ll)g(i, j+1, 1) + factor * g(i, j+2, w)) % MOD;
	}
}

int f(int i) {
	if (i == m) return 1;
	if (dpf[i] != -1) return dpf[i];

	bool isH = false, isV = false, isC = false;
	rp(j, n) {
		switch(a[j][i]) {
		case 'h': isH = true; break;
		case 'v': isV = true; break;
		case 'c': isC = true; break;
		}
	}

	if (!isH && !isC) {
		if (n % 2 == 1) return 0;
		return dpf[i] = f(i + 1);
	}

	if (!isH) {
		int factor = 1 - n % 2;
		if (i == m - 1) return dpf[i] = factor * f(i + 1) % MOD;
		return dpf[i] = ((factor * f(i + 1) % MOD) + ((ll)g(i, 0, 0) * f(i + 2))) % MOD;
	}

	if (i == m - 1) return dpf[i] = 0;
	return dpf[i] = ((ll) g(i, 0, 0) * f(i + 2)) % MOD;
}

int main()
{
	hor.pb("O.......O"); hor.pb("O...O...O"); hor.pb("OOO...OOO");
	ver.pb("..O...O.."); ver.pb("..O.O.O.."); ver.pb("O.OO.OO.O");
	memset(dpf, -1, sizeof(dpf));
	memset(dpg, -1, sizeof(dpg));
	s[9] = 0;
	scanf("%d%d\n", &n, &m);
	rp(i, n) {
		rp(j, 4) gets(buf[j]);
		rp(j, m) {
			rept(ibuf, 1, 3) rp(k, 3)
				s[(ibuf-1) * 3 + k] = buf[ibuf][4 * j + 1 + k];
			a[i][j] = getClass(s);
		}
	}

	int ans = f(0);
	cout << ans << endl;
	return 0;
}


#include <iostream>
#include <cassert>

using namespace std;

enum {BOTH, VERT, HORIZ};

const int N_MAX = 400;

int P = 1000000007;
int N, M;
char grid[N_MAX * 4][N_MAX * 4];
int carpet[N_MAX][N_MAX];
int cols1[N_MAX];
int cols2[N_MAX];

int get_orientation(int x, int y) {
  int num_dots = 0;
  for (int i = 0; i < 3; i++)
    for (int j = 0; j < 3; j++)
      if (grid[x + i][y + j] == 'O')
	num_dots++;

  switch(num_dots) {
  case 0:
  case 1:
  case 4:
  case 5:
    return BOTH;
  case 2:
  case 3:
    return (grid[x][y] == 'O' ? HORIZ : VERT);
  case 6:
    return (grid[x][y + 1] == 'O' ? HORIZ : VERT);
  }
  assert(false);
}

bool tiles_horiz(int x, int y) {
  return (carpet[x][y] != VERT && carpet[x + 1][y] != VERT);
}
bool tiles_vert(int x, int y) {
  return (carpet[x][y] != HORIZ && carpet[x][y + 1] != HORIZ);
}

int num_vert_tilings(int col) {
  if (N % 2 == 1)
    return 0;
  for (int i = 0; i < N; i++) {
    if (carpet[i][col] == HORIZ)
      return 0;
  }
  return 1;
}

int num_horiz_tilings(int col) {
  long long dp[N + 1];
  dp[0] = 1LL;
  dp[1] = (tiles_horiz(0, col) ? 1LL : 0LL);

  for (int i = 2; i <= N; i++) {
    dp[i] = 0LL;
    if (tiles_vert(i - 2, col) && tiles_vert(i - 2, col + 1))
      dp[i] += dp[i - 2];
    if (tiles_horiz(i - 1, col))
      dp[i] += dp[i - 1];
    dp[i] %= P;
  }

  if (cols1[col] > 0 && cols1[col + 1] > 0)
    return (dp[N] + P - 1) % P;
  return dp[N];
}

int main() {
  cin >> N >> M;
  while (cin.get() != '\n');

  for (int i = 0; i < 4 * N + 1; i++) {
    cin.getline(grid[i], 4 * N_MAX);
    //    cout << grid[i] << endl;
  }

  for (int i = 0; i < N; i++) {
    for (int j = 0; j < M; j++) {
      carpet[i][j] = get_orientation(4 * i + 1, 4 * j + 1);
      //      cout << carpet[i][j] << (j == M - 1 ? "\n" : "");
    }
  }

  for (int i = 0; i < M; i++) {
    cols1[i] = num_vert_tilings(i);
    //    cout << cols1[i] << " ";
  }
  //  cout << endl;
  for (int i = 0; i < M - 1; i++) {
    cols2[i] = num_horiz_tilings(i);
    //    cout << cols2[i] << " ";
  }
  //  cout << endl;

  long long dp[M + 1];
  dp[0] = 1LL;
  dp[1] = (long long) cols1[0];
  for (int i = 2; i <= M; i++) {
    dp[i] = cols1[i - 1] * dp[i - 1];
    dp[i] %= P;
    dp[i] += cols2[i - 2] * dp[i - 2];
    dp[i] %= P;
  }
  cout << dp[M] << '\n';
}


#include <iostream>
#include <cassert>

using namespace std;

enum {BOTH, VERT, HORIZ};

const int N_MAX = 400;

int P = 1000000007;
int N, M;
char grid[N_MAX * 4][N_MAX * 4];
int carpet[N_MAX][N_MAX];
int cols1[N_MAX];
int cols2[N_MAX];

int get_orientation(int x, int y) {
  int num_dots = 0;
  for (int i = 0; i < 3; i++)
    for (int j = 0; j < 3; j++)
      if (grid[x + i][y + j] == 'O')
	num_dots++;

  switch(num_dots) {
  case 0:
  case 1:
  case 4:
  case 5:
    return BOTH;
  case 2:
  case 3:
    return (grid[x][y] == 'O' ? HORIZ : VERT);
  case 6:
    return (grid[x][y + 1] == 'O' ? HORIZ : VERT);
  }
  assert(false);
}

bool tiles_horiz(int x, int y) {
  return (carpet[x][y] != VERT && carpet[x][y + 1] != VERT);
}
bool tiles_vert(int x, int y) {
  return (carpet[x + 1][y] != HORIZ && carpet[x][y] != HORIZ);
}

int num_vert_tilings(int col) {
  if (N % 2 == 1)
    return 0;
  for (int i = 0; i < N; i++) {
    if (carpet[i][col] == HORIZ)
      return 0;
  }
  return 1;
}

int num_horiz_tilings(int col) {
  long long dp[N + 1];
  dp[0] = 1LL;
  dp[1] = (tiles_horiz(0, col) ? 1LL : 0LL);

  for (int i = 2; i <= N; i++) {
    dp[i] = 0LL;
    if (tiles_vert(i - 2, col) && tiles_vert(i - 2, col + 1))
      dp[i] += dp[i - 2];
    if (tiles_horiz(i - 1, col))
      dp[i] += dp[i - 1];
    dp[i] %= P;
  }

  if (cols1[col] > 0 && cols1[col + 1] > 0)
    return (dp[N] + P - 1) % P;
  return dp[N];
}

int main() {
  cin >> N >> M;
  while (cin.get() != '\n');

  for (int i = 0; i < 4 * N + 1; i++) {
    cin.getline(grid[i], 4 * N_MAX);
    //    cout << grid[i] << endl;
  }

  for (int i = 0; i < N; i++) {
    for (int j = 0; j < M; j++) {
      carpet[i][j] = get_orientation(4 * i + 1, 4 * j + 1);
      //      cout << carpet[i][j] << (j == M - 1 ? "\n" : "");
    }
  }

  for (int i = 0; i < M; i++) {
    cols1[i] = num_vert_tilings(i);
    //    cout << cols1[i] << " ";
  }
  //  cout << endl;
  for (int i = 0; i < M - 1; i++) {
    cols2[i] = num_horiz_tilings(i);
    //    cout << cols2[i] << " ";
  }
  //  cout << endl;

  long long dp[M + 1];
  dp[0] = 1LL;
  dp[1] = (long long) cols1[0];
  for (int i = 2; i <= M; i++) {
    dp[i] = cols1[i - 1] * dp[i - 1];
    dp[i] %= P;
    dp[i] += cols2[i - 2] * dp[i - 2];
    dp[i] %= P;
  }
  cout << dp[M] << '\n';
}


/* C Libs */
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cctype>
#include <climits>
#include <ctime>
/* IOstream Libs */
#include <iostream>
#include <fstream>
#include <sstream>
/* String Libs */
#include <string>
/* STL Containers */
#include <bitset>
#include <vector>
#include <queue>
#include <deque>
#include <stack>
#include <list>
#include <map>
#include <set>
/* STL Algorithm */
#include <algorithm>
/* Miscellaneous */
#include <complex>
#include <functional>
#include <iterator>
//#include <limits>
#include <numeric>
#include <typeinfo>
#include <utility>
#include <valarray>

using namespace std;

#define REP(i,s,t) for(int _t=t,i=s;i<_t;i++ )
#define REPP(i,s,t) for(int _t=t,i=s;i<=_t;i++)

#define LET(x,a) __typeof(a) x (a)
#define ITER(i,a,b) for(LET(i,a);i!=(b);++i)
#define FOREACH(it,v) ITER(it,v.begin(),v.end())

#define FILLA(a,x) memset(&a,x,sizeof(a))
#define FILL(a,x) memset(a,x,sizeof(a))
#define CLEARA(a,x) FILLA(a,0)
#define CLEAR(a) FILL(a,0)

#define m_p make_pair
#define fst first
#define snd second
typedef pair<int,int> PII;
typedef long long ll;
template<class T> void check_max( T&a, T b ){ if ( a < b ) a = b; }
template<class T> void check_min( T&a, T b ){ if ( a > b ) a = b; }

//#define debug

const ll MOD = 1E9+7;

const int MAXN = 300;

char inp[MAXN*4][MAXN*4];//(4n+1)*(4m+1)
int n,m;

int id[MAXN][MAXN];

int s2id( string s ){
	int res = 0;
	REP(i,0,s.length())
		res = res * 3 + (s[i]=='O');
	return res;
}
int inp2id( int x, int y ){
	string s = "";
	REP(i,0,3)REP(j,0,3) s += inp[x+i][y+j];
	return s2id( s );
}

map<int,bool> hori,vert;

void prep(){
	hori.clear();
	hori[s2id(".........")]=true;
	hori[s2id("....O....")]=true;
	hori[s2id("..O...O..")]=true;
	hori[s2id("..O.O.O..")]=true;
	hori[s2id("O.O...O.O")]=true;
	hori[s2id("O.O.O.O.O")]=true;
	hori[s2id("O.OO.OO.O")]=true;

	vert.clear();
	vert[s2id(".........")]=true;
	vert[s2id("....O....")]=true;
	vert[s2id("O.......O")]=true;
	vert[s2id("O...O...O")]=true;
	vert[s2id("O.O...O.O")]=true;
	vert[s2id("O.O.O.O.O")]=true;
	vert[s2id("OOO...OOO")]=true;
}

bool ok_hori[MAXN][MAXN];
bool ok_vert[MAXN][MAXN];

ll f[MAXN];
ll g[MAXN];

int main(){
	scanf("%d%d",&n,&m);
	REP(i,0,4*n+1)scanf("%s",inp[i]);
	REP(i,0,n)REP(j,0,m)
		id[i][j] = inp2id( i*4+1, j*4+1 );
	prep();

	CLEAR(ok_vert);
	CLEAR(ok_hori);
	REP(i,0,n)REP(j,0,m-1)
		ok_vert[i][j] = vert[ id[i][j] ] && vert[ id[i][j+1] ];
	REP(i,0,n-1)REP(j,0,m)
		ok_hori[i][j] = hori[ id[i][j] ] && hori[ id[i+1][j] ];

	/*
	puts("ok_vert");
	REP(i,0,n){
		REP(j,0,m-1) printf("%d ",ok_vert[i][j]); puts("");
	}
	puts("ok_hori");
	REP(i,0,n-1){
		REP(j,0,m) printf("%d ",ok_hori[i][j]); puts("");
	}
	*/

	CLEAR(f);
	f[0] = 1;
	REP(i,0,m){
		// add 1 column
		{
			CLEAR(g);
			g[0] = 1;
			REP(j,0,n) if(ok_hori[j][i]) g[j+2] += g[j];
			f[i+1] = ( f[i+1] + g[n]*f[i]%MOD ) % MOD;
		}
		if( i < m-1 ){
			//add 2 column
			CLEAR(g);
			g[0] = 1;
			REP(j,0,n){
				if ( ok_vert[j][i] )
					g[j+1] = ( g[j+1] + g[j] ) % MOD;
				if ( ok_hori[j][i] && ok_hori[j][i+1] )
					g[j+2] = ( g[j+2] + g[j] ) % MOD;
			}
			ll tmp = g[n];

			CLEAR(g);
			g[0] = 1;
			REP(j,0,n) if(ok_hori[j][i] && ok_hori[j][i+1]) g[j+2] += g[j];
			tmp -= g[n];

			f[i+2] = ( f[i+2] + tmp*f[i]%MOD ) % MOD;
		}
	}

	cout << f[m] << endl;

    return 0;
}


/*
 ID: ahaigh11
 PROG: ssu 110 dungeon
 URL:
 LANG: C++

 */
#include <iostream>
#include <string>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <utility>
#include <cassert>
#include <queue>
#include <ctime>
#include <map>
#include <set>
using namespace std;

#define REP(i, n) for(int i = 0; i < n; i++)
#define CL(x) memset(x, 0, sizeof(x))
typedef pair<double, double> is;

#define N 1050
#define EPS (1e-8)
#define MOD (1000000007)

int n, m, dp[N];
char vert[7][10] = {".........","....O....","..O...O..","..O.O.O..","O.O...O.O","O.O.O.O.O","O.OO.OO.O"},
	horiz[7][10] = {".........","....O....","O.......O","O...O...O","O.O...O.O","O.O.O.O.O","OOO...OOO"};
char p[N][N];
bool h_ok[N][N], v_ok[N][N];

void get(int x, int y, char* s) {
	s[9] = '\0';
	REP(i,3) REP(j,3)
		s[i*3+j] = p[4*x+1+i][4*y+1+j];
}

bool all_vert(int x) { //can we tile xth col vertical tiles (max 1 way)
	if (n%2) return false;
	REP(i,n) if (!v_ok[i][x]) return false;
	return true;
}
int horiz_ways(int x) { //how many ways to tile x & x+1 th col with SOME horiz tiles
	int b[N];
	REP(i, n) {
		b[i] = 0; //ways to tile first i rows
		if (h_ok[i][x] && h_ok[i][x+1])
			if (i == 0) b[i] = (b[i] + 1) % MOD;
				else b[i] = (b[i] + b[i-1]) % MOD;
		if (i && v_ok[i][x] && v_ok[i][x+1] && v_ok[i-1][x] && v_ok[i-1][x+1])
			if (i == 1) b[i] = (b[i] + 1) % MOD;
				else b[i] = (b[i] + b[i-2]) % MOD;
	}

	if (all_vert(x) && all_vert(x+1)) b[n-1] = (b[n-1] + (MOD - 1)) % MOD;
	return b[n-1] % MOD;
}

int main() {
	cin >> n >> m;
	REP(i,4*n+1) cin >> p[i];

	CL(h_ok); CL(v_ok);
	REP(i,n) REP(j,m) {
		char s[10]; get(i,j,s);
		REP(k,7) {
			if (!strcmp(s,horiz[k])) h_ok[i][j] = true;
			if (!strcmp(s,vert[k])) v_ok[i][j] = true;
		}

		//cout << i << " " << j << " " << h_ok[i][j] << " " << v_ok[i][j] << endl;
	}

	REP(i,m) {
		dp[i] = 0; //ways to tile first i **columns**
		if (all_vert(i)) {
			if (i) dp[i] = (dp[i] + dp[i-1]) % MOD;
				else dp[i] = (dp[i] + 1) % MOD;
		}

		//cout << i << " " << dp[i] << endl;

		if (i)
			dp[i] = ( dp[i] + ((long long)horiz_ways(i-1) * ((i==1)?1:dp[i-2])) % MOD ) % MOD;

		//cout << i << " " << dp[i] << endl;
		//cout << i << " " << horiz_ways(i-1) << endl;
	}
	cout << dp[m-1] << endl;
}


/*
 ID: ahaigh11
 PROG: ssu 110 dungeon
 URL:
 LANG: C++

 */
#include <iostream>
#include <string>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <utility>
#include <cassert>
#include <queue>
#include <ctime>
#include <map>
#include <set>
using namespace std;

#define REP(i, n) for(int i = 0; i < n; i++)
#define CL(x) memset(x, 0, sizeof(x))
typedef pair<double, double> is;

#define N 1050
#define EPS (1e-8)
#define MOD (1000000007)

int n, m, dp[N];
char vert[7][10] = {".........","....O....","..O...O..","..O.O.O..","O.O...O.O","O.O.O.O.O","O.OO.OO.O"},
	horiz[7][10] = {".........","....O....","O.......O","O...O...O","O.O...O.O","O.O.O.O.O","OOO...OOO"};
char p[N][N];
bool h_ok[N][N], v_ok[N][N];

void get(int x, int y, char* s) {
	s[9] = '\0';
	REP(i,3) REP(j,3)
		s[i*3+j] = p[4*x+1+i][4*y+1+j];
}

bool all_vert(int x) { //can we tile xth col vertical tiles (max 1 way)
	if (n%2) return false;
	REP(i,n) if (!v_ok[i][x]) return false;
	return true;
}
int horiz_ways(int x) { //how many ways to tile x & x+1 th col with SOME horiz tiles
	int b[N];
	REP(i, n) {
		b[i] = 0; //ways to tile first i rows
		if (v_ok[i][x] && v_ok[i][x+1])
			if (i == 0) b[i] = (b[i] + 1) % MOD;
				else b[i] = (b[i] + b[i-1]) % MOD;
		if (i && h_ok[i][x] && h_ok[i][x+1] && h_ok[i-1][x] && h_ok[i-1][x+1])
			if (i == 1) b[i] = (b[i] + 1) % MOD;
				else b[i] = (b[i] + b[i-2]) % MOD;
	}

	if (all_vert(x) && all_vert(x+1)) b[n-1] = (b[n-1] + (MOD - 1)) % MOD;
	return b[n-1] % MOD;
}

int main() {
	cin >> n >> m;
	REP(i,4*n+1) cin >> p[i];

	CL(h_ok); CL(v_ok);
	REP(i,n) REP(j,m) {
		char s[10]; get(i,j,s);
		REP(k,7) {
			if (!strcmp(s,horiz[k])) h_ok[i][j] = true;
			if (!strcmp(s,vert[k])) v_ok[i][j] = true;
		}

		//cout << i << " " << j << " " << h_ok[i][j] << " " << v_ok[i][j] << endl;
	}

	REP(i,m) {
		dp[i] = 0; //ways to tile first i **columns**
		if (all_vert(i)) {
			if (i) dp[i] = (dp[i] + dp[i-1]) % MOD;
				else dp[i] = (dp[i] + 1) % MOD;
		}

		if (i)
			dp[i] = ( dp[i] + ((long long)horiz_ways(i-1) * ((i==1)?1:dp[i-2])) % MOD ) % MOD;

		cout << i << " " << dp[i] << endl;
		//cout << i << " " << horiz_ways(i-1) << endl;
	}
	cout << dp[m-1] << endl;
}


/*
 ID: ahaigh11
 PROG: ssu 110 dungeon
 URL:
 LANG: C++

 */
#include <iostream>
#include <string>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <utility>
#include <cassert>
#include <queue>
#include <ctime>
#include <map>
#include <set>
using namespace std;

#define REP(i, n) for(int i = 0; i < n; i++)
#define CL(x) memset(x, 0, sizeof(x))
typedef pair<double, double> is;

#define N 1050
#define EPS (1e-8)
#define MOD (1000000007)

int n, m, dp[N];
char vert[7][10] = {".........","....O....","..O...O..","..O.O.O..","O.O...O.O","O.O.O.O.O","O.OO.OO.O"},
	horiz[7][10] = {".........","....O....","O.......O","O...O...O","O.O...O.O","O.O.O.O.O","OOO...OOO"};
char p[N][N];
bool h_ok[N][N], v_ok[N][N];

void get(int x, int y, char* s) {
	s[9] = '\0';
	REP(i,3) REP(j,3)
		s[i*3+j] = p[4*x+1+i][4*y+1+j];
}

bool all_vert(int x) { //can we tile xth col vertical tiles (max 1 way)
	if (n%2) return false;
	REP(i,n) if (!v_ok[i][x]) return false;
	return true;
}
int horiz_ways(int x) { //how many ways to tile x & x+1 th col with SOME horiz tiles
	int b[N];
	REP(i, n) {
		b[i] = 0; //ways to tile first i rows
		if (v_ok[i][x] && v_ok[i][x+1])
			if (i == 0) b[i] = (b[i] + 1) % MOD;
				else b[i] = (b[i] + b[i-1]) % MOD;
		if (i && h_ok[i][x] && h_ok[i][x+1] && h_ok[i-1][x] && h_ok[i-1][x+1])
			if (i == 1) b[i] = (b[i] + 1) % MOD;
				else b[i] = (b[i] + b[i-2]) % MOD;
	}

	if (all_vert(x) && all_vert(x+1)) b[n-1] = (b[n-1] + (MOD - 1)) % MOD;
	return b[n-1] % MOD;
}

int main() {
	cin >> n >> m;
	REP(i,4*n+1) cin >> p[i];

	CL(h_ok); CL(v_ok);
	REP(i,n) REP(j,m) {
		char s[10]; get(i,j,s);
		REP(k,7) {
			if (!strcmp(s,horiz[k])) h_ok[i][j] = true;
			if (!strcmp(s,vert[k])) v_ok[i][j] = true;
		}

		//cout << i << " " << j << " " << h_ok[i][j] << " " << v_ok[i][j] << endl;
	}

	REP(i,m) {
		dp[i] = 0; //ways to tile first i **columns**
		if (all_vert(i)) {
			if (i) dp[i] = (dp[i] + dp[i-1]) % MOD;
				else dp[i] = (dp[i] + 1) % MOD;
		}

		if (i)
			dp[i] = ( dp[i] + ((long long)horiz_ways(i-1) * ((i==1)?1:dp[i-2])) % MOD ) % MOD;

		//cout << i << " " << dp[i] << endl;
		//cout << i << " " << horiz_ways(i-1) << endl;
	}
	cout << dp[m-1] << endl;
}


// =========================================================
//
//       Filename:  prob77D.cpp
//
//    Description:  D. Domino Carpet
//
//        Version:  1.0
//        Created:  04/20/2011 12:26:35 PM
//       Revision:  none
//       Compiler:  g++
//
//         Author:  LI YAN (lyan), lyan@cs.ucr.edu
//        Company:  U of California Riverside
//      Copyright:  Copyright (c) 04/20/2011, LI YAN
//
// =========================================================

#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <vector>
#include <iostream>
#include <iomanip>
#include <sstream>
#include <algorithm>
#include <map>
using namespace std;

typedef long long LL;
typedef vector<int> VI;
typedef pair<int,int> PI;

#define INF (1<<29)
#define fort(i,a) for(typeof a.begin() i=a.begin(); i!=a.end(); ++i)
#define ALL(x) x.begin(), x.end()
#define PB push_back
#define MP make_pair

#define MOD 1000000007
int dp[300];
int carpet[300][300];

// 1: hori piece
// 2: vert piece
// 3: both
void parse(int n, int m)
{
    for(int r=0; r<n; ++r)
    {
        string lines[4];
        for(int i=0; i<4; ++i) getline(cin,lines[i]);
        //for(int i=0; i<4; ++i) cout << "line " << lines[i] << endl;
        for(int k=0; k < m; k++)
        {
            int cnt=0;
            for(int s=1; s<=3; s++) for(int t=1; t<=3; t++)
                cnt += (lines[s][4*k+t]=='O');
            //cout << r << " " << k << " " << cnt << endl;
            switch(cnt) {
            case 0: case 1: case 4: case 5: carpet[r][k] = 3; break;
            case 2: case 3:
                if (lines[1][4*k+1]=='O') carpet[r][k] = 1;
                else carpet[r][k] = 2;
                break;
            case 6:
                if (lines[1][4*k+2]=='O') carpet[r][k] = 1;
                else carpet[r][k] = 2;
                break;
            default: assert(false);
            }
        }
    }
}

bool isvert(int r, int c)
{ return (carpet[r][c] & 2) != 0; }

bool ishori(int r, int c)
{ return (carpet[r][c] & 1) != 0; }

void solve()
{
    memset(dp,0,sizeof dp);
    int n,m; cin >> n >> m; cin.ignore(1024,'\n');
    parse(n,m);

//    for(int r=0; r<n; ++r)
//    { for(int c=0; c<m; ++c) cout << carpet[r][c] << " "; cout << endl;}

    dp[0] = 1;
    for(int c=1; c<=m; ++c)
    {
        dp[c]=0;
        bool allvert = true;
        for(int r=1; r<=n; ++r) if (!isvert(r-1,c-1))
        { allvert=false; break; }
        if (n%2==0 && allvert) dp[c] += dp[c-1];
        if (c<2) continue;
        int dp2[300]; dp2[0]=1;
        for(int r=1; r<=n; ++r)
        {
            dp2[r] = 0;
            if (ishori(r-1,c-2) && ishori(r-1,c-1)) dp2[r] += dp2[r-1];
            if ( r>=2 && isvert(r-2,c-2) && isvert(r-2,c-1) &&
                isvert(r-1,c-2) && isvert(r-1,c-1))
                { dp2[r] = ((LL)dp2[r]+dp2[r-2])%MOD; }
            //cout << "r " << r << " " << dp2[r] << endl;
        }
        //cout << dp2[n] << endl;
        dp[c] = (dp[c]+(LL)dp2[n]*dp[c-2])%MOD;
        if (c>=2)
        {
            bool allvert = true;
            for(int r=1; r<=n; ++r) if (!(isvert(r-1,c-2) && isvert(r-1,c-1)))
            { allvert=false; break; }
            if (allvert && n%2==0) dp[c]=((LL)dp[c]-dp[c-2]+MOD)%MOD;
        }
        //cout << c << " " << dp[c] << endl;
    }
    cout << dp[m] << endl;
}

int main()
{
    solve();
}


// =========================================================
//
//       Filename:  prob77D.cpp
//
//    Description:  D. Domino Carpet
//
//        Version:  1.0
//        Created:  04/20/2011 12:26:35 PM
//       Revision:  none
//       Compiler:  g++
//
//         Author:  LI YAN (lyan), lyan@cs.ucr.edu
//        Company:  U of California Riverside
//      Copyright:  Copyright (c) 04/20/2011, LI YAN
//
// =========================================================

#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <vector>
#include <iostream>
#include <iomanip>
#include <sstream>
#include <algorithm>
#include <map>
using namespace std;

typedef long long LL;
typedef vector<int> VI;
typedef pair<int,int> PI;

#define INF (1<<29)
#define fort(i,a) for(typeof a.begin() i=a.begin(); i!=a.end(); ++i)
#define ALL(x) x.begin(), x.end()
#define PB push_back
#define MP make_pair

#define MOD 1000000007
int dp[300];
int carpet[300][300];

// 1: hori piece
// 2: vert piece
// 3: both
void parse(int n, int m)
{
    for(int r=0; r<n; ++r)
    {
        string lines[4];
        for(int i=0; i<4; ++i) getline(cin,lines[i]);
        //for(int i=0; i<4; ++i) cout << "line " << lines[i] << endl;
        for(int k=0; k < m; k++)
        {
            int cnt=0;
            for(int s=1; s<=3; s++) for(int t=1; t<=3; t++)
                cnt += (lines[s][4*k+t]=='O');
            //cout << r << " " << k << " " << cnt << endl;
            switch(cnt) {
            case 0: case 1: case 4: case 5: carpet[r][k] = 3; break;
            case 2: case 3:
                if (lines[1][4*k+1]=='O') carpet[r][k] = 1;
                else carpet[r][k] = 2;
                break;
            case 6:
                if (lines[1][4*k+2]=='O') carpet[r][k] = 1;
                else carpet[r][k] = 2;
                break;
            default: assert(false);
            }
        }
    }
}

void solve()
{
    memset(dp,0,sizeof dp);
    int n,m; cin >> n >> m; cin.ignore(1024,'\n');
    parse(n,m);

//    for(int r=0; r<n; ++r)
//    { for(int c=0; c<m; ++c) cout << carpet[r][c] << " "; cout << endl;}

    dp[0] = 1;
    for(int c=1; c<=m; ++c)
    {
        dp[c]=0;
        bool allvert = true;
        for(int r=0; r<n; ++r) if (!(carpet[r][c-1]&2))
        { allvert=false; break; }
        if (n%2==0 && allvert) dp[c] += dp[c-1];
        if (c<2) continue;
        int dp2[300]; dp2[0]=1;
        for(int r=1; r<=n; ++r)
        {
            dp2[r] = 0;
            if ((carpet[r-1][c-2]&1) && (carpet[r-1][c-1]&1))
                dp2[r] += dp2[r-1];
            if ( r>=2 && (carpet[r-2][c-2]&2) && (carpet[r-2][c-1]&2) &&
                (carpet[r-1][c-2]&2) && (carpet[r-1][c-1]&2))
                { dp2[r] = ((LL)dp2[r]+dp2[r-2])%MOD; }
            //cout << "r " << r << " " << dp2[r] << endl;
        }
        dp[c] = (dp[c]+(LL)dp2[n]*dp[c-2])%MOD;
        if (c>=2)
        {
            bool allvert = true;
            for(int r=0; r<n; ++r) if (!((carpet[r][c-2]&1) && (carpet[r][c-1]&1)))
            { allvert=false; break; }
            if (allvert && n%2==0) dp[c]=(dp[c]-dp[c-2]+MOD)%MOD;
        }
        //cout << c << " " << dp[c] << endl;
    }
    cout << dp[m] << endl;
}

int main()
{
    solve();
}