CodeEff/ECCO huggingface dataset:
# Original solution
from bisect import*
class SqrtSet:
    def __init__(self,block_limit=201):
        self.key=[]
        self.child=[[]]
        self.block_limit=block_limit
    def search_lower(self,key):
        if not key:return None
        ret=None
        i=bisect_left(self.key,key)
        if i:ret=self.key[i-1]
        block=self.child[i]
        i=bisect_left(block,key)
        if i:ret=block[i-1]
        return ret
    def search_higher(self,key):
        if not key:return None
        ret=None
        i=bisect(self.key,key)
        if i<len(self.key):ret=self.key[i]
        block=self.child[i]
        i=bisect(block,key)
        if i<len(block):ret=block[i]
        return ret
    def insert(self,key):
        i=bisect(self.key,key)
        block=self.child[i]
        insort(block,key)
        if len(block)==self.block_limit:
            sep=self.block_limit//2
            self.key.insert(i,block[sep])
            self.child.insert(i+1,block[sep+1:])
            self.child[i]=block[:sep]
def main():
    n,*a=list(map(int,open(0).read().split()))
    l=[0]*n
    for i,v in enumerate(a,1):l[v-1]=i
    t=SqrtSet()
    t.insert(0)
    t.insert(n+1)
    c=0
    for i,v in enumerate(l,1):
        c+=(t.search_higher(v)-v)*(v-t.search_lower(v))*i
        t.insert(v)
    print(c)
main()

# Optimized solution
class UnionFind():
    def __init__(self,size):
        self.table=[-1]*size
    def root(self,x):
        while self.table[x]>=0:
            x=self.table[x]
        return x
    def unite(self,x,y):
        s1=self.root(x)
        s2=self.root(y)
        if s1!=s2:
            if self.table[s1]>self.table[s2]:
                s1,s2=s2,s1
            self.table[s1]+=self.table[s2]
            self.table[s2]=s1
        return
    def same(self,x,y):
        return self.root(x)==self.root(y)
    def size(self,x):
        return -self.table[self.root(x)]
n,*a=list(map(int,open(0).read().split()))
u=UnionFind(n)
b=[0]*n
for i,t in enumerate(a):b[t-1]=i
c=0
for k in b[::-1]:
    l=r=1
    if k>0 and a[k-1]>a[k]:
        l+=u.size(k-1)
        u.unite(k-1,k)
    if k+1<n and a[k+1]>a[k]:
        r+=u.size(k+1)
        u.unite(k+1,k)
    c+=l*r*a[k]
print(c)
# Original solution
import bisect
n = int(eval(input()))
a = [int(i) for i in input().split()]
b = [0 for i in range(n)]
for i in range(n): b[a[i]-1] = i
ans,c = (b[0]+1)*(n-b[0]),[b[0]]
for i in range(1,n):
	x = bisect.bisect_left(c,b[i])
	if 0<x<len(c): ans += (c[x]-b[i])*(b[i]-c[x-1])*(i+1)
	elif x==0: ans += (c[0]-b[i])*(b[i]+1)*(i+1)
	elif x==len(c): ans += (b[i]-c[-1])*(n-b[i])*(i+1)
	bisect.insort_left(c,b[i])
print(ans)

# Optimized solution
n = int(eval(input()))
a = [int(i) for i in input().split()]
b,l,r,ans = [0]*(n+1),[i for i in range(n+2)],[i for i in range(n+2)],0
for i in range(n): b[a[i]]=i
for i in range(n,0,-1):
	m = b[i]
	x,y = l[m],r[m]
	ans+=i*(m-x+1)*(y-m+1)
	l[y+1],r[x-1] = x,y
print(ans)
# Original solution
import sys
sys.setrecursionlimit(2*10**5)

n = int(eval(input()))
a = list(map(int, input().split()))
# aのindexを前計算
d = {}
for i,j in enumerate(a):
    d[j] = i


# segtree
data = [float("inf")]*(2*n)
# a_k の値を x に更新
def update(k, x):
    k += n-1
    data[k] = x
    while k >= 0:
        k = (k - 1) // 2
        data[k] = min(data[2*k+1], data[2*k+2])
# 区間[l, r)の最小値
def query(l, r):
    L = l + n; R = r + n
    s = float("inf")
    while L < R:
        if R & 1:
            R -= 1
            s = min(s, data[R-1])

        if L & 1:
            s = min(s, data[L-1])
            L += 1
        L >>= 1; R >>= 1
    return s

