Problem:


今年も，全国プログラミング選手権大会の時期がやってきた．全国大会の参加権を賭けた地区大会は， 2n チームが1 対1 の勝ち残り式トーナメント方式で対決する．

トーナメント表にはチーム番号 0, . . . 2n &minus; 1 が割り振られており，1 回戦から n 回戦までの対決手順は次の通りである．

 1 回戦では，（チーム番号が l のチーム）と（チーム番号が l + 1 のチーム）が対決する．(l &equiv; 0 (mod 2))

 i + 1 回戦(1 ≤ i < n) では，「チーム番号が l 以上 l + 2i 未満のチームのうち， i 回戦までの対決で 1 回も負けていないチーム」と「チーム番号が l + 2i 以上 l + 2i+1 未満のチームのうち， i 回戦までの対決で一回も負けていないチーム」が対決する．(l &equiv; 0 (mod 2i+1))

n 回戦まで終わると，各チームの順位は 2n &minus; (そのチームが勝った回数) 位で確定する．なお，この対決には引き分けが存在しないため，対決したチームのいずれか一方が勝ち，もう一方が負ける．

晴れて地区大会の代表に選ばれた私達は，他の地区大会の結果をマネージャーに調べてもらうことにした．ここで調べてもらった結果が「マネージャーから受け取った順位表」であった．「マネージャーから受け取った順位表」をより詳細に説明すると，長さ 2n の数列で i ( 0 ≤ i ≤ 2n &minus; 1 ) 番目の要素にチーム番号 i のチームの順位が書かれているものである．

だが，「マネージャーから受け取った順位表」には同じ順位が大量に並んでいた！トーナメントのルール上，同じ順位が大量に並ぶなんてありえないはずだ．そこで，「マネージャーから受け取った順位表」を「無矛盾な順位表」にするために順位を変更するチーム数の最小値を計算してどのくらい順位表が間違っているかをマネージャーに教えてあげよう．「無矛盾な順位表」とは，順位が確定したトーナメントの結果として起こりうる順位表のことを表す．

Input

入力には，「マネージャーから受け取った順位表」が以下の形式で与えられる．

n m
a0 a1 . . .  am
b0 b1 . . .  bm&minus;1

 1 行目は n, m の2 個の整数からなり， 2n は「地区大会の参加チーム数」，m は「『マネージャーから受け取った順位表』で連続した順位が並んでいる区間の個数」を表す．

 2 行目は ai(0 ≤ i ≤ m) の m + 1 個の整数からなり，各 ai は「『マネージャーから受け取った順位表』で連続した順位が並んでいる区間の区切り位置」を表す．

 3 行目は bi(0 ≤ i < m) の m 個の整数からなり，各2bi は「『マネージャーから受け取った順位表』におけるチーム番号が ai 以上 ai+1 未満のチームの順位」を表す．

Constraints

 1 ≤ n ≤ 30

 1 ≤ m ≤ 10,000

 0 = a0 < a1 ≤ . . . ≤ am&minus;1 < am = 2n

 0 ≤ bi ≤ n

Output

「マネージャーから受け取った順位表」を「無矛盾な順位表」にするために順位を変更するチーム数の最小値を1 行に出力せよ．

Sample Input 1

1 1
0 2
1

Output for the Sample Input 1

1

参加チーム数が2 の「無矛盾な順位表」は，{"チーム番号 0 のチームの順位", "チーム番号 1 のチームの順位"} として {1, 2} と {2, 1} の2 通りがある．順位表 {2, 2} を「無矛盾な順位表」に修正するためには，いずれかのチームの順位を 1 に変更しなければならない．

Sample Input 2

2 3
0 1 2 4
0 1 2

Output for the Sample Input 2

2

Sample Input 3

2 3
0 1 3 4
0 2 1

Output for the Sample Input 3

0

Sample Input 4

4 5
0 1 2 4 8 16
0 1 2 3 4

Output for the Sample Input 4

10



Sample input:
1 1
0 2
1


Sample output:
1

Submission status: Accepted

Solution code:
import sys
readline = sys.stdin.readline
write = sys.stdout.write
def solve():
    N, M = map(int, readline().split())
    *A, = map(int, readline().split())
    *B, = map(int, readline().split())
    C = []
    prv = 0
    for i in range(M):
        C.append((A[i+1] - prv, 1 << B[i]))
        prv = A[i+1]
    ans = 0
    for i in range(N-1, -1, -1):
        v = 1 << (i+1)
        C1 = []
        r = 0; p = 0
        for c, b in C:
            if r:
                if (b & v) == (p & v) > 0:
                    b0 = b | p
                elif b & v:
                    b0 = p
                elif p & v:
                    b0 = b
                else:
                    b0 = b | p
                    ans += 1
                if C1 and C1[-1][1] == b0:
                    c1, b1 = C1.pop()
                    C1.append((1+c1, b0))
                else:
                    C1.append((1, b0))
                c -= 1
            if c > 1:
                if b & v == 0:
                    ans += c // 2
                if C1 and C1[-1][1] == b:
                    c1, b1 = C1.pop()
                    C1.append((c//2+c1, b))
                else:
                    C1.append((c//2, b))
            if c % 2:
                r = 1; p = b
            else:
                r = 0
        C = C1
    c, p = C[0]
    if p & 1 == 0:
        ans += 1
    write("%d\n" % ans)
solve()