using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static string InputPattern = "InputX";
static List<string> GetInputList()
{
var WillReturn = new List<string>();
if (InputPattern == "Input1") {
WillReturn.Add("3");
WillReturn.Add("1 -1 3");
//3
}
else if (InputPattern == "Input2") {
WillReturn.Add("6");
WillReturn.Add("2 -1 -1 9 -1 9");
//36
}
else if (InputPattern == "Input3") {
WillReturn.Add("5");
WillReturn.Add("1 -1 -1 -1 1000000000");
//999999972
}
else {
string wkStr;
while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
}
return WillReturn;
}
const long Hou = 1000000007;
static void Main()
{
List<string> InputList = GetInputList();
long[] AArr = InputList[1].Split(' ').Select(pX => long.Parse(pX)).ToArray();
List<RunLenLongArr.RunLenLongArrInfo> RunLenLongArrInfoList =
RunLenLongArr.DeriveRunLenLongArrInfoList(AArr);
long Answer = 1;
for (int I = 0; I <= RunLenLongArrInfoList.Count - 1; I++) {
if (RunLenLongArrInfoList[I].AppearNum == -1) {
long PrevNum = RunLenLongArrInfoList[I - 1].AppearNum;
long NextNum = RunLenLongArrInfoList[I + 1].AppearNum;
long Result = DerivePatternCnt(RunLenLongArrInfoList[I].RunLen, NextNum - PrevNum);
Answer *= Result;
Answer %= Hou;
}
}
Console.WriteLine(Answer);
}
static long DerivePatternCnt(long pTakeCnt, long pAddCnt)
{
return DeriveChoose(pTakeCnt + pAddCnt, pTakeCnt);
}
// nCr (mod Hou)を求める
static long DeriveChoose(long pN, long pR)
{
if (pN < pR) return 0;
pR = Math.Min(pR, pN - pR);
long WillReturn = 1;
for (long I = pN - pR + 1; I <= pN; I++) {
WillReturn *= I;
WillReturn %= Hou;
}
for (long I = 2; I <= pR; I++) {
WillReturn *= DeriveGyakugen(I);
WillReturn %= Hou;
}
return WillReturn;
}
// 引数の逆元を求める
static long DeriveGyakugen(long pLong)
{
return DeriveBekijyou(pLong, Hou - 2, Hou);
}
// 繰り返し2乗法で、(NのP乗) Mod Mを求める
static long DeriveBekijyou(long pN, long pP, long pM)
{
long CurrJyousuu = pN % pM;
long CurrShisuu = 1;
long WillReturn = 1;
while (true) {
// 対象ビットが立っている場合
if ((pP & CurrShisuu) > 0) {
WillReturn = (WillReturn * CurrJyousuu) % pM;
}
CurrShisuu *= 2;
if (CurrShisuu > pP) return WillReturn;
CurrJyousuu = (CurrJyousuu * CurrJyousuu) % pM;
}
}
}
/*
// 使用例1
List<RunLenLongArr.RunLenLongArrInfo> RunLenLongArrInfoList =
RunLenLongArr.DeriveRunLenLongArrInfoList(ランレングス圧縮する配列);
// 使用例2
foreach (RunLenLongArr.RunLenLongArrInfo EachRunLenLongArrInfo in
RunLenLongArr.DeriveRunLenLongArrInfoList(ランレングス圧縮する配列)) {
Console.WriteLine("AppearNum={0},RunLen={1}",
EachRunLenLongArrInfo.AppearNum, EachRunLenLongArrInfo.RunLen);
}
*/
#region RunLen
// ランレングス圧縮(longの配列)
internal class RunLenLongArr
{
// ランレングス圧縮情報
internal struct RunLenLongArrInfo
{
internal long AppearNum;
internal long RunLen;
}
// ランレングス圧縮結果を返す
internal static List<RunLenLongArrInfo> DeriveRunLenLongArrInfoList(long[] pArr)
{
var WillReturn = new List<RunLenLongArrInfo>();
// 空配列の対応
if (pArr.Length == 0) {
return WillReturn;
}
long PrevNum = pArr[0];
long SeqLen = 0;
for (int I = 0; I <= pArr.GetUpperBound(0); I++) {
if (pArr[I] != PrevNum) {
RunLenLongArrInfo WillAdd;
WillAdd.AppearNum = PrevNum;
WillAdd.RunLen = SeqLen;
WillReturn.Add(WillAdd);
SeqLen = 0;
PrevNum = pArr[I];
}
SeqLen++;
if (I == pArr.GetUpperBound(0)) {
RunLenLongArrInfo WillAdd;
WillAdd.AppearNum = pArr[I];
WillAdd.RunLen = SeqLen;
WillReturn.Add(WillAdd);
}
}
return WillReturn;
}
}
#endregion