# initialize
for i, j in enumerate(a):
    update(i,j)

# 区間[left, right)が与えられた場合の和を求める再帰
def rec(left=0, right=n):
    if left==right:
        return 0
    # O(logN)
    min_ = query(left, right)
    ind = d[min_]
    res = min_*(right-ind)*(ind+1-left)
    res += rec(left, ind)
    res += rec(ind+1,right)
    return res

print((rec()))

# Optimized solution
n = int(eval(input()))
a = list(map(int, input().split()))
d = {}
for i,j in enumerate(a):
    d[j] = i

uf = [-1]*n
def root(a):
    if uf[a] < 0:
        return a
    uf[a] = root(uf[a])
    return uf[a]
def unite(a,b):
    ra,rb = root(a),root(b)
    if ra==rb:
        return False
    if uf[ra] > uf[rb]:
        ra,rb = rb,ra
    uf[ra] += uf[rb]
    uf[rb] = ra
    return True

ans = 0
for i in range(n,0,-1):
    left=right=0
    ind = d[i]

    if ind<n-1 and a[ind] < a[ind+1]:
        right -= uf[root(ind+1)]
        unite(ind, ind+1)
    if ind>0 and a[ind] < a[ind-1]:
        left -= uf[root(ind-1)]
        unite(ind, ind-1)
    ans += i*(left+1)*(right+1)

print(ans)
# Original solution
N = int(eval(input()))
A = [int(_) for _ in input().split()]
dp = [-1] * (N + 1)
count = [0] * N
for i in range(N):
    count[i] = i - dp[A[i]]
    dp = dp[:A[i]] + [i] * (N - A[i] + 1)
dp_r = [N] * (N + 1)
ans = 0
for i in range(N - 1, -1, -1):
    ans += A[i] * (dp_r[A[i]] - i) * count[i]
    dp_r = dp_r[:A[i]] + [i] * (N - A[i] + 1)
print(ans)


# Optimized solution
N = int(eval(input()))
A = [int(_) for _ in input().split()]
left = list(range(N + 2))
right = list(range(N + 2))
index = {A[i - 1]: i for i in range(1, N + 1)}
ans = 0
for a in range(N, 0, -1):
    i = index[a]
    l = left[i]
    r = right[i]
    ans += a * (i - l + 1) * (r - i + 1)
    left[r + 1] = l
    right[l - 1] = r
print(ans)
# Original solution
n=int(eval(input()))
ide_ele=n
num=2**(n-1).bit_length()
seg=[ide_ele]*2*num
segfunc=min

def init(init_val):
  for i in range(n):
    seg[i+num-1]=init_val[i]    
    for i in range(num-2,-1,-1) :
      seg[i]=segfunc(seg[2*i+1],seg[2*i+2]) 
    
def update(k,x):
  k+=num-1
  seg[k]=x
  while k+1:
    k=(k-1)//2
    seg[k]=segfunc(seg[k*2+1],seg[k*2+2])
    
def query(p,q):
  if q<=p:
    return ide_ele
  p+=num-1
  q+=num-2
  res=ide_ele
  while q-p>1:
    if p&1==0:
      res=segfunc(res,seg[p])
    if q&1==1:
      res=segfunc(res,seg[q])
      q-=1
    p=p//2
    q=(q-1)//2
  if p==q:
    res=segfunc(res,seg[p])
  else:
    res=segfunc(segfunc(res,seg[p]),seg[q])
  return res
init_val=[int(i) for i in input().split()]
init(init_val)
ans=0
for i in range(n):
  for j in range(i,n):
    ans+=query(i,j+1)
print(ans)


# Optimized solution
n=int(eval(input()))
A=[int(i) for i in input().split()]

Ans=[0]*n
Ans[0]=1
Stack=[[A[0],1]]
for i in range(1,n):
  a=A[i]
  b,ct_b=Stack.pop()
  ct=1
  while b>a and Stack:
    ct+=ct_b
    b,ct_b=Stack.pop()
  if b<a:
    Stack.append([b,ct_b])
    Stack.append([a,ct])
  else:
    Stack.append([a,ct+ct_b])
    ct+=ct_b
  Ans[i]=ct
