#include <stdio.h>
#include <utility>
#include <algorithm>
using namespace std;
#define F first
#define S second

typedef long long int ll;
constexpr int kMod = int(1E9 + 7), kN = int(3E5 + 10);

ll Pow(ll a, ll b) {
	ll ans = 1;
	while (b) {
		if (b & 1) ans = ans * a % kMod;
		a = a * a % kMod;
		b >>= 1;
	}
	return ans;
}
ll Rev(ll n) {return Pow(n, kMod - 2);}

int LCA(int l, int r) {
	while (l != r) {
		l >>= 1;
		r >>= 1;
	}
	return l;
}

struct seg_tree {
	ll val[kN << 2], flag[kN << 2];
	void init(int n, int l, int r) {
		val[n] = 0;
		flag[n] = 1;
		if (l < r) {
			int mid = (l + r) >> 1;
			init(n << 1, l, mid);
			init(n << 1 | 1, mid + 1, r);
		}
		return ;
	}
	void addtag(int n, ll x) {
		flag[n] = flag[n] * x % kMod;
		val[n] = val[n] * x % kMod;
		return ;
	}
	void push(int n) {
		if (flag[n] != 1) {
			addtag(n << 1, flag[n]);
			addtag(n << 1 | 1, flag[n]);
			flag[n] = 1;
		}
		return ;
	}
	void pull(int n) {
		val[n] = (val[n << 1] + val[n << 1 | 1]) % kMod;
		return ;
	}
	void set(int n, int l, int r, int pos, ll x) {
		if (l == r) val[n] = x;
		else {
			int mid = (l + r) >> 1;
			push(n);
			if (pos <= mid) set(n << 1, l, mid, pos, x);
			else set(n << 1 | 1, mid + 1, r, pos, x);
			pull(n);
		}
		return ;
	}
	void mul(int n, int l, int r, int L, int R, ll x) {
		if (L <= l && r <= R) addtag(n, x);
		else if (!(l > R || L > r)) {
			int mid = (l + r) >> 1;
			push(n);
			mul(n << 1, l, mid, L, R, x);
			mul(n << 1 | 1, mid + 1, r, L, R, x);
			pull(n);
		}
		return ;
	}
};

seg_tree sg;
int p[kN];
ll v[kN], x[kN], f[kN];

int main() {
	int h, l, tot, tmp, nxt;
	ll ans = 0; 
	scanf("%d", &h);
	l = (1 << (h - 1));
	for (int i = 1; i <= l; i++) scanf("%d", &p[i]);
	tot = (1 << h) - 1;
	v[0] = 1;
	v[1] = 1;
	for (int i = 1; i < l; i++) {
		v[i << 1] = (i << 1) * v[i] % kMod;
		v[i << 1 | 1] = (i << 1 | 1) * v[i] % kMod;
	}
	for (int i = l - 1; i >= 1; i--) v[i] = Rev(v[i >> 1] * v[i] % kMod);
	for (int i = 1; i <= l; i++) x[i] = v[l + i - 1] * v[l + p[i] - 1] % kMod;

	for (int j = 2; j <= l; j++) 
		f[j] = x[j] * v[LCA(l + 1 - 1, l + j - 1)] % kMod * v[LCA(l + p[1] - 1, l + p[j] - 1)] % kMod;
	sg.init(1, 1, l);
	for (int i = 2; i <= l; i++) sg.set(1, 1, l, p[i], f[i]);
	
	ans += x[1] * sg.val[1] % kMod;

	for (int i = 2; i <= l; i++) {
		sg.set(1, 1, l, p[i], 0);
		tmp = p[i - 1] - 1;
		for (int j = 0; j < h - 1; j++) { 
			nxt = tmp & -(1 << (j + 1));
			if (nxt != tmp) sg.mul(1, 1, l, nxt + 1, nxt + (1 << j), Rev(v[(l + tmp) >> (j + 1)]));
			else sg.mul(1, 1, l, tmp + (1 << j) + 1, tmp + (1 << (j + 1)), Rev(v[(l + tmp) >> (j + 1)]));
			tmp = nxt;
		}
		tmp = p[i] - 1;
		for (int j = 0; j < h - 1; j++) {
			nxt = tmp & -(1 << (j + 1));
			if (nxt != tmp) sg.mul(1, 1, l, nxt + 1, nxt + (1 << j), v[(l + tmp) >> (j + 1)]);
			else sg.mul(1, 1, l, tmp + (1 << j) + 1, tmp + (1 << (j + 1)), v[(l + tmp) >> (j + 1)]);
			tmp = nxt;
		}
		tmp = (i - 1) & -(i - 1);
		for (int j = 1; j < tmp; j++) {
			sg.mul(1, 1, l, p[i + j], p[i + j],
				Rev(v[LCA(l + i - 2, l + i - 1 + j)]) * v[LCA(l + i - 1, l + i - 1 + j)] % kMod); 
		}
		ans += x[i] * sg.val[1] % kMod;
	}
	ans %= kMod;
	//ans = ans * Rev(2) % kMod;
	printf("%lld\n", ans);
}


Measured memory_bytes: 10484