Harryxun/sft_time huggingface dataset:
### BUGGY CODE ###

number_of_prefecture, number_of_cities = [int(x) for x in input().split(' ')]

city_list = []

import collections
city_dict = collections.defaultdict(list)

for i in range (number_of_cities):
    prefecture_id, year_of_establishment = [int(x) for x in input().split(' ')]
    city_dict[prefecture_id].append(year_of_establishment)
    city_list.append([prefecture_id, year_of_establishment])

for prefecture in city_dict:
    city_dict[prefecture].sort()

# print(city_dict)
# print(city_list)

for j in city_list:
    prefecture = j[0]
    year = j[1]
    city_number = city_dict[prefecture].index(year) + 1
    front_string = '0'*(6 - len(str(prefecture))) + str(prefecture)
    back_string = '0'*(6 - len(str(city_number))) + str(city_number)
    print(front_string+back_string)


### FIXED CODE ###

number_of_prefecture, number_of_cities = [int(x) for x in input().split(' ')]

city_list = []

import bisect
import collections
city_dict = collections.defaultdict(list)

for i in range (number_of_cities):
    prefecture_id, year_of_establishment = [int(x) for x in input().split(' ')]
    city_dict[prefecture_id].append(year_of_establishment)
    city_list.append([prefecture_id, year_of_establishment])

for prefecture in city_dict:
    city_dict[prefecture].sort()

for j in city_list:
    prefecture = j[0]
    year = j[1]
    city_number = bisect.bisect(city_dict[prefecture],year)
    front_string = '0'*(6 - len(str(prefecture))) + str(prefecture)
    back_string = '0'*(6 - len(str(city_number))) + str(city_number)
    print(front_string+back_string)
### BUGGY CODE ###

import sys
read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines
import numpy as np 
def main():
    H, W = map(int , readline().split())
    A = np.array([1 if i == ord('.') else 0 for i in read()], np.int16).reshape(H, W+1)
    A = np.vstack((A, np.zeros(W+1, np.int16)))

    for j in range(H):
        prev = 0
        start = 0
        for i in range(W+1):
            if A[j, i] > 0:
                if prev == 0:
                    start = i 
                    prev = 1
            else:
                if prev == 1:
                    n = i - start
                    for k in range(start, i):
                        A[j, k] = n
                    prev = 0 
    

    for i in range(W):
        prev = 0
        start = 0
        for j in range(H+1):
            if A[j, i] > 0:
                if prev == 0:
                    start = j
                    prev = 1
            else:
                if prev == 1:
                    n = j - start - 1
                    for k in range(start, j):
                        A[k, i] += n
                    prev = 0

    print(A.max())
if __name__ == '__main__':
    main()


### FIXED CODE ###

import sys
read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines
import numpy as np 
import itertools as it
def main():
    H, W = map(int, readline().split())
    G = np.zeros((H+2, W+2), np.int16)
    G[1:-1, 1:] = (np.frombuffer(read(H*(W+1)), dtype='B') == ord('.')).reshape((H, W+1))
    def solve(G):
        left = np.zeros(G.shape, np.int16)
        for i in range(G.shape[0]):
            left[i, ] = np.arange(G.shape[1])
        left[G>0] = 0
        np.maximum.accumulate(left, out=left, axis=1)

        rG = G[..., ::-1]
        right = np.zeros(G.shape, np.int16)
        for i in range(G.shape[0]): 
            right[i, ] = np.arange(G.shape[1])
        right[rG>0] = 0
        np.maximum.accumulate(right, out=right, axis=1)

        right = G.shape[1] - right[..., ::-1]-1
        scoreres = (right-left-1) 
        scoreres[G==0] = 0
        return scoreres

    print((solve(G)+solve(G.T).T-1).max())
if __name__ == '__main__':
    main()
### BUGGY CODE ###