RA=A[::-1]
Ans_R=[0]*n
Ans_R[0]=1
Stack=[[RA[0],1]]
for i in range(1,n):
  a=RA[i]
  b,ct_b=Stack.pop()
  ct=1
  while b>a and Stack:
    ct+=ct_b
    b,ct_b=Stack.pop()
  if b<a:
    Stack.append([b,ct_b])
    Stack.append([a,ct])
  else:
    Stack.append([a,ct+ct_b])
    ct+=ct_b
  Ans_R[i]=ct  
Ans_R=Ans_R[::-1]
ans=0
for i in range(n):
  ans+=(A[i]*Ans[i]*Ans_R[i])
print(ans)
# Original solution
class BinaryIndexTree:  # 1-indexed
    def __init__(self, N):
        """
        INPUT
        N [int] -> 全部0で初期化
        N [list] -> そのまま初期化
        """
        if isinstance(N, int):
            self.N = N
            self.depth = N.bit_length()
            self.tree = [0] * (N + 1)
            self.elem = [0] * (N + 1)
        elif isinstance(N, list):
            self.N = len(N)
            self.depth = self.N.bit_length()
            self.tree = [0] + N
            self.elem = [0] + N
            self._init()
        else:
            raise "INVALID INPUT: input must be int or list"

    def _init(self):
        size = self.N + 1
        for i in range(1, self.N):
            if i + (i & -i) > size:
                continue
            self.tree[i + (i & -i)] += self.tree[i]

    def add(self, i, x):
        self.elem[i] += x
        while i <= self.N:
            self.tree[i] += x
            i += i & -i

    def sum(self, i):
        res = 0
        while i > 0:
            res += self.tree[i]
            i -= i & -i
        return res

    def lower_bound(self, val):
        if val <= 0:
            return 0
        i = 0
        k = 1 << self.depth
        while k:
            if i + k <= self.N and self.tree[i + k] < val:
                val -= self.tree[i + k]
                i += k
            k >>= 1
        return i + 1


if __name__ == "__main__":
    N = int(eval(input()))
    P = list(map(int, input().split()))
    idx = {a: i for i, a in enumerate(P, start=1)}

    bit = BinaryIndexTree(N)
    ans = 0
    for i in range(1, N + 1):
        bit.add(idx[i], 1)
        s = bit.sum(idx[i])
        l = bit.lower_bound(s)-bit.lower_bound(s-1)
        r = bit.lower_bound(s+1) - idx[i]
        ans += i*l*r
    print(ans)

# Optimized solution
N = int(eval(input()))
A = list(map(int, input().split()))
a_to_i = {a: i for i, a in enumerate(A, start=1)}

L = [i - 1 for i in range(N + 2)]
R = [i + 1 for i in range(N + 2)]

ans = 0
for a in range(N, 0, -1):
    i = a_to_i[a]
    ans += a * (R[i] - i) * (i - L[i])
    L[R[i]] = L[i]
    R[L[i]] = R[i]

print(ans)
# Original solution
A, B = list(map(int, input().split()))

if B % A == 0: print(str(A+B))
else: print(str(B-A))




# Optimized solution
A, B = list(map(int, input().split()))

if B % A == 0: print((A+B))
else: print((B-A))
# Original solution
a,b=list(map(int,input().split()))
if b%a==0:
  print((a+b))
else:
  print((b-a))

# Optimized solution
a,b=list(map(int,input().split()))
print((b-a+2*a*(b%a==0)))
# Original solution
A, B = list(map(int, input().split()))

if B % A == 0:
    print((A+B))
else:
    print((B-A))

# Optimized solution
A, B = list(map(int, input().split()))
print((B+A if B%A == 0 else B-A))
# Original solution
def read():
    return int(eval(input()))

def reads():
    return list(map(int, input().split()))

a,b =reads()
if b%a == 0:
    print((a+b))
else:
    print((b-a))

# Optimized solution
a,b = list(map(int,input().split()))
print((a+b if b%a == 0 else b-a))
# Original solution
A, B = list(map(int,input().split()))
if B % A == 0:
  print((A + B))
else:
  print((B - A))

# Optimized solution
a,b=list(map(int,input().split()))
if b%a== 0:
    print((a+b))
else:
    print((b-a))
# Original solution
a, b = list(map(int, input().split()))
print(((a + b) if b % a == 0 else (b - a)))


