Harryxun/stf_run huggingface dataset:
# ABC073D - joisino's travel
from heapq import heapify, heappop, heappush
from itertools import permutations


def dijkstra(G: "Array[Array[int]]", size: int, start: int) -> list:
    dist = [float("inf")] * size
    searched = [0] * size
    dist[start], searched[start] = 0, 1
    queue = G[start]
    heapify(queue)
    while queue:
        v, cost = heappop(queue)
        if searched[v]:
            continue
        dist[v] = cost
        searched[v] = 1
        for u, next_cost in G[v]:
            heappush(queue, (u, cost + next_cost))
    return dist


def main():
    global G, N
    N, M, R, *RABC = map(int, open(0).read().split())
    visit, ABC = RABC[:R], RABC[R:]
    G = [[] for _ in range(N + 1)]
    for v, u, c in zip(*[iter(ABC)] * 3):
        G[v].append((u, c)), G[u].append((v, c))
    dist = [None] + [dijkstra(G, N + 1, i) for i in range(1, N + 1)]
    ans = float("inf")
    for perm in permutations(visit):
        cur = sum(dist[v][u] for v, u in zip(perm, perm[1:]))
        ans = min(ans, cur)
    print(int(ans))


if __name__ == "__main__":
    main()

### FIXED CODE ###

# ABC073D - joisino's travel
from itertools import permutations
from scipy.sparse.csgraph import floyd_warshall


def main():
    N, M, R, *RABC = map(int, open(0).read().split())
    visit, ABC = RABC[:R], RABC[R:]
    G = [[float("inf")] * (N + 1) for _ in range(N + 1)]
    for v, u, c in zip(*[iter(ABC)] * 3):
        G[v][u] = G[u][v] = c
    dist = floyd_warshall(G, directed=0)
    ans = float("inf")
    for perm in permutations(visit):
        cur = sum(dist[v][u] for v, u in zip(perm, perm[1:]))
        ans = min(ans, cur)
    print(int(ans))


if __name__ == "__main__":
    main()