from math import factorial as f
N, M = map(int, input().split())
a1, a2 = 2, M
a = {}
while (a1 - 1) ** 2 <= a2 or a1 == a2:
    if a2 % a1 == 0:
        a2 //= a1
        if a1 in a:
            a[a1] += 1
        else:
            a[a1] = 1
    else:
        a1 += 1
p = 1
if a2 != 1:
    a[a2] = 1
for v in a.values():
    p *= f(v + N - 1) // (f(v) * f(N - 1))
print(p % (10 ** 9 + 7))

### FIXED CODE ###

N, M = map(int, input().split())
a1, a2 = 2, M
a = {}
while (a1 - 1) ** 2 <= a2 or a1 == a2:
    if a2 % a1 == 0:
        a2 //= a1
        if a1 in a:
            a[a1] += 1
        else:
            a[a1] = 1
    else:
        a1 += 1
p = 1
if a2 != 1:
    a[a2] = 1
for v in a.values():
    tmp = 1
    for i in range(v):
        tmp = tmp * (v + N - 1 - i) // (i + 1)
    p *= tmp
print(p % (10 ** 9 + 7))
### BUGGY CODE ###

N = int(input())
*A, = list(map(int, input().split()))
count = 0


def merge(a, left, mid, right):
    global count
    n1 = mid - left
    n2 = right - mid
    la, ra = [], []
    for i in range(0, n1):
        la += [a[left + i]]
    for i in range(0, n2):
        ra += [a[mid + i]]
    la += [float("inf")]
    ra += [float("inf")]

    i, j = 0, 0
    for k in range(left, right):
        count += 1
        if la[i] <= ra[j]:
            a[k] = la[i]
            i = i + 1
        else:
            a[k] = ra[j]
            j = j + 1


def merge_sort(a, left, right):
    # それぞれの要素数が二個の配列へ分割できるまで処理を行う
    if left + 1 < right:
        mid = int((left + right) / 2)
        merge_sort(a, left, mid)
        merge_sort(a, mid, right)
        merge(a, left, mid, right)


merge_sort(A, 0, N)
print(*A)
print(count)



### FIXED CODE ###

N = int(input())
*A, = list(map(int, input().split()))
count = 0


def merge(a, left, mid, right):
    global count
    la = a[left:mid] + [float("inf")]
    ra = a[mid:right] + [float("inf")]

    i, j = 0, 0
    for k in range(left, right):
        count += 1
        if la[i] <= ra[j]:
            a[k] = la[i]
            i += 1
        else:
            a[k] = ra[j]
            j += 1


def merge_sort(a, left, right):
    if left + 1 < right:
        mid = int((left + right) / 2)
        merge_sort(a, left, mid)
        merge_sort(a, mid, right)
        merge(a, left, mid, right)

merge_sort(A, 0, N)
print(*A)
print(count)
### BUGGY CODE ###

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

mod = 10**9 + 7