# Optimized solution
a,b=list(map(int,input().split()));print(([b+a,b-a][b%a>0]))
# Original solution
a,b=list(map(int,input().split()));print(((b-a)*(b%a>0)or a+b))

# Optimized solution
a,b=list(map(int,input().split()))
print((a+b-2*a*(b%a>0)))
# Original solution
def ans():
  a, b = list(map(int,input().split()))
  if(b%a == 0):
    print((a+b))
  else:
    print((b-a))
ans()

# Optimized solution
A, B = list(map(int,input().split()))
if(B%A == 0):
  print((A+B))
else:
  print((B-A))
# Original solution
a,b = list(map(int,input().split()))
if b%a == 0:
    print((b+a))
else:
    print((b-a))

# Optimized solution
a,b = list(map(int,input().split()))
if b%a==0:print((a+b))
else:print((b-a))
# Original solution
while 1:
    r,a=input().split()
    if r=='0' and a=='0': break
    h = b = 0
    for i in range(4):
        if r[i]==a[i]: h+=1
    for i in range(10):
        b += min(r.count(chr(ord('0')+i)),a.count(chr(ord('0')+i)))
    print(h,b-h)

# Optimized solution
while 1:
    r,a=input().split()
    if r=='0' and a=='0': break
    h = b = 0
    for i in range(4):
        if r[i]==a[i]: h+=1
    for s in r:
        for t in a:
            if s==t:
                b+=1; break;
    print(h,b-h)
# Original solution
H, W , N = list(map(int,input().split()))
from bisect import bisect_left
from bisect import bisect_right
matrix = []
for _ in range(N):
    x,y = list(map(int,input().split()))
    x -= 1
    y -= 1
    matrix.append([x,y])
matrix.sort()
ans = [0 for _ in range(10)]
from bisect import bisect_left
cand = {}
for l in matrix:
    for x_r in [-2, -1 , 0]:
        for y_r in [-2, -1 , 0]:
            nowx = l[0] + x_r
            nowy = l[1] + y_r
            if nowx < 0 or nowy < 0 or nowx + 2>= H or nowy+ 2 >= W:
                continue
            #ここで起点(左上)nowx, nowy として　 9マスに着目する
            name = str(nowx) + str(nowy)
            try: cand[name] += 1
            except: cand[name] = 1
tmp = ((H - 2) * (W - 2))
for x in list(cand.values()):
    if x > 9:
        while True:
            print(W)
    ans[x] += 1
    tmp -= 1
ans[0] = tmp
for x in ans:
    print(x)

    
    


# Optimized solution
H, W , N = list(map(int,input().split()))
from bisect import bisect_left
from bisect import bisect_right
matrix = []
for _ in range(N):
    x,y = list(map(int,input().split()))
    x -= 1
    y -= 1
    matrix.append([x,y])
matrix.sort()
ans = [0 for _ in range(10)]
cand = {}
for l in matrix:
    for x_r in [-2, -1 , 0]:
        for y_r in [-2, -1 , 0]:
            nowx = l[0] + x_r
            nowy = l[1] + y_r
            if nowx < 0 or nowy < 0 or nowx + 2>= H or nowy+ 2 >= W:
                continue
            #ここで起点(左上)nowx, nowy として　 9マスに着目する
            name = str(nowx) +"hoge" +str(nowy)
            try: cand[name] += 1
            except: cand[name] = 1
tmp = ((H - 2) * (W - 2))
for x in list(cand.values()):
    ans[x] += 1
    tmp -= 1
ans[0] = tmp
for x in ans:
    print(x)
# Original solution
H, W , N = list(map(int,input().split()))
from bisect import bisect_left
from bisect import bisect_right
matrix = []
for _ in range(N):
    x,y = list(map(int,input().split()))
    x -= 1
    y -= 1
    matrix.append([x,y])
matrix.sort()
ans = [0 for _ in range(10)]
cand = {}
for l in matrix:
    for x_r in [-2, -1 , 0]:
        for y_r in [-2, -1 , 0]:
            nowx = l[0] + x_r
            nowy = l[1] + y_r
            if nowx < 0 or nowy < 0 or nowx + 2>= H or nowy+ 2 >= W:
                continue
            #ここで起点(左上)nowx, nowy として　 9マスに着目する
            name = str(nowx) +"hoge" +str(nowy)
            try: cand[name] += 1
            except: cand[name] = 1
tmp = ((H - 2) * (W - 2))
for x in list(cand.values()):
    ans[x] += 1
    tmp -= 1
