/* -----------------------
Autor: Tomasz Boguslawski
-------------------------- */
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<fstream>
#include<iomanip>
#include<string>
#include<sstream>
#include<cstring>
#include<map>
#include<vector>
#include<set>
#include<queue>
#include<algorithm>
#include <fstream>
#include<math.h>

#define LL long long
#define FOR(x, b, e) for(LL x = b; x <= (e); x++)
#define FORD(x, b, e) for(LL x = b; x >= (e); x--)
#define VAR(v, n) __typeof(n) v = (n)
#define ALL(c) (c).begin(), (c).end()
#define FOREACH(i, c) for(VAR(i, (c).begin()); i != (c).end(); ++i)
#define DEBUG if (debug)
#define MIN(a,b) ((a>b)?b:a)
#define MAX(a,b) ((a>b)?a:b)

using namespace std;

const long treeSize=16;
//const LL P=11;
const LL P=1000000007;
LL n;
LL a[310000];

class Node
{
    public:
    long num;
    long left, right;
};

Node t[1100000];

void buildTree(long k, long left, long right)
{
    t[k].left=left; t[k].right=right; t[k].num=k;
    if (right!=left)
    {
        long med = (left+right)/2;
        buildTree(k*2, left, med);
        buildTree(k*2+1, med+1, right);
    }
}

LL B[310000];

void gluptak()
{
    B[1]=1;
    FOR(k,1,n)
    {
        LL su=0;
        LL b=0;
        FORD(j,k,1)
        {
            su=(su+a[j])%P;
            if (su%2==0) b=(b+B[j])%P;
        }
        B[k+1]=b;
        //cout << "B["<<k+1<<"]=" << b << "\n";
    }
}

LL dodawajnik;

class Elem
{
    public:
    long index;
    LL value;
    LL sumaPar; LL sumaNPar;
    bool zmianaPar;
    LL realValue()
    {
        return (value+dodawajnik)%P;
    }
};

struct Comparator
{
    inline bool operator() (const Elem& e1, const Elem& e2)
    {
        return (e1.value<e2.value);
    }
};

vector<Elem> *elems;
long st, en;
long ds,de;

long realPos(long pos)
{
    long r=st+pos-1;
    if (r>n) r-=n;
    return r;
}

long findFirstBad(long left, long right, LL limit)
{
    if (right-left>5)
    {
        long med=(left+right)/2;
        if ((*elems)[realPos(med)].realValue()>=limit) return findFirstBad(left, med, limit);
        else return findFirstBad(med+1, right, limit);
    }
    else
    {
        FOR(i,left,right) if ((*elems)[realPos(i)].realValue()>=limit) return i;
        return -1;
    }
}

class Odcinek
{
public:
    long ds, de;
    Odcinek(long p_ds, long p_de)
    {
        ds=p_ds;
        de=p_de;
    }
};

vector<Odcinek> odwrocone;

void dodaj(LL v)
{
    cout << "Dodaje: " << v << "\n";
    LL limit=P-v;
    // mniejsze niz limit po prostu sie zwieksza
    // pozostale zmienia parzystosc
    // no to szukamy binarnie pierwszej liczby >=limit
    long newStart=findFirstBad(1,n,limit);
    cout << "! " << newStart << " " << realPos(newStart) << "\n";
    if (v%2==0)
    {
        // parzysta: zmieniaja sie >=limit
        if (newStart==-1)
        {
            // wszystkie sa mniejsze niz limit, zatem nic sie nie zmienia
        }
        else
        {
            // zmiana na odcinku od newStart do n
            odwrocone.push_back(Odcinek(newStart,n));
        }
    }
    else
    {
        // nieparzysta: zmieniaja sie <limit
        if (newStart==-1)
        {
            // wszystkie sa mniejsze niz limit, zatem zmieniaja się wszystkie od 1 do n
            odwrocone.push_back(Odcinek(1,n));
        }
        else
        {
            // zmiana na odcinku od 1 do newStart-1 (o ile newStart nie był równy 1)
            if (newStart!=1) odwrocone.push_back(Odcinek(1,newStart-1));
        }
    }
    cout << "Odwrocone: "; FOREACH(o,odwrocone) cout << o->ds << "-" << o->de << " "; cout << "\n";
    if (newStart!=-1)
    {
        FOREACH(o,odwrocone)
        {
            o->ds-=(newStart-1); if (o->ds<=0) o->ds+=n;
            o->de-=(newStart-1); if (o->de<=0) o->de+=n;
        }
    }
    if (odwrocone.size()>1)
    {
        LL qs,qe;
        if (odwrocone[0].de+1==odwrocone[1].ds) { qs=odwrocone[0].ds; qe=odwrocone[1].de; }
        else if (odwrocone[1].de+1==odwrocone[0].ds) { qs=odwrocone[1].ds; qe=odwrocone[2].de; }
        else { cout << "999\n"; exit(0); }
        odwrocone.clear();
        odwrocone.push_back(Odcinek(qs, qe));
    }
    if (newStart!=-1)
    {
        st=realPos(newStart);
    }
    dodawajnik = (dodawajnik+v)%P;

    cout << "Odwrocone: "; FOREACH(o,odwrocone) cout << o->ds << "-" << o->de << " "; cout << "\n";
}

void calculate()
{
    dodawajnik=0; ds=0; de=0;
    elems = new vector<Elem>(n+1);
    FOR(i,0,n) { (*elems)[i].sumaPar=0; (*elems)[i].sumaNPar=0; /* zmianaPar=false; */ };
    LL b=0; long i=0;
    FORD(k,n,1)
    {
        b = (b+a[k])%P;
        i++;
        (*elems)[i].index=k;
        (*elems)[i].value=b;
    }
    LL firstDodawajnik=P-b; st=1; en=n;
    sort((*elems).begin()+1, (*elems).end(), Comparator());
    FOR(i,1,n) cout << "value=" << (*elems)[i].value << " from position " << (*elems)[i].index << "\n";

    dodaj(firstDodawajnik);
    cout << "st=" << st << "\n";
    FOR(i,1,n) cout << (*elems)[realPos(i)].realValue() << " "; cout << "\n";

    dodaj(3);
}

/// MAIN
int main(int argc, char* argv[])
{
    // magic formula, which makes streams work faster:
	ios_base::sync_with_stdio(0);

    //FOR(i,1,treeSize*2-1) cout << i << " " << t[i].num << ": " << t[i].left << "-" << t[i].right << "\n";
    cin >> n;
    FOR(i,1,n) cin >> a[i];
    gluptak();
    cout << B[n+1] << "\n";
    return 0;
};
