//CNF-SAT

#include <stdio.h>

long n;
long ciag[1000002];
long konce[1000002];
long dwa_do_pot[1000002];
long licz_ciag,licz_kon,mnoznik,liczba,minus;
char rown[20000000];
long suma_ok=0;
int jedynki[1000002];
long zmienione[1000002];
long licz_zmienione;
long mnoznik_2;
char cc;


int DODAJ(int poz)
{
if (jedynki[poz]==0) jedynki[poz]=1;
else
   {
   jedynki[poz]=0;
   DODAJ(poz+1);
   }
return 0;
}


int CZY()
{
// Jest dobrze, jeśli przynajmniej jedna z każdej klauzuli jest prawidłowa
int ok_ogolny=1;
int ok_klauz=0;
for (int i=1; i<=licz_kon; i++)
   {// Dla każdej klauzuli
   ok_klauz=0;
   for (int j=konce[i-1]+1; j<=konce[i]; j++)
	   {// Po wszystkich literałach
	   if ( ((ciag[j]<0) && (jedynki[-ciag[j]]==0)) || ((ciag[j]>0)&&(jedynki[ciag[j]]==1)) )
	      {
	      ok_klauz=1;
	      break;
	      }
		}
	if (ok_klauz==0)
	   {
	   ok_ogolny=0;
	   break;
	   }
   }
return ok_ogolny;
}



int WEZ_GRUPE(int nr_grupy,int ktora_grupa,int uzyte_jed)
{
if (ktora_grupa>1)
   {// Bo jeśli to pierwsza grupa, to tego nie trzeba sprawdzać
   for (int j=konce[nr_grupy-1]+1; j<=konce[nr_grupy]; j++) 
	   {// Po kolei, czy jest pusta, lub taka sama
	   if (!(   ((ciag[j]>0) && (jedynki[ciag[j]]>=0))  ||  ((ciag[j]<0) && (jedynki[-ciag[j]]<=0))   ))
		   {// Jeśli nie, to przerwij. Nic nie zmieniono, więc niczego nie trzeba przywracać
		   return 0;
		   }
		}
   }

int zmien_pocz,zmien_kon;
zmien_pocz=licz_zmienione+1;
// Dopisanie jedynek do pamięci i zapamiętanie, które to były:
for (int j=konce[nr_grupy-1]+1; j<=konce[nr_grupy]; j++)
   {
   if (ciag[j]>0)
      {
      if (jedynki[ciag[j]]==0)
         {
         jedynki[ciag[j]]=1;
         licz_zmienione++; uzyte_jed++;
         zmienione[licz_zmienione]=ciag[j];
         }
      }
   else if (ciag[j]<0)
      {
      if (jedynki[-ciag[j]]==0)
         {
         jedynki[-ciag[j]]=-1;
         licz_zmienione++; uzyte_jed++;
         zmienione[licz_zmienione]=-ciag[j];
         }
      }
   }
zmien_kon=licz_zmienione;
// Później będzie trzeba wyzerować 'jedynki' w indeksach zapisanych w 'zmienione'


// Odpowiednio zmieniam wynik o 2^(n-uzyte_jed)
// Na plus, jeśli 'ktora_grupa' jest parzysta, a gdy nieparzysta - na minus.
if (ktora_grupa%2==0) dwa_do_pot[n-uzyte_jed]++;
else dwa_do_pot[n-uzyte_jed]--;

//Wywołuję rekurencyjnie kolejne grupy:
for (int kk=nr_grupy+1; kk<=licz_kon; kk++)
   {
   WEZ_GRUPE(kk,ktora_grupa+1,uzyte_jed);
   }

//No i cofnięcie tablicy jedynek do poprzedniego wyglądu:
for (int kk=zmien_pocz; kk<=zmien_kon; kk++) jedynki[zmienione[kk]]=0;
licz_zmienione=zmien_pocz-1;


return 0;
}