a,b,c,d=map(int,input().split())
print(max([a*b,c*d])

### FIXED CODE ###

a,b,c=map(str,input().split(","))
print(a,b,c)
def make_tree(node):
    for i in tree_list[node]:
        if i != tree_dic[node]["p"]:
            tree_dic[node]["c"].append(i)
            tree_dic[i]["p"] = node
            make_tree(i)

n, q = map(int, input().split())
tree_list = [[] for _ in range(n)]
for i in range(n-1):
    a, b = map(int, input().split())
    tree_list[a-1].append(b-1)
    tree_list[b-1].append(a-1)

tree_dic = {} #tree_dic = {i:{p:j, c:[k, l]}}
for i in range(n):
    tree_dic[i] = {"p": None, "c": [], "x": 0}

make_tree(0)

for i in range(q):
    p, x = map(int, input().split())
    tree_dic[p-1]["x"] += x
# print(tree_dic)

x_list = [0 for _ in range(n)]

# import queue
# next_visit = queue.Queue()
# next_visit.put(0)
# while not next_visit.empty():
#     i = next_visit.get()
#     tmp = tree_dic[i]["x"]
#     if i != 0:
#         tmp += x_list[tree_dic[i]["p"]]
#     x_list[i] = tmp
#     for j in tree_dic[i]["c"]:
#         next_visit.put(j)

for i in x_list:
    print(i, end=" ")

### FIXED CODE ###

n, q = map(int, input().split())
tree_candidate = [[] for _ in range(n)]

for i in range(n-1):
    a, b = map(int, input().split())
    a -= 1
    b -= 1
    tree_candidate[a].append(b)
    tree_candidate[b].append(a)

tree = [[] for _ in range(n)]

app = set([0])

import queue
next = queue.Queue()
next.put(0)
# print(tree_candidate)
while not next.empty():
    i = next.get()
    for j in tree_candidate[i]:
        if not j in app:
            tree[i].append(j)
            app.add(j)
            next.put(j)

cnts = [0 for _ in range(n)]
for i in range(q):
    p, x = map(int, input().split())
    cnts[p-1] += x
    # print(x, p, tree[p-1], cnts)

next = queue.Queue()
next.put(0)

while not next.empty():
    i = next.get()
    for j in tree[i]:
        cnts[j] += cnts[i]
        next.put(j)

for i in cnts:
    print(i, end=' ')
N, K = map(int, input().split())
A = list(map(int, input().split()))
e = [False] * (N+1)
idx = 1
move = []
while True:
  if e[idx]:
    break
  move.append(idx)
  e[idx] = True
  idx = A[idx-1]
m = move.index(idx)
c = len(move) - m

if K <= m:
    print(D[K])
else:
    print(D[m+(K-m) % c])

### FIXED CODE ###

N, K = map(int, input().split())
A = [int(i) for i in input().split()]

R = [False]*(N+1)
D = []
p = 1
while True:
    if R[p]:
        break
    D.append(p)
    R[p] = True
    p = A[p-1]
m = D.index(p)
c = len(D)-m

if K <= m:
    print(D[K])
else:
    print(D[m+(K-m) % c])
w, h, w, y, r = map(int, input().split())

if (x - r) >= 0 and (x + r) <= w:
    print("Yes")
else:
    print("No")

### FIXED CODE ###

w, h, x, y, r = map(int, input().split())

if x + r <= w and y + r >= 0 and x - r >= 0 and y + r <= h:
    print("Yes")
else:
    print("No")
n,*a=map(int,open(0))
*l,=range(1,n+1)
c=0
for i in range(n):
    if a[i]!=l[i]:
        c+=1
if c<=2:
    print("YES")
else:
    print("NO")
    

### FIXED CODE ###

n,*a=map(int,open(0).read().split())
*l,=range(1,n+1)
c=0
for i in range(n):
    if a[i]!=l[i]:
        c+=1
if c<=2:
    print("YES")
else:
    print("NO")
n,m = map(int,input().split())

global clasta
clasta = [-1 for i in range(n)]
path = [[] for i in range(n)]
for _ in range(m):
    x,y,z = map(int,input().split())
    path[x-1].append(y-1)
    path[y-1].append(x-1)

def dfs(now,color):
    for y in path[now]:
        if clasta[y] == -1:
            clasta[y] = color
            dfs(y,color)
ans = 0
for idx,i in enumerate(clasta):
    if i == -1:
        clasta[idx] = idx
        dfs(idx,idx)
        ans += 1

print(ans)

### FIXED CODE ###

import sys
sys.setrecursionlimit(10**6)

class UnionFind():
    def __init__(self, n):
        self.n = n
        self.parents = [-1] * n

    def find(self, x):
        if self.parents[x] < 0:
            return x
        else:
            self.parents[x] = self.find(self.parents[x])
            return self.parents[x]

    def union(self, x, y):
        x = self.find(x)
        y = self.find(y)

        if x == y:
            return

        if self.parents[x] > self.parents[y]:
            x, y = y, x

        self.parents[x] += self.parents[y]
        self.parents[y] = x

    def size(self, x):
        return -self.parents[self.find(x)]

    def same(self, x, y):
        return self.find(x) == self.find(y)

    def members(self, x):
        root = self.find(x)
        return [i for i in range(self.n) if self.find(i) == root]

    def roots(self):
        return [i for i, x in enumerate(self.parents) if x < 0]

    def group_count(self):
        return len(self.roots())

    def all_group_members(self):
        return {r: self.members(r) for r in self.roots()}

    def __str__(self):
        return '\n'.join('{}: {}'.format(r, self.members(r)) for r in self.roots())
        
        
n,m = map(int,input().split())

uf = UnionFind(n)
for _ in range(m):
    x,y,z = map(int,input().split())
    uf.union(x-1, y-1)
    
print(uf.group_count())
nums = list(map(int, input().split()))
n = 1
if nums[0] != nums[1]:
	n++
if nums[1] != nums[2] and nums[0] != nums[2]:
	n++
print(n)


### FIXED CODE ###

nums = list(map(int, input().split()))
n = 1
if nums[0] != nums[1]:
	n+=1
if nums[1] != nums[2] and nums[0] != nums[2]:
	n+=1
print(n)
a, b = map(int, input().split())
diff = b - a

def generate(n):
    if n == 0:
        return 0
    elif n == 1:
        return 1
    return generate(n-1) + n

print(generate(diff) - b)

### FIXED CODE ###

a, b = map(int, input().split())

tower = 0

for i in range(1, b - a + 1):
    tower += i

print(tower - b)
import math
S = int(input())
 
x1 = math.ceil(math.sqrt(S))
y1 = 1
x2 = x1 * y2 - S
y2 = x1
x3 = 0
y3 = 0
 
print(x1, y1, x2, y2, x3, y3)

### FIXED CODE ###

import math
S = int(input())
 
x1 = math.ceil(math.sqrt(S))
y1 = 1
x2 = x1 ** 2 - S
y2 = x1
x3 = 0
y3 = 0
 
print(x1, y1, x2, y2, x3, y3)
s = input()
if len(s) == 1:
    print(0)
else:
    r = 0
    f = s[0]
    for i in s[1:]:
        if i == f:
            r += 1
        	f = '1' if i == '0' else '0'
        f = i
    print(r)

### FIXED CODE ###

s = list(input())
a = {'1': '0', '0': '1'}
if len(s) == 1:
    print(0)
else:
    r = 0
    for i in range(len(s) - 1):
        if s[i] == s[i+1]:
            r += 1
            s[i+1] = a[s[i]]
    print(r)
n = input().split()
res = list(map(int, num))
if sum(res) >= 22:
    print('bust')
else:
    print('win')

### FIXED CODE ###

n = input().split()
res = list(map(int, n))
if sum(res) >= 22:
    print('bust')
else:
    print('win')
N=int(input())
dstb=[1]+[6**i for i in range(1,7)]+[9**j for j in range(1,6)]
DP=[10**5]*(N*2)
DP[0]=0
for i in range(N+1):
  for j in dstb:
    DP[i+j]=min(DP[i+j], DP[i]+1)

print(DP[N])


### FIXED CODE ###

N=int(input())
dstb=[1]+[6**i for i in range(1,7)]+[9**j for j in range(1,6)]
DP=[10**5]*(10**5*2)
DP[0]=0
for i in range(N+1):
  for j in dstb:
    DP[i+j]=min(DP[i+j], DP[i]+1)

print(DP[N])
import numpy as np
N, T = [int(a) for a in input().split()]
time = np.full(N + 1, -1)
value = np.full(N + 1, -1)
for i in range(1, N + 1):
    time[i], value[i] = [int(a) for a in input().split()]

# Sort the array in the increasing order of value
time = time[np.argsort(value)]
value.sort()

# table for knapsack problem
# maximum possible time is T-1
dp_table = np.full((N + 1, T + 1), -1)

def knapsack(n, t):
    '''
    Input: n ... the number of elements to choose from
                 n means items 1, 2, ..., n can be chosen
           t ... time limit
    Output: total value
    '''
    if n <= 0 or t <= 0:
        return 0
    elif dp_table[n, t] >= 0:
        return dp_table[n, t]
    elif time[n] > t:
        ans =  knapsack(n-1, t)
    else:
        ans = max(knapsack(n-1, t), value[n] + knapsack(n-1, t - time[n]))

    dp_table[n, t] = ans
    return ans

def all_you_can_eat(n, t):
    if n <= 0 or t <= 0:
        return 0
    else:
        # Eat the most delicious food at the beginning
        tmp1 = value[n] + all_you_can_eat(n - 1, t - time[n])
        # Eat the most delicious food at the end
        tmp2 = value[n] + knapsack(n - 1, t - 1)
        return max(tmp1, tmp2)

print(int(all_you_can_eat(N, T)))


### FIXED CODE ###

#!/usr/bin/env python3
from collections import defaultdict,deque
from heapq import heappush, heappop
from bisect import bisect_left, bisect_right
import sys, random, itertools, math
sys.setrecursionlimit(10**5)
input = sys.stdin.readline
sqrt = math.sqrt
def LI(): return list(map(int, input().split()))
def LF(): return list(map(float, input().split()))
def LI_(): return list(map(lambda x: int(x)-1, input().split()))
def II(): return int(input())
def IF(): return float(input())
def LS(): return list(map(list, input().split()))
def S(): return list(input().rstrip())
def IR(n): return [II() for _ in range(n)]
def LIR(n): return [LI() for _ in range(n)]
def FR(n): return [IF() for _ in range(n)]
def LFR(n): return [LI() for _ in range(n)]
def LIR_(n): return [LI_() for _ in range(n)]
def SR(n): return [S() for _ in range(n)]
def LSR(n): return [LS() for _ in range(n)]
mod = 1000000007
inf = float('INF')

#solve
def solve():
    n, t = LI()
    ab = LIR(n)
    ab.sort(key=lambda x: x[0])
    dp = [0] * (t+1)
    for i in range(n):
        a, b = ab[i]
        for ti in range(t - 1, -1, -1):
            dp[min(ti + a, t)] = max(dp[min(ti + a, t)], dp[ti] + b)
    print(dp[t])
    return


#main
if __name__ == '__main__':
    solve()
n, m, q = map(int, input().split())
start_sets = [set() for _ in range(n+2)]
end_sets = [set() for _ in range(n+2)]
for i in range(m):
    l, r = map(int, input().split())
    start_sets[l].add(i)
    end_sets[r].add(i)

for i in range(1, n+2):
    start_sets[i] |= start_sets[i-1]
    end_sets[i] |= end_sets[i-1]

ans = []
for _ in range(q):
    p, q = map(int, input().split())
    start = start_sets[q]-start_sets[p-1]
    end = end_sets[q] - end_sets[p-1]
    res = start & end
    ans.append(len(res))
print(*ans, sep="\n")

### FIXED CODE ###

N,M,Q = map(int,input().split())
l = [[0 for i in range(N)] for j in range(N)]
 
for _ in range(M):
    L,R = map(int,input().split())
    l[L-1][R-1] += 1
 
csum = [[0 for i in range(N+1)] for j in range(N+1)]
 
for i in range(1,N+1):
    for j in range(1,N+1):
        csum[i][j] = csum[i][j-1] + csum[i-1][j] - csum[i-1][j-1] + l[i-1][j-1]
 
for _ in range(Q):
    p,q = map(int,input().split())
    print(csum[q][q]-csum[q][p-1]-csum[p-1][q]+csum[p-1][p-1])
N,X=map(int, input().split())
L=list(map(int, input().split()))
count = 0
x=0
while x <= X and count <= N:
  x = x + L[count]
  count = count + 1
print(count)

### FIXED CODE ###

N,X=map(int, input().split())
L=list(map(int, input().split()))
L.append(0)


d = 0
count = 0

#跳ねる直前からスタート

for i in range(1, N+2):
  if d <= X:
    count = count + 1
    d = d + L[i-1]

print(count)
s = int(input().split())
print(int(s[0])*int(s[1]),' ',int(s[0]*2)+int(s[1]*2))

### FIXED CODE ###

s = input().split()
print(int(s[0])*int(s[1]),int(s[0])*2+int(s[1])*2)
if a>b:
    print ("a>b")
if a==b:
    print ("a==b")
if a<b:
    print ("a<b")


### FIXED CODE ###

a,b = map(int,input().split())
if a>b:
    print ("a > b")
elif a==b:
    print ("a == b")
else :
    print ("a < b")
import sys

try:
    d = int(input('D: '))
    t = int(input('T: '))
    s = int(input('S: '))
except ValueError:
    print('エラー：整数以外を入力しないでください')
    sys.exit(1)

if 1 <= d <= 10000 and 1 <= t <= 10000 and 1 <= s <= 10000:
    take_time = d / s
    if take_time <= t:
        print("Yes")
    else:
        print("No")
else:
    print('エラー：各入力は1～10000までの整数です')

### FIXED CODE ###

import sys

try:
    #d = int(input('D: '))
    #t = int(input('T: '))
    #s = int(input('S: '))
    nums = [int(e) for e in input().split()]
except ValueError:
    print('エラー：整数以外を入力しないでください')
    sys.exit(1)

if 1 <= nums[0] <= 10000 and 1 <= nums[1] <= 10000 and 1 <= nums[2] <= 10000:
    take_time = nums[0] / nums[2]
    if take_time <= nums[1]:
        print("Yes")
    else:
        print("No")
else:
    print('エラー：各入力は1～10000までの整数です')
α = int(input())

if α == α.upper():
  print('A')
elif α == α.lower():
  print('a')


### FIXED CODE ###

α = input()
 
if α == α.upper():
  print('A')
elif α == α.lower():
  print('a')
N, K = map(int, input().split(' '))
A = list(map(int, input().split(' ')))

A_itta = [None] * N
# A_cycle = '1'

A_stayed = []
# A_stayed.append(1)

is_looped = None
jump_cnt = 0

i = 0
while True:
    # for i in range(K):
    # while True:

    # 行ったことある町についた
    if A_itta[i]:
        is_looped = 1
        break

    # 訪問済みフラグ
    A_itta[i] = 1

    # 訪問順リスト
    A_stayed.append(i + 1)

    # 次の町のidx
    i = A[i] - 1
    jump_cnt += 1

    # ジャンプ回数が上限を超えた
    if jump_cnt > K:
        is_looped = 0
        break

# print('ループするまでにいった町', A_stayed)

# 最初の町からループする場合
if is_looped and i == 0:
    cycle = A_stayed
    ans = cycle[K % len(cycle)]
elif is_looped and i > 0:
    cycle = A_stayed[i + 1:]
    K -= i + 1
    ans = cycle[K % len(cycle)]
else:
    cycle = 'no cycle'
    ans = A_stayed[-1]

# print('i', i)
# print('loop=', cycle)
print(ans)


### FIXED CODE ###

N, K = map(int, input().split(' '))
A = list(map(int, input().split(' ')))

visited = [False for _ in range(N)]
now = 0

cycle = []

while True:
    cycle.append(now)
    visited[now] = True
    now = A[now] - 1

    if visited[now]:
        break

total_len = len(cycle)

cycle_start = 0

for i in range(total_len):
    if cycle[i] == now:
        cycle_start = i
        break

cycle_len = total_len - cycle_start

if K < cycle_start:
    print(cycle[K] + 1)
else:
    print(cycle[cycle_start + (K - cycle_start) % cycle_len] + 1)
#A
if False:
    N=int(input())
    E=[int(i) for i in input().split()]
    E.sort()
    s=sum(E)
    if E[-1]<s-E[-1]:
        print('Yes')
    else:
        print('No')
#B
#C
if False:
    N=int(input())
    S=[input() for _ in range(N)]
    march=list('MARCH')
    nam=[[] for _ in range(len(march))]
    for s in S:
        if s[0] in march:
            nam[march.index(s[0])].append(s)
    ans=0
    for i in range(5):
        for j in range(i+1,5):
            for k in range(j+1,5):
                ans+=len(nam[i])*len(nam[j])*len(nam[k])
    print(ans)

#D
N=int(input())
ver=[[] for _ in range(N)]
for _ in range(N-1):
    u,v,W=map(int,input().split())
    ver[u-1].append((v-1,W))
    ver[v-1].append((u-1,W))
his=[-1 for _ in range(N)]

def dfs(i,col):
    his[i]=col
    for j,w in ver[i]:
        if his[j]==-1:
            if w%2==0:
                dfs(j,col)
            else:
                dfs(j,(col+1)%2)

dfs(0,0)            
for i in range(N):
    print(his[i])


### FIXED CODE ###

import sys

if sys.getrecursionlimit()<10**7:
    sys.setrecursionlimit(10**7)

N=int(input())
ver=[[] for _ in range(N)]
for _ in range(N-1):
    u,v,W=map(int,input().split())
    ver[u-1].append((v-1,W))
    ver[v-1].append((u-1,W))
his=[-1 for _ in range(N)]

def dfs(i,col):
    his[i]=col
    for j,w in ver[i]:
        if his[j]==-1:
            if w%2==0:
                dfs(j,col)
            else:
                dfs(j,(col+1)%2)

dfs(0,0)            
for i in range(N):
    print(his[i])
N,M = map(int,input().split())
P = list(map(int,input().split()))
XY = []
for i in range(M):
  XY.append(list(map(int,input().split())))
#print(XY)

E = [set() for _ in range(N+1)]
for x,y in XY:
  E[x].add(y)
  E[y].add(x)
#print(E)

def dfs(v,mark):
  visited[v] = mark
  for u in E[v]:
    if visited[u] == 0:
      dfs(u,mark)

visited = [0 for _ in range(N+1)]
mark = 1
for i in range(1,N+1):
  if visited[i] == 0:
    dfs(i,mark)
    mark += 1
#print(visited)

G = [set() for _ in range(max(visited))]
for i in range(1,N+1):
  G[visited[i]-1].add(i)
#print(G)

ans = 0
for g in G:
  Pset = set()
  for idx in g:
    Pset.add(P[idx-1])
  ans += len(Pset & g)
print(ans)

### FIXED CODE ###

import sys
sys.setrecursionlimit(10 ** 9)

N,M = map(int,input().split())
P = list(map(int,input().split()))
XY = []
for i in range(M):
  XY.append(list(map(int,input().split())))
#print(XY)

E = [set() for _ in range(N+1)]
for x,y in XY:
  E[x].add(y)
  E[y].add(x)
#print(E)

def dfs(v,mark):
  visited[v] = mark
  for u in E[v]:
    if visited[u] == 0:
      dfs(u,mark)

visited = [0 for _ in range(N+1)]
mark = 1
for i in range(1,N+1):
  if visited[i] == 0:
    dfs(i,mark)
    mark += 1
#print(visited)

G = [set() for _ in range(max(visited))]
for i in range(1,N+1):
  G[visited[i]-1].add(i)
#print(G)

ans = 0
for g in G:
  Pset = set()
  for idx in g:
    Pset.add(P[idx-1])
  ans += len(Pset & g)
print(ans)
import math

def pi(n):
    m = int(math.sqrt(n))
    keys = [n / i for i in range(1, m + 1)]
    keys += range(keys[-1] - 1, 0, -1)
    h = {i : i - 1 for i in keys}
    for i in range(2, m + 1):
        if h[i] > h[i - 1]:
            hp = h[i - 1]
            i2 = i * i
            for j in keys:
                if j < i2: break
                h[j] -= h[j / i] - hp

    return h[n]

while 1:
    i = int(raw_input())
    print pi(i)

### FIXED CODE ###

import math
import sys

def pi(n):
    m = int(math.sqrt(n))
    keys = [n / i for i in range(1, m + 1)]
    keys += range(keys[-1] - 1, 0, -1)
    h = {i : i - 1 for i in keys}
    for i in range(2, m + 1):
        if h[i] > h[i - 1]:
            hp = h[i - 1]
            i2 = i * i
            for j in keys:
                if j < i2: break
                h[j] -= h[j / i] - hp

    return h[n]

for line in sys.stdin:
    i = int(line)
    print pi(i)
import fraction
from functools import reduce

n,X = map(int,input().split())
x =list(map(int,input().split()))
x.append(X)
x.sort()
a = []*n
for i in range(n):
  a[i] = x[i+1]-x[i]
  
g = gcd(*a)
print(g)



### FIXED CODE ###

n,X = map(int,input().split())
x =list(map(int,input().split()))
x.append(X)
x.sort()
a = []
for i in range(n):
  a.append(x[i+1]-x[i])
  
h = min(a)
gcd = 1
for i in range(h,0,-1):
  if h%i == 0:
    if all(a[j]%i == 0 for j in range(n)):
      gcd = i
      break
      
print(gcd)
A = int(input())
B = int(input())

if A>8 or B>8:
    print( ':(')    
else:
    print('Yay!')

### FIXED CODE ###

A,B = map(int,input().split())
 
if A <= 8:
    if B <= 8:
        print('Yay!')
    else:
        print( ':(') 
else:
    print( ':(')
# ?????????O(n)????????£???????????????
class union_find(object):
 	"""union-find tree"""
 	def __init__(self, length):
 		self.length = length
 		self.unionnumber=0
 		self.unionlist=[[]]
 		self.num=list(-1 for i in range(length))

 	def unite(self,i,j):
 		if self.num[i]==-1:
 			if self.num[j]==-1:
 				self.unionlist[self.unionnumber].extend([i,j])
 				self.num[i]=self.unionnumber
 				self.num[j]=self.unionnumber
 				self.unionnumber+=1
 				self.unionlist.append([])
 			else:
 				tmp=i 
 				i=j 
 				j=tmp 
 		if self.num[i]!=-1:
 			if self.num[j]!=-1:
 				if self.num[i]==self.num[j]:
 					pass
 				else:
 					self.unionlist[self.num[i]].extend(self.unionlist[self.num[j]])
 					tmp=self.num[j]
 					for k in self.unionlist[self.num[j]]:
 						self.num[k]=self.num[i]
 					self.unionlist[tmp]="del"
 			else:
 				self.num[j]=self.num[i]
 				self.unionlist[self.num[i]].append(j)

 	def same(self,i,j):
 		print(self.num[i]==self.num[j])


n,m=input().split()
n=int(n)
m=int(m)

l=[]
union=union_find(n)
for i in range(m):
	com,a,b=input().split()
	a=int(a)
	b=int(b)
	if com="unite":
		union.unite(a,b)
	else:
		union.same(a,b)

### FIXED CODE ###

# ?????????O(n)????????£?????????
class union_find(object):
 	"""union-find tree"""
 	def __init__(self, length):
 		self.length = length
 		self.unionnumber=0
 		self.unionlist=[[]]
 		self.num=list(-1 for i in range(length))

 	def unite(self,i,j):
 		if self.num[i]==-1:
 			if self.num[j]==-1:
 				self.unionlist[self.unionnumber].extend([i,j])
 				self.num[i]=self.unionnumber
 				self.num[j]=self.unionnumber
 				self.unionnumber+=1
 				self.unionlist.append([])
 			else:
 				tmp=i 
 				i=j 
 				j=tmp 
 		if self.num[i]!=-1:
 			if self.num[j]!=-1:
 				if self.num[i]==self.num[j]:
 					pass
 				else:
 					self.unionlist[self.num[i]].extend(self.unionlist[self.num[j]])
 					tmp=self.num[j]
 					for k in self.unionlist[self.num[j]]:
 						self.num[k]=self.num[i]
 					self.unionlist[tmp]="del"
 			else:
 				self.num[j]=self.num[i]
 				self.unionlist[self.num[i]].append(j)

 	def same(self,i,j):
 		if self.num[i]==-1 or self.num[j]==-1:
 			return(False)
 		else:
 			return(self.num[i]==self.num[j])


n,m=input().split()
n=int(n)
m=int(m)

l=[]
union=union_find(n)
for i in range(m):
	com,a,b=input().split()
	a=int(a)
	b=int(b)
	if com=="0":
		union.unite(a,b)
	else:
		if union.same(a,b):
			print(1)
		else:
			print(0)
N, M = map(int, input().split())
a = [int(input()) for _ in range(M)] # a_0...a_(M-1)

MOD = 10**9 + 7

def f(x): # フィボナッチ数列
    if x == 0:
        return(1)
    elif x == 1:
        return(1)
    elif x == 2:
        return(2)
    else:
        return(f(x-1) % MOD + f(x-2) % MOD)

ans = 0

for i in range(M+1): # iは0からM
    if i == 0:
        ans += f((a[0]-1) - 0) % MOD # 0段目からa_0-1段目に上る(その後a_0段目を飛ばしてa_0+1段目に上る)
    elif i == M:
        ans *= f(N - (a[M-1] + 1)) % MOD # a_M-1段目からN段目に上る
    else: # iは1からM-1
        stair = (a[i] - 1) - (a[i-1] + 1) # 登る段数
        if stair >= 0:
            ans *= f(stair) % MOD # a_(i-1)+1段目からa_i-1段目に上る(その後a_i段目を飛ばしてa_i+1段目に上る)
        else:
            ans = 0
            break

print(ans % MOD)

### FIXED CODE ###

N, M = map(int, input().split())
a = [int(input()) for _ in range(M)] # a_0...a_(M-1)

def f(x):
    a, b = 1, 1
    if x == 0:
        return a
    elif x == 1:
        return b
    else:
        for i in range(x-1):
            a, b = b, a + b
        return b
"""
# 再帰だとTLEとかREとかになるよ
def f(x): # フィボナッチ数列
    if x == 0:
        return(1)
    elif x == 1:
        return(1)
    else:
        return(f(x-1) + f(x-2))
"""

ans = 0
MOD = 10**9 + 7

if M == 0:
    ans += f(N) % MOD
    print(ans)
else:
    ans += f((a[0]-1) - 0) % MOD # 0段目からa_0-1段目に上る(その後a_0段目を飛ばしてa_0+1段目に上る)
    for i in range(1, M): # iは1からM-1
        stair = (a[i] - 1) - (a[i-1] + 1) # 登る段数
        if stair >= 0:
            ans *= f(stair) % MOD # a_(i-1)+1段目からa_i-1段目に上る(その後a_i段目を飛ばしてa_i+1段目に上る)
        else:
            ans = 0
            break
    ans *= f(N - (a[M-1] + 1)) % MOD # a_M-1段目からN段目に上る
    print(ans % MOD)