#include <algorithm>
#include <array>
#include <cassert>
#include <iostream>
#include <vector>
using namespace std;

template<typename T> ostream& operator<<(ostream &os, const vector<T> &v) { os << '{'; string sep; for (const auto &x : v) os << sep << x, sep = ", "; return os << '}'; }
template<typename T, size_t size> ostream& operator<<(ostream &os, const array<T, size> &arr) { os << '{'; string sep; for (const auto &x : arr) os << sep << x, sep = ", "; return os << '}'; }
template<typename A, typename B> ostream& operator<<(ostream &os, const pair<A, B> &p) { return os << '(' << p.first << ", " << p.second << ')'; }

void dbg_out() { cerr << endl; }
template<typename Head, typename... Tail> void dbg_out(Head H, Tail... T) { cerr << ' ' << H; dbg_out(T...); }

#ifdef NEAL_DEBUG
#define dbg(...) cerr << "(" << #__VA_ARGS__ << "):", dbg_out(__VA_ARGS__)
#else
#define dbg(...)
#endif

template<const int &MOD>
struct _m_int {
    int val;

    _m_int(int64_t v = 0) {
        if (v < 0) v = v % MOD + MOD;
        if (v >= MOD) v %= MOD;
        val = int(v);
    }

    _m_int(uint64_t v) {
        if (v >= MOD) v %= MOD;
        val = int(v);
    }

    _m_int(int v) : _m_int(int64_t(v)) {}
    _m_int(unsigned v) : _m_int(uint64_t(v)) {}

    explicit operator int() const { return val; }
    explicit operator unsigned() const { return val; }
    explicit operator int64_t() const { return val; }
    explicit operator uint64_t() const { return val; }
    explicit operator double() const { return val; }
    explicit operator long double() const { return val; }

    _m_int& operator+=(const _m_int &other) {
        val -= MOD - other.val;
        if (val < 0) val += MOD;
        return *this;
    }

    _m_int& operator-=(const _m_int &other) {
        val -= other.val;
        if (val < 0) val += MOD;
        return *this;
    }

    static unsigned fast_mod(uint64_t x, unsigned m = MOD) {
#if !defined(_WIN32) || defined(_WIN64)
        return unsigned(x % m);
#endif
        // Optimized mod for Codeforces 32-bit machines.
        // x must be less than 2^32 * m for this to work, so that x / m fits in an unsigned 32-bit int.
        unsigned x_high = unsigned(x >> 32), x_low = unsigned(x);
        unsigned quot, rem;
        asm("divl %4\n"
            : "=a" (quot), "=d" (rem)
            : "d" (x_high), "a" (x_low), "r" (m));
        return rem;
    }

    _m_int& operator*=(const _m_int &other) {
        val = fast_mod(uint64_t(val) * other.val);
        return *this;
    }

    _m_int& operator/=(const _m_int &other) {
        return *this *= other.inv();
    }

    friend _m_int operator+(const _m_int &a, const _m_int &b) { return _m_int(a) += b; }
    friend _m_int operator-(const _m_int &a, const _m_int &b) { return _m_int(a) -= b; }
    friend _m_int operator*(const _m_int &a, const _m_int &b) { return _m_int(a) *= b; }
    friend _m_int operator/(const _m_int &a, const _m_int &b) { return _m_int(a) /= b; }

    _m_int& operator++() {
        val = val == MOD - 1 ? 0 : val + 1;
        return *this;
    }

    _m_int& operator--() {
        val = val == 0 ? MOD - 1 : val - 1;
        return *this;
    }

    _m_int operator++(int) { _m_int before = *this; ++*this; return before; }
    _m_int operator--(int) { _m_int before = *this; --*this; return before; }

    _m_int operator-() const {
        return val == 0 ? 0 : MOD - val;
    }

    friend bool operator==(const _m_int &a, const _m_int &b) { return a.val == b.val; }
    friend bool operator!=(const _m_int &a, const _m_int &b) { return a.val != b.val; }
    friend bool operator<(const _m_int &a, const _m_int &b) { return a.val < b.val; }
    friend bool operator>(const _m_int &a, const _m_int &b) { return a.val > b.val; }
    friend bool operator<=(const _m_int &a, const _m_int &b) { return a.val <= b.val; }
    friend bool operator>=(const _m_int &a, const _m_int &b) { return a.val >= b.val; }