int main()
{
scanf("%ld\n",&n);
gets(rown);

/*
FILE *plik;
//plik=fopen("test_00.in","r"); // Odp: 3
//plik=fopen("test_01.in","r"); // Odp: 2
//plik=fopen("test_02.in","r"); // Odp: 10
//plik=fopen("test_03.in","r"); // Odp: 9
//plik=fopen("owca/cnf_owca1.in","r"); // Odp: 268
//plik=fopen("owca/cnf_owca2.in","r"); // Odp: 1334
//plik=fopen("owca/cnf_owca3.in","r"); // Odp: 10580
//plik=fopen("owca/cnf_owca4.in","r"); // Odp: 10566
//plik=fopen("owca/cnf_owca5.in","r"); // Odp: 6569
//plik=fopen("owca/cnf_owca6.in","r"); // Odp: 8604
//plik=fopen("owca/cnf_owca7.in","r"); // Odp: 7116
//plik=fopen("owca/cnf_owca8.in","r"); // Odp: 13527
//plik=fopen("owca/cnf_owca9.in","r"); // Odp: 19138
//plik=fopen("owca/cnf_owca10.in","r"); // Odp: 1640

//plik=fopen("lama/cnf_lama1.in","r"); // Odp: 930772170
//plik=fopen("lama/cnf_lama2.in","r"); // Odp: 43577009
//plik=fopen("lama/cnf_lama3.in","r"); // Odp:   239707828
//plik=fopen("lama/cnf_lama4.in","r"); // Odp: 808949359
//plik=fopen("lama/cnf_lama5.in","r"); // Odp:   31491702
//plik=fopen("lama/cnf_lama6.in","r"); // Odp: 557470540
//plik=fopen("lama/cnf_lama7.in","r"); // Odp: 220751964
//plik=fopen("lama/cnf_lama8.in","r"); // Odp: 925454494
//plik=fopen("lama/cnf_lama9.in","r"); // Odp: 149646238
//plik=fopen("lama/cnf_lama10.in","r"); // Odp: 980499050

//plik=fopen("stado/cnf_stado1.in","r"); // Odp:   360050271
//plik=fopen("stado/cnf_stado2.in","r"); // Odp:   433312657
//plik=fopen("stado/cnf_stado3.in","r"); // Odp:   3690382
//plik=fopen("stado/cnf_stado4.in","r"); // Odp:   687954900
//plik=fopen("stado/cnf_stado5.in","r"); // Odp: 408465841

fscanf(plik,"%ld\n",&n);
fgets(rown,20000000,plik);
fclose(plik);
*/



licz_ciag=0;
licz_kon=0;
konce[0]=0;
minus=1;
liczba=0;

int iii=0;
while (rown[iii]!=0)
   {
   cc=rown[iii];
   if ((cc>='0')&&(cc<='9'))
      {
      liczba=liczba*10 + long(cc-'0');
      }
   else if (cc=='v')
      {
      licz_ciag++;
      ciag[licz_ciag]=liczba*minus;
      
      minus=1;
      liczba=0;
      }
   else if (cc=='~')
      {
      minus=-1;
      }
   else if (cc=='^')
      {
      licz_ciag++;
      ciag[licz_ciag]=liczba*minus;
      licz_kon++;
      konce[licz_kon]=licz_ciag;
      
      minus=1;
      liczba=0;
      }
   iii++;
   }
licz_ciag++;
ciag[licz_ciag]=liczba*minus;
licz_kon++;
konce[licz_kon]=licz_ciag;


/*
for (int i=1; i<=licz_kon; i++)
   {
   for (int j=konce[i-1]+1; j<=konce[i]; j++) printf("%ld ",ciag[j]);
   printf("\n");
   }
printf("\n\n");
*/

//=========================================

suma_ok=0;
for (int i=0; i<=n+1; i++) dwa_do_pot[i]=0;
for (int i=1;i<=n+1;i++) jedynki[i]=0;

for (int i=1; i<=licz_kon; i++)
   {
//   printf("%ld/%ld\n",i,licz_kon);
   licz_zmienione=0;
   WEZ_GRUPE(i,1,0);
   }
dwa_do_pot[n]++;

/*
for (int i=0; i<=n; i++) printf("2^%ld * %ld +\n",i,dwa_do_pot[i]);
*/

mnoznik_2=1;
suma_ok=dwa_do_pot[0];
for (int i=1; i<=n; i++)
   {
   mnoznik_2=(mnoznik_2*2)%1000000007;
   if (dwa_do_pot[i]>0)
      {
      for (int j=1; j<=dwa_do_pot[i]; j++) 
		   {
			suma_ok=(suma_ok+mnoznik_2)%1000000007;
			}
      }
   else if (dwa_do_pot[i]<0)
      {
      for (int j=1; j<=-dwa_do_pot[i]; j++)
		   {
			suma_ok-=mnoznik_2;
			if (suma_ok<0) suma_ok+=1000000007;
			}
      }
   }

printf("%ld",suma_ok);


return 0;
}