ans[0] = tmp
for x in ans:
    print(x)


# Optimized solution
H, W , N = list(map(int,input().split()))
from bisect import bisect_left
from bisect import bisect_right
matrix = []
for _ in range(N):
    x,y = list(map(int,input().split()))
    x -= 1
    y -= 1
    matrix.append([x,y])
matrix.sort()
ans = [0 for _ in range(10)]
cand = {}
for l in matrix:
    for x_r in [-2, -1 , 0]:
        for y_r in [-2, -1 , 0]:
            nowx = l[0] + x_r
            nowy = l[1] + y_r
            if nowx < 0 or nowy < 0 or nowx + 2>= H or nowy+ 2 >= W:
                continue
            #ここで起点(左上)nowx, nowy として　 9マスに着目する
            name = str(nowx) + 'sakoda'  +str(nowy)
            try: cand[name] += 1
            except: cand[name] = 1
tmp = ((H - 2) * (W - 2))
for x in list(cand.values()):
    ans[x] += 1
    tmp -= 1
ans[0] = tmp
for x in ans:
    print(x)
# Original solution
H, W , N = list(map(int,input().split()))
from bisect import bisect_left
from bisect import bisect_right
matrix = []
for _ in range(N):
    x,y = list(map(int,input().split()))
    x -= 1
    y -= 1
    matrix.append([x,y])
matrix.sort()
ans = [0 for _ in range(10)]
cand = {}
for l in matrix:
    for x_r in [-2, -1 , 0]:
        for y_r in [-2, -1 , 0]:
            nowx = l[0] + x_r
            nowy = l[1] + y_r
            if nowx < 0 or nowy < 0 or nowx + 2>= H or nowy+ 2 >= W:
                continue
            #ここで起点(左上)nowx, nowy として　 9マスに着目する
            name = str(nowx) + 'sakoda'  +str(nowy)
            try: cand[name] += 1
            except: cand[name] = 1
tmp = ((H - 2) * (W - 2))
for x in list(cand.values()):
    ans[x] += 1
    tmp -= 1
ans[0] = tmp
for x in ans:
    print(x)


# Optimized solution
H, W , N = list(map(int,input().split()))
from bisect import bisect_left
from bisect import bisect_right
matrix = []
for _ in range(N):
    x,y = list(map(int,input().split()))
    x -= 1
    y -= 1
    matrix.append([x,y])
matrix.sort()
ans = [0 for _ in range(10)]
cand = {}
for l in matrix:
    for x_r in [-2, -1 , 0]:
        for y_r in [-2, -1 , 0]:
            nowx = l[0] + x_r
            nowy = l[1] + y_r
            if nowx < 0 or nowy < 0 or nowx + 2>= H or nowy+ 2 >= W:
                continue
            #ここで起点(左上)nowx, nowy として　 9マスに着目する
            name = str(nowx) + ' '  +str(nowy)
            try: cand[name] += 1
            except: cand[name] = 1
tmp = ((H - 2) * (W - 2))
for x in list(cand.values()):
    ans[x] += 1
    tmp -= 1
ans[0] = tmp
for x in ans:
    print(x)
# Original solution
a={}
h,w,n=list(map(int,input().split()))
for i in range(n):
  y,x=list(map(int,input().split()))
  for j in range(max(2,x-1),min(w-1,x+1)+1):
    for k in range(max(2,y-1),min(h-1,y+1)+1):
      if j*(10**10)+k in a:
        a[j*(10**10)+k]+=1
      else:
        a[j*(10**10)+k]=1
ans=[0]*10
ans[0]=(h-2)*(w-2)
for key in a:
  ans[0]-=1
  ans[a[key]]+=1
for i in ans:
  print(i)

# Optimized solution
h,w,n=list(map(int,input().split()))
dic={}
INF=10**10
for i in range(n):
  y,x=list(map(int,input().split()))
  for j in range(max(2,x-1),min(w-1,x+1)+1):
    for k in range(max(2,y-1),min(h-1,y+1)+1):
      if j*INF+k in dic:
        dic[j*INF+k]+=1
      else:
        dic[j*INF+k]=1
ans=[0]*10
ans[0]=(h-2)*(w-2)
for i in dic:
  ans[0]-=1
  ans[dic[i]]+=1
for i in ans:
  print(i)