    static const int SAVE_INV = 1e6 + 5;
    static _m_int save_inv[SAVE_INV];

    static void prepare_save() {
        // Make sure MOD is prime, which is necessary for the inverse algorithm below.
        for (int p = 2; p * p <= MOD; p += p % 2 + 1)
            assert(MOD % p != 0);

        save_inv[0] = 0;
        save_inv[1] = 1;

        for (int i = 2; i < SAVE_INV; i++)
            save_inv[i] = save_inv[MOD % i] * (MOD - MOD / i);
    }

    _m_int inv() const {
        if (save_inv[1] == 0)
            prepare_save();

        if (val < SAVE_INV)
            return save_inv[val];

        _m_int product = 1;
        int v = val;

        while (v >= SAVE_INV) {
            product *= MOD - MOD / v;
            v = MOD % v;
        }

        return product * save_inv[v];
    }

    _m_int pow(int64_t p) const {
        if (p < 0)
            return inv().pow(-p);

        _m_int a = *this, result = 1;

        while (p > 0) {
            if (p & 1)
                result *= a;

            p >>= 1;

            if (p > 0)
                a *= a;
        }

        return result;
    }

    friend ostream& operator<<(ostream &os, const _m_int &m) {
        return os << m.val;
    }
};

template<const int &MOD> _m_int<MOD> _m_int<MOD>::save_inv[_m_int<MOD>::SAVE_INV];

extern const int MOD = 1e9 + 7;
using mod_int = _m_int<MOD>;


int H, N;
vector<int> P;
vector<mod_int> root_product;

int lca(int x, int y) {
    assert(N <= x && x < 2 * N);
    assert(N <= y && y < 2 * N);
    int value = x ^ y;
    int highest = value == 0 ? 0 : 32 - __builtin_clz(value);
    return x >> highest;
}

mod_int remove_lca_single(int node, bool include) {
    return root_product[include ? node : node / 2].inv();
}

mod_int remove_lca_double(int node) {
    return remove_lca_single(node, true) * remove_lca_single(node, false);
}

mod_int solve(int start, int mid, int end) {
    if (start >= mid || mid >= end)
        return 0;

    mod_int total = 0;
    total += solve(start, (start + mid) / 2, mid);
    total += solve(mid, (mid + end) / 2, end);

    int anc = lca(N + start, N + end - 1);
    dbg(start, mid, end, anc);
    vector<pair<int, mod_int>> left, right;

    for (int i = start; i < mid; i++)
        left.emplace_back(N + P[i], root_product[N + i] * remove_lca_single(anc, true) * root_product[N + P[i]]);

    for (int i = mid; i < end; i++)
        right.emplace_back(N + P[i], root_product[N + i] * remove_lca_single(anc, false) * root_product[N + P[i]]);

    sort(left.begin(), left.end());
    sort(right.begin(), right.end());
    int n = int(left.size());
    vector<mod_int> left_sum(n + 1, 0);

    for (int i = 0; i < n; i++)
        left_sum[i + 1] = left_sum[i] + left[i].second;

    for (auto &rt : right) {
        int current = 0;

        while (current < n) {
            int current_anc = lca(rt.first, left[current].first);
            int low = current + 1, high = n;

            while (low < high) {
                int b_mid = (low + high) / 2;

                if (lca(rt.first, left[b_mid].first) == current_anc)
                    low = b_mid + 1;
                else
                    high = b_mid;
            }

            total += rt.second * (left_sum[low] - left_sum[current]) * remove_lca_double(current_anc);
            current = low;
        }
    }

    dbg(start, mid, end, total);
    return total;
}

int main() {
    ios::sync_with_stdio(false);
#ifndef NEAL_DEBUG
    cin.tie(nullptr);
#endif

    cin >> H;
    N = 1 << (H - 1);
    P.resize(N);

    for (auto &p : P) {
        cin >> p;
        p--;
    }

    root_product.assign(2 * N, 1);

    for (int i = 1; i < 2 * N; i++)
        root_product[i] = i * root_product[i / 2];

    cout << solve(0, N / 2, N) << '\n';
}


Measured memory_bytes: 10000