def comb_mod(n, r, mod):
    if n < r:
        return 0
    elif n < 0 or r < 0:
        return 0
    else:
        fac = [1, 1]
        finv = [1, 1]
        inv = [0, 1]
        for i in range(2, n + 1):
            fac.append(fac[-1] * i % mod)
            inv.append(-inv[mod % i] * (mod // i) % mod)
            finv.append((finv[-1] * inv[-1]) % mod)
        return int(fac[n] * finv[r] * finv[n - r] % mod)

m = pow(2,n,mod) - 1

import math
def perm(n,r):
    return (math.factorial(n)//math.factorial(n-r))

s = perm(n,a) * pow(math.factorial(a),mod-2,mod)
# print(s)

t = perm(n,b) * pow(math.factorial(b),mod-2,mod)
# print(t)

ans = m - s - t

print(ans%mod)

### FIXED CODE ###

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

mod = 10**9 + 7

def comb(n,k,mod):
    if n<k:
        return 0
    if n<0 or k<0:
        return 0
    k=min(n-k,k)
    ans=1
    inv=[1]*(k+1)
    if k>=1:
        ans*=(n-k+1)%mod
    for i in range(2,k+1):
        inv[i]=mod-inv[mod%i]*(mod//i)%mod
        ans=ans*(n-k+i)*inv[i]%mod
    return ans

def comb_mod(n, r, mod):
    if n < r:
        return 0
    elif n < 0 or r < 0:
        return 0
    else:
        fac = [1, 1]
        finv = [1, 1]
        inv = [0, 1]
        for i in range(2, n + 1):
            fac.append(fac[-1] * i % mod)
            inv.append(-inv[mod % i] * (mod // i) % mod)
            finv.append((finv[-1] * inv[-1]) % mod)
        return int(fac[n] * finv[r] * finv[n - r] % mod)

m = pow(2,n,mod) - 1

import math
def perm(n,r):
    return (math.factorial(n)//math.factorial(n-r))

s = comb(n,a,mod)
# print(s)

t = comb(n,b,mod)
# print(t)

ans = m - s - t

print(ans%mod)
### BUGGY CODE ###

N = int(input())

A = list(map(int, input().split()))

c = 0

for i in range(N-1):
  for j in range(int(i)+1, N):
    d = A[i] % (10**9+7)
    e = A[j] % (10**9+7)
    f = (d*e) % (10**9+7)
    c += f
    

c = c % (10**9+7)

print(c)

### FIXED CODE ###

N = int(input())

A = list(map(int, input().split()))

S = 0
for i in range(N):
  S += A[i]

c = S
d = 0
for j in range(N):
  c -= A[j]
  c = c%(10**9+7)
  d += A[j]*c
  d = d%(10**9+7)
  
print(d)
### BUGGY CODE ###

N, K, Q = map(int, input().split())

P = [int(K) for i in range(N)]

for q in range(Q):
    P[int(input())-1] += 1
    for k in range(N):
        P[k] -= 1

for k in range(N):
    if P[k] > 0:
        print('Yes')
    else:
        print('No')


### FIXED CODE ###

N, K, Q = map(int, input().split())

import numpy as np
P = np.ones(N)*K

for q in range(Q):
    P[int(input())-1] += 1

P[:]-=Q

for k in range(N):
    if P[k] > 0:
        print('Yes')
    else:
        print('No')
### BUGGY CODE ###

A, B, K = map(int, input().split())

if K >= A:
    K = K - A
    A = 0
else:
    A = A - K
    K = 0


if K >= B:
    K = K - B
    B = 0
else:
    B = B - K
    K = 0



for i in range(K):
    if A >= 1:
        A -= 1
    elif B >= 1:
        B -= 1
    else:
        pass

print('{} {}'.format(A, B))


### FIXED CODE ###

A, B, K = map(int, input().split())

if K >= A:
    K = K - A
    A = 0
else:
    A = A - K
    K = 0


if K >= B:
    K = K - B
    B = 0
else:
    B = B - K
    K = 0


if A or B:
    for i in range(K):
        if A >= 1:
            A -= 1
        elif B >= 1:
            B -= 1
        else:
            pass

print('{} {}'.format(A, B))
### BUGGY CODE ###

n=int(input())
a_list=[int(i) for i in input().split(' ')]

slaves=[str(a_list.count(i+1)) for i in range(n-1)]+[str(0)]
print('\n'.join(slaves))

### FIXED CODE ###

n=int(input())
a_list=[int(i) for i in input().split(' ')]

import collections

c = collections.Counter(a_list)
[print(c[i+1]) for i in range(n)]
### BUGGY CODE ###

N, Q = map(int, input().split())
S = input()
for i in range(Q):
  l, r = map(int, input().split())
  T = S[(l-1):r]
  n = len(T)
  a = 0
  ans = 0
  if T[0] == 'A':
    a = 1
  for j in range(1,n):
    if a == 1 and T[j] == 'C':
      ans += 1
      a = 0
    if T[j] == 'A':
      a = 1
    else:
      a = 0
  print(ans)

### FIXED CODE ###

N, Q = map(int, input().split())
S = input()
A = []
a = 0
for i in range(N-1):
  if S[i] == 'A' and S[i+1] == 'C':
    a += 1
    A.append(a)
  else:
    A.append(a)
for i in range(Q):
  l, r = map(int, input().split())
  if l>=2:
    ans = A[r-2]-A[l-2]
    print(ans)
  else:
    ans = A[r-2]
    print(ans)
### BUGGY CODE ###

N, M = map(int, input().split())
A = list(map(int, input().split()))
CB = []
for _ in range(M):
    b, c = map(int, input().split())
    CB.append((c, b))

A.sort()

for bc in sorted(CB, reverse=True):
    tgt = bc[0]
    if A[0] >= tgt:
        break
    for i in range(bc[1]):
        if A[0] >= tgt:
            break
        A.pop(0)
        A.append(tgt)

print(sum(A))

### FIXED CODE ###

from operator import itemgetter

N, M = map(int, input().split())
A = list(map(int, input().split()))
BC = []
for _ in range(M):
    BC.append(tuple(map(int, input().split())))

A.sort(reverse=True)
BC.sort(key=itemgetter(1), reverse=True)

n = 0
ans = 0
while True:
    if not BC:
        ans += sum(A[: N - n])
        break
    tgt = BC[0][1]
    a = A[0]
    if a >= tgt:
        ans += A.pop(0)
        n += 1
        if n == N:
            break
    else:
        tgt_n = BC[0][0]
        if n + tgt_n < N:
            ans += tgt * tgt_n
            n += tgt_n
            _ = BC.pop(0)
        else:
            ans += tgt * (N - n)
            break

print(ans)
### BUGGY CODE ###

import sys
from collections import deque
sys.setrecursionlimit(10**5)
def input(): return sys.stdin.readline().strip()

def main():
    N, u, v = map(int, input().split())
    u -= 1
    v -= 1
    repn = [[] for _ in range(N)]
    for i in range(N - 1):
        a, b = map(int, input().split())
        repn[a - 1].append((b - 1, i))
        repn[b - 1].append((a - 1, i)) # (to, id)

    """
    まずu, vを結ぶ単純パス上にあるnodeを列挙する。
    これはvを根とする根付き木に対するdfs（再帰）により求まる（参考：ABC152F）
    """

    path = []
    def connected(v, tv, p=-1):
        if v == tv:
            return True
        for w, _ in repn[v]:
            if w == p:
                continue
            elif connected(w, tv, v):
                path.append(w)
                return True
        return False
    connected(v, u)
    path.append(v)
    #print("path={}".format(path))

    """
    次にu, vを結ぶ単純パスP上の各頂点wに対して、wからPに沿わない向きにどれだけ深く潜れるかを求める。
    しかし最終的には「頂点vから（高橋君が逃げ込める中で）最も遠い頂点」を求めればよいので、
    uvの中点からdfsすれば十分。
    """

    def dfs(v, p): # Pと異なる頂点方向にdfsして深さを求める
        d = -1
        for w, _ in repn[v]:
            if w == p:
                continue
            else:
                d = max(d, dfs(w, v))
        return d + 1
    
    dist = len(path)
    mid = path[dist // 2 - 1]
    par = path[dist // 2]
    ans = dfs(mid, par)
    print(ans + (dist - 1) // 2)
   


if __name__ == "__main__":
    main()


### FIXED CODE ###

import sys
from collections import deque
sys.setrecursionlimit(10**5)
def input(): return sys.stdin.readline().strip()

"""
Pypyは再帰が遅いらしいのでPythonで通してみる
"""

def main():
    N, u, v = map(int, input().split())
    u -= 1
    v -= 1
    repn = [[] for _ in range(N)]
    for i in range(N - 1):
        a, b = map(int, input().split())
        repn[a - 1].append((b - 1, i))
        repn[b - 1].append((a - 1, i)) # (to, id)

    """
    まずu, vを結ぶ単純パス上にあるnodeを列挙する。
    これはvを根とする根付き木に対するdfs（再帰）により求まる（参考：ABC152F）
    """

    path = []
    def connected(v, tv, p=-1):
        if v == tv:
            return True
        for w, _ in repn[v]:
            if w == p:
                continue
            elif connected(w, tv, v):
                path.append(w)
                return True
        return False
    connected(v, u)
    path.append(v)
    #print("path={}".format(path))

    """
    次にu, vを結ぶ単純パスP上の各頂点wに対して、wからPに沿わない向きにどれだけ深く潜れるかを求める。
    しかし最終的には「頂点vから（高橋君が逃げ込める中で）最も遠い頂点」を求めればよいので、
    uvの中点からdfsすれば十分。
    """

    def dfs(v, p): # Pと異なる頂点方向にdfsして深さを求める
        d = -1
        for w, _ in repn[v]:
            if w == p:
                continue
            else:
                d = max(d, dfs(w, v))
        return d + 1
    
    dist = len(path)
    mid = path[dist // 2 - 1]
    par = path[dist // 2]
    ans = dfs(mid, par)
    print(ans + (dist - 1) // 2)
   


if __name__ == "__main__":
    main()
### BUGGY CODE ###

import collections

N,K,L=map(int,input().split())

RP=[i for i in range(N+1)]
Rsize=[1 for i in range(N+1)]
TP=[i for i in range(N+1)]
Tsize=[1 for i in range(N+1)]

def findR(a):
    if a==RP[a]:
        return a
    else:
        return findR(RP[a])
        
def findT(a):
    if a==TP[a]:
        return a
    else:
        return findT(TP[a])
        
def unionR(b,c):
    B=findR(b)
    C=findR(c)
    if Rsize[B]>=Rsize[c]:
        Rsize[B]+=Rsize[C]
        RP[C]=RP[B]
    else:
        Rsize[C]+=Rsize[B]
        RP[B]=RP[C]

def unionT(b,c):
    B=findT(b)
    C=findT(c)
    if Tsize[B]>=Tsize[c]:
        Tsize[B]+=Tsize[C]
        TP[C]=TP[B]
    else:
        Tsize[C]+=Tsize[B]
        TP[B]=TP[C]
        
for i in range(K):
    p,q=map(int,input().split())
    if findR(p)==findR(q):
        pass
    else:
        unionR(p,q)

for i in range(L):
    r,s=map(int,input().split())
    if findT(r)==findT(s):
        pass
    else:
        unionT(r,s)
        
L=collections.defaultdict(int)
for i in range(1,N+1):
    L[findR(i),findT(i)]+=1

ans=str(L[findR(1),findT(1)])
for i in range(2,N+1):
    ans+=" "+str(L[findR(i),findT(i)])
print(ans)


### FIXED CODE ###

N,K,L=map(int,input().split())
Road_P=[i for i in range(N+1)]
Road_size=[1 for i in range(N+1)]

def find_road(a):
    if a==Road_P[a]:
        return a
    else:
        return find_road(Road_P[a])
        
def union_road(b,c):
    B=find_road(b)
    C=find_road(c)
    if Road_size[B]>=Road_size[C]:
        Road_P[C]=Road_P[B]
        Road_size[B]+=Road_size[C]
    else:
        Road_P[B]=Road_P[C]
        Road_size[C]+=Road_size[B]

for i in range(K):
    p,q=map(int,input().split())
    if find_road(p)!=find_road(q):
        union_road(p,q)
#print(Road_P)

Rail_P=[i for i in range(N+1)]
Rail_size=[1 for i in range(N+1)]

def find_rail(a):
    if a==Rail_P[a]:
        return a
    else:
        return find_rail(Rail_P[a])
        
def union_rail(b,c):
    B=find_rail(b)
    C=find_rail(c)
    if Rail_size[B]>=Rail_size[C]:
        Rail_P[C]=Rail_P[B]
        Rail_size[B]+=Rail_size[C]
    else:
        Rail_P[B]=Rail_P[C]
        Rail_size[C]+=Rail_size[B]

for i in range(L):
    p,q=map(int,input().split())
    if find_rail(p)!=find_rail(q):
        union_rail(p,q)

#print(Rail_P)

comb={}
for i in range(1,N+1):
    if (find_road(i),find_rail(i)) in comb:
        comb[(find_road(i),find_rail(i))]+=1
    else:
        comb[(find_road(i),find_rail(i))]=1

#print(comb)

for i in range(1,N+1):
    print(comb[(find_road(i),find_rail(i))])
### BUGGY CODE ###

import numpy as np
N=input()

lists = []
temp=np.asarray([i for i in range(10)])

MOD=10**9+7

dic={0:1}

for i in N:
    new_dic={}
    hoge=list(dic.items())
    if i == "?":
        for amari,count in hoge:
            amari*=10
            a=(temp+amari)%13
            for pa in a:
                if pa in new_dic:
                    new_dic[pa]+=count
                else:
                    new_dic[pa]=count
    else:
        num=int(i)
        for amari,count in hoge:
            a = (amari*10 + num)%13
            if a in new_dic:
                new_dic[a]+=count
            else:
                new_dic[a]=count
    for key in new_dic:
        new_dic[key] %= MOD
    dic = new_dic

try:
    print(dic[5])
except:
    print(0)

### FIXED CODE ###


N=input()

lists = []
temp=[i for i in range(10)]

MOD=10**9+7

dic={0:1}

for i in N:
    new_dic={}
    hoge=list(dic.items())
    if i == "?":
        for amari,count in hoge:
            amari*=10
            for num in temp:
                a = (amari + num) % 13
                if a in new_dic:
                    new_dic[a]+=count
                else:
                    new_dic[a]=count
    else:
        num=int(i)
        for amari,count in hoge:
            a = (amari*10 + num)%13
            if a in new_dic:
                new_dic[a]+=count
            else:
                new_dic[a]=count
    for key in new_dic:
        new_dic[key] %= MOD
    dic = new_dic

try:
    print(dic[5])
except:
    print(0)
### BUGGY CODE ###

class unionFind:
    def __init__(self, n, p):
        p = [0] + p + [0]*9
        self.data = [-1] * (n+10)
        self.sets = [set([i]) for i in range(n+10)]
        self.valsets = [set([p[i]])for i in range(n+10)]

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

    def unite(self, x, y):
        a, b = self.find(x), self.find(y)
        if a!=b:
            self.sets[b] |= self.sets[a]
            self.valsets[b] |= self.valsets[a]
            self.data[b] += self.data[a]
            self.data[a] = b


n, m = map(int, input().split())
p = list(map(int, input().split()))

tree = unionFind(n, p)
for i in range(m):
    x, y = map(int, input().split())
    tree.unite(x, y)

ans = -1
for i in range(n+1):
    if tree.data[i]<0:
        ans += len(tree.sets[i] & tree.valsets[i])
print(ans)

### FIXED CODE ###

class unionFind:
    def __init__(self, n):
        self.data = [-1] * (n+10)

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

    def unite(self, x, y):
        a, b = self.find(x), self.find(y)
        if a!=b:
            self.data[b] += self.data[a]
            self.data[a] = b


n, m = map(int, input().split())
p = list(map(int, input().split()))

tree = unionFind(n)
for i in range(m):
    x, y = map(int, input().split())
    tree.unite(p[x-1], p[y-1])

ans = 0
for i in range(n):
    if tree.find(i+1)==tree.find(p[i]): ans += 1
print(ans)
### BUGGY CODE ###

import numpy as np
bisect_left = np.searchsorted
input()
a = np.int32(input().split())
b = np.int32(input().split())
ans = 0
for k in range(28, -1, -1):
    low = pow(2, k)
    high = pow(2, k + 1)
    a %= high
    b %= high
    b.sort()
    y = np.hstack((b - high, b))
    left = bisect_left(y, low - a)
    right = bisect_left(y, high - a)
    if sum(right - left) % 2:
        ans += low
print(ans)

### FIXED CODE ###

def main():
    from numpy import array,searchsorted,sum,hstack
    n,*t=map(int,open(0).read().split())
    a,b=array(t[:n],'i4'),array(t[n:],'i4')
    c=0
    for k in range(28,-1,-1):
        l,h=pow(2,k),pow(2,k+1)
        a%=h
        b%=h
        b.sort()
        y=hstack((b-h,b))
        i=searchsorted(y,l-a)
        j=searchsorted(y,h-a)
        m=sum(j-i)
        c+=m%2*l
    print(c)
if __name__=='__main__':
    main()
### BUGGY CODE ###

n,a=map(int,input().split())
X=list(map(int,input().split()))
def DP(i,j,k):
  if i==0:
    if j==0 and k==0:
      return 1
    else:
      return 0
  else:
    return DP(i-1,j,k)+DP(i-1,j-1,k-X[i-1])
ans=0
for i in range(1,50):
  ans+=DP(n,i,i*a)
print(ans)

### FIXED CODE ###

n,a=map(int,input().split())
X=[int(i) for i in input().split()]
DP=[[[0 for i in range(50*n+1)] for i in range(n+1)] for i in range(n+1)]
DP[0][0][0]=1
for i in range(1,n+1):
  for j in range(i+1):
    for s in range(50*j+1):
      DP[i][j][s]=DP[i-1][j][s]+DP[i-1][j-1][s-X[i-1]]
ans=0
for j in range(1,n+1):
  ans+=DP[n][j][j*a]
print(ans)
### BUGGY CODE ###

import sys
sys.setrecursionlimit(10**7)

h,w=map(int,input().split())
s=[input() for _ in range(h)]
flag = [[0]*w for _ in range(h)]

def dfs(th,tw):
    global flag,h,w
    flag[th][tw] = True
    tblack = 0
    twhite = 0
    if s[th][tw] == "#":
        tblack += 1
    else:
        twhite += 1 
    for x,y in ([0,1],[0,-1],[1,0],[-1,0]):
        nth = th + x
        ntw = tw + y
        if nth >= 0 and nth < h and ntw >= 0 and ntw < w:
            if not flag[nth][ntw] and s[th][tw] != s[nth][ntw]:
                ttb,ttw = dfs(nth,ntw)
                tblack += ttb
                twhite += ttw
    return [tblack,twhite]
                
res = 0
for i in range(h):
    for j in range(w):
        if not flag[i][j]:
            black,white = dfs(i,j)
            res += black * white 

print(res)

### FIXED CODE ###

import sys
sys.setrecursionlimit(10**7)

h,w=map(int,input().split())
s=[input() for _ in range(h)]
flag = [[0]*w for _ in range(h)]

def dfs(th,tw):
    global flag,h,w,s
    flag[th][tw] = True
    tblack = 0
    twhite = 0
    if s[th][tw] == "#":
        tblack += 1
    else:
        twhite += 1 
    for x,y in ([0,1],[0,-1],[1,0],[-1,0]):
        nth = th + x
        ntw = tw + y
        if nth >= 0 and nth < h and ntw >= 0 and ntw < w:
            if not flag[nth][ntw] and s[th][tw] != s[nth][ntw]:
                ttb,ttw = dfs(nth,ntw)
                tblack += ttb
                twhite += ttw
    return [tblack,twhite]
                
def main():
    global flag,h,w,s
    res = 0
    for i in range(h):
        for j in range(w):
            if not flag[i][j]:
                black,white = dfs(i,j)
                res += black * white 

    return res
print(main())