# Original solution
from collections import defaultdict
import sys
input = sys.stdin.readline

H,W,N = map(int,input().split())
D = defaultdict(bool)
B = []

for _ in range(N):
    a,b = map(lambda x: int(x)-1,input().split())
    D[(a,b)] = True
    B.append((a,b))

ans = [0 for _ in range(10)]

for a,b in B:
    for i in range(9):
        ix,iy = divmod(i,3)
        if a-ix<0 or b-iy<0:
            continue
        black_count = 0
        for j in range(9):
            jx,jy = divmod(j,3)
            if H<=a-ix+jx or W<=b-iy+jy:
                break
            if D[(a-ix+jx,b-iy+jy)]:
                if -ix+jx<0 or (-ix+jx==0 and -iy+jy<0):
                    break
                black_count += 1
        else:
            ans[black_count] += 1

ans[0] = (H-2)*(W-2)-sum(ans)
print(*ans,sep='\n')


# Optimized solution
from collections import defaultdict
import sys
input = sys.stdin.readline

H,W,N = map(int,input().split())
D = defaultdict(bool)
B = []

for _ in range(N):
    a,b = map(lambda x: int(x)-1,input().split())
    D[(a,b)] = True
    B.append((a,b))

ans = [0 for _ in range(10)]

for a,b in B:
    for i in range(9):
        ix,iy = divmod(i,3)
        if a-ix<0 or b-iy<0:
            continue
        black_count = 0
        for j in range(9):
            jx,jy = divmod(j,3)
            if H<=a-ix+jx or W<=b-iy+jy:
                break
            if (a-ix+jx,b-iy+jy) in D:
                if -iy+jy<0 or (-iy+jy==0 and -ix+jx<0):
                    break
                black_count += 1
        else:
            ans[black_count] += 1

ans[0] = (H-2)*(W-2)-sum(ans)
print(*ans,sep='\n')
# Original solution
from collections import Counter
import sys
import itertools
input = sys.stdin.readline

c = Counter()
H,W,N = list(map(int,input().split()))
for _ in range(N):
  a,b = list(map(int,input().split()))
  # そのセルを含む正方形の中心を記録
  for dx,dy in itertools.product([-1,0,1],repeat = 2):
    aa = a + dx
    bb = b + dy
    if 2 <= aa <= H-1 and 2 <= bb <= W-1:
	    c[(aa,bb)] += 1

result = Counter(list(c.values()))
result[0] = (H-2)*(W-2) - sum(result.values())

for j in range(10):
  print((result[j]))

# Optimized solution
from collections import defaultdict, Counter
import sys
import itertools
input = sys.stdin.readline

c = defaultdict(int)
H,W,N = list(map(int,input().split()))
for _ in range(N):
  a,b = list(map(int,input().split()))
  # そのセルを含む正方形の中心を記録
  for dx,dy in itertools.product([-1,0,1],repeat = 2):
    aa = a + dx
    bb = b + dy
    if 2 <= aa <= H-1 and 2 <= bb <= W-1:
	    c[(aa,bb)] += 1

result = Counter(list(c.values()))
result[0] = (H-2)*(W-2) - sum(result.values())

for j in range(10):
  print((result[j]))
# Original solution
import sys
from bisect import bisect_left
from collections import defaultdict
def input(): return sys.stdin.readline().strip()

def main():
    H, W, N = list(map(int, input().split()))
    black = []
    d = defaultdict(list)
    for _ in range(N):
        a, b = list(map(int, input().split()))
        black.append((a - 1, b - 1))
        d[a - 1].append(b - 1)
    for key in d: d[key].sort()

    ans = [0] * 10
    checked = set()
    # (a, b)がテンプレートのどこにいるかで９通り試す
    for i in range(9):
        for a, b in black:
            h, w = a - i // 3, b - i % 3
            if (h, w) in checked: continue
            if h < 0 or w < 0: continue
            if h > H - 3 or w > W - 3: continue
            cnt = 0
            idx1 = bisect_left(d[h], w)
            idx2 = bisect_left(d[h], w + 3)
            cnt += idx2 - idx1
            idx1 = bisect_left(d[h + 1], w)
            idx2 = bisect_left(d[h + 1], w + 3)
            cnt += idx2 - idx1
            idx1 = bisect_left(d[h + 2], w)
            idx2 = bisect_left(d[h + 2], w + 3)
            cnt += idx2 - idx1
            #print("({}, {})=>{}".format(h, w, cnt))
            ans[cnt] += 1
            checked.add((h, w))
    ans[0] = (H - 2) * (W - 2) - sum(ans[1:])
    for a in ans: print(a)




if __name__ == "__main__":
    main()


# Optimized solution
import sys
def input(): return sys.stdin.readline().strip()

def main():
    """
    https://atcoder.jp/contests/abc045/submissions/14945636
    が高速に動作していたので参考に写経する。

    各黒マスに対して、それを含むテンプレートを左上の座標値で管理する。
    （写経元は右下座標で管理してる）
    このテンプレート及びそこに黒マスが何個入っているかを管理しておけば
    黒マス位置をソートして全体位置を把握していなくてもオンラインで更新が可能。
    """
    H, W, N = list(map(int, input().split()))
    ans = [0] * 10
    templates = {}
    for _ in range(N):
        a, b = list(map(int, input().split()))
        for i in range(9):
            # (h, w)がテンプレートの左上座標
            h, w = (a - 3) + i // 3, (b - 3) + i % 3
            if h < 0 or w < 0: continue
            if h > H - 3 or w > W - 3: continue
            idx = h * W + w
            if idx in templates:
                ans[templates[idx]] -= 1
                templates[idx] += 1
                ans[templates[idx]] += 1
            else:
                templates[idx] = 1
                ans[1] += 1
    ans[0] = (H - 2) * (W - 2) - sum(ans[1:])
    for a in ans: print(a)


if __name__ == "__main__":
    main()
# Original solution
def sol():
    import sys
    input=sys.stdin.readline
    h,w,n=list(map(int,input().split()))
    d={}
    for i in range(n):
        y,x=list(map(int,input().split()))
        if (y,x) in d:
            d[(y,x)]+=1
        else:
            d[(y,x)]=1
        if y+1<=h and (y+1,x) in d:
            d[(y+1,x)]+=1
        elif y+1<=h:
            d[(y+1,x)]=1
        if y+2<=h and (y+2,x) in d:
            d[(y+2,x)]+=1
        elif y+2<=h:
            d[(y+2,x)]=1
 
        if x+1<=w and (y,x+1) in d:
            d[(y,x+1)]+=1
        elif x+1<=w:
            d[(y,x+1)]=1
        if x+2<=w and (y,x+2) in d:
            d[(y,x+2)]+=1
        elif x+2<=w:
            d[(y,x+2)]=1
        if x+1<=w and y+1<=h and (y+1,x+1) in d:
            d[(y+1,x+1)]+=1
        elif x+1<=w and y+1<=h:
            d[(y+1,x+1)]=1
        if x+2<=w and y+1<=h and (y+1,x+2) in d:
            d[(y+1,x+2)]+=1
        elif x+2<=w and y+1<=h:
            d[(y+1,x+2)]=1
        if x+1<=w and y+2<=h and (y+2,x+1) in d:
            d[(y+2,x+1)]+=1
        elif x+1<=w and y+2<=h:
            d[(y+2,x+1)]=1
        if x+2<=w and y+2<=h and (y+2,x+2) in d:
            d[(y+2,x+2)]+=1
        elif x+2<=w and y+2<=h:
            d[(y+2,x+2)]=1
    ans=[0]*10
    for i in d:
        if i[0]>2 and i[1]>2:
            ans[d[i]]+=1
 
    ans[0]=h*w-sum(ans)-w*2-h*2+4
    for i in ans:
        print(i)
        
if __name__=="__main__":
    sol()

# Optimized solution
def sol():
    import sys
    input=sys.stdin.readline
    h,w,n=list(map(int,input().split()))
    d={}
    t=[(0,0),(0,1),(0,2),(1,0),(1,1),(1,2),(2,0),(2,1),(2,2)]
    for i in range(n):
        y,x=list(map(int,input().split()))
        for a,b in t:
            a+=y
            b+=x
            if 0<a<=h and 0<b<=w and (a,b) in d: d[(a,b)]+=1
            elif 0<a<=h and 0<b<=w: d[(a,b)]=1

    ans=[0]*10
    for i in d:
        if i[0]>2 and i[1]>2:
            ans[d[i]]+=1

    ans[0]=h*w-sum(ans)-w*2-h*2+4
    for i in ans:
        print(i)

if __name__=="__main__":
    sol()