// use std::cmp;
use std::collections::BTreeMap;
// use std::collections::HashSet;
// use std::collections::VecDeque;


const MOD: i64 = 1_000_000_007;


fn pow(a: i64, b: i64) -> i64{
    if b == 0 {
        1
    } else {
        let t = pow(a, b/2);
        let t = t * t % MOD;
        if b % 2 == 0 {
            t
        } else {
            t * a % MOD
        }
    }
}

struct Solver {
    //dp0: Vec<Vec<i64>>,
    //dp1: Vec<Vec<i64>>,
}

impl Solver {

    fn new() -> Self {
        Solver {
            //dp0: vec![],
            //dp1: vec![],
        }
    }

    //fn solve(&mut self, h: &Vec<i64>, l: usize, r: usize) -> (i64, i64) {
    fn solve(&mut self, h: &Vec<i64>) -> (i64, i64) {
        /*
        if self.dp0[l][r] < 0 {
        }
        return (self.dp0[l][r], self.dp1[l][r]);
        */
        //println!("{:?}", h);
        let hmin = *h.iter().min().unwrap();
        let mut dp0 = 1;
        let mut dp1 = 1;
        let mut k = Vec::new();
        let mut cnt = 0;
        for i in 0..(h.len()) {
            let hi = h[i];
            if i + 1 < h.len() && (hi == hmin || h[i+1] == hmin) {
                cnt += 1;
            }
            if hi == hmin {
                if k.len() >= 1 {
                    let (mut tmp0, mut tmp1) = self.solve(&mut k);
                    tmp0 += tmp1;
                    tmp1 *= 2;
                    dp0 *= tmp0;
                    dp0 %= MOD;
                    dp1 *= tmp1;
                    dp1 %= MOD;
                    k.clear();
                }
            } else {
                k.push(hi - hmin);
            }
        }
                if k.len() >= 1 {
                    let (mut tmp0, mut tmp1) = self.solve(&mut k);
                    tmp0 += tmp1;
                    tmp1 *= 2;
                    dp0 *= tmp0;
                    dp0 %= MOD;
                    dp1 *= tmp1;
                    dp1 %= MOD;
                    k.clear();
                }

        //println!("{:?} {:?}", dp0, dp1);
        let ans1 = dp1 * pow(2, hmin - 1) % MOD;
        let ans0 = (dp0 - dp1) * pow(2, cnt) + dp1 * (pow(2, cnt) - 1) + ans1;
        let ans0 = (ans0 % MOD + MOD) % MOD;
        //println!("{:?} {:?}", ans0, ans1);
        return (ans0, ans1);
    }

    fn run(&mut self, sc: &mut Scanner) {
        let n = sc.read();
        let mut h = vec![0; n];
        for i in 0..n {
            h[i] = sc.read();
        }
        //self.dp0.resize(n, vec![-1; n]);
        //self.dp1.resize(n, vec![-1; n]);
        let (ans, _) = self.solve(&h);
        // println!("{:?}", self.dp0);
        // println!("{}", self.dp0[0][n-1]);
        println!("{}", ans * 2 % MOD);
    }
}


fn main() {
    let cin = stdin();
    Solver::new().run(&mut Scanner::new(cin.lock()));
}

// thanks, ir5
use std::io::{stdin, Read, StdinLock};
use std::str::FromStr;

struct Scanner<'a> {
    cin: StdinLock<'a>,
}

impl<'a> Scanner<'a> {
    fn new(cin: StdinLock<'a>) -> Scanner<'a> {
        Scanner { cin: cin }
    }

    fn read1<T: FromStr>(&mut self) -> Option<T> {
        let token = self.cin
            .by_ref()
            .bytes()
            .map(|c| c.unwrap() as char)
            .skip_while(|c| c.is_whitespace())
            .take_while(|c| !c.is_whitespace())
            .collect::<String>();
        token.parse::<T>().ok()
    }

    fn read<T: FromStr>(&mut self) -> T {
        self.read1().unwrap()
    }
}


Measured memory_bytes: 4352