Little Tanya decided to present her dad a postcard on his Birthday. She has already created a message — string s of length n, consisting of uppercase and lowercase English letters. Tanya can't write yet, so she found a newspaper and decided to cut out the letters and glue them into the postcard to achieve string s. The newspaper contains string t, consisting of uppercase and lowercase English letters. We know that the length of string t greater or equal to the length of the string s.

The newspaper may possibly have too few of some letters needed to make the text and too many of some other letters. That's why Tanya wants to cut some n letters out of the newspaper and make a message of length exactly n, so that it looked as much as possible like s. If the letter in some position has correct value and correct letter case (in the string s and in the string that Tanya will make), then she shouts joyfully "YAY!", and if the letter in the given position has only the correct value but it is in the wrong case, then the girl says "WHOOPS".

Tanya wants to make such message that lets her shout "YAY!" as much as possible. If there are multiple ways to do this, then her second priority is to maximize the number of times she says "WHOOPS". Your task is to help Tanya make the message.


-----Input-----

The first line contains line s (1 ≤ |s| ≤ 2·10^5), consisting of uppercase and lowercase English letters — the text of Tanya's message.

The second line contains line t (|s| ≤ |t| ≤ 2·10^5), consisting of uppercase and lowercase English letters — the text written in the newspaper.

Here |a| means the length of the string a.


-----Output-----

Print two integers separated by a space:  the first number is the number of times Tanya shouts "YAY!" while making the message,  the second number is the number of times Tanya says "WHOOPS" while making the message. 


-----Examples-----
Input
AbC
DCbA

Output
3 0

Input
ABC
abc

Output
0 3

Input
abacaba
AbaCaBA

Output
3 4

Difficulty: MEDIUM
Tags: String algorithms

Implementation

Greedy algorithms
Skill types: Greedy algorithms

Starter code:

Solutions:
import collections
s = input()
t = input()
letter_s = collections.Counter(s)
letter_t = collections.Counter(t)
yay = 0
whoops = 0
for i in s:
	if letter_t[i] > 0:
		letter_s[i] -= 1
		letter_t[i] -= 1
		yay += 1
for i in s:
	if letter_s[i] > 0:
		if i.islower() and letter_t[i.upper()] > 0:
			letter_s[i] -= 1
			letter_t[i.upper()] -= 1
			whoops += 1
		elif i.isupper() and letter_t[i.lower()] > 0:
			letter_s[i] -= 1
			letter_t[i.lower()] -= 1
			whoops += 1
print(yay, whoops)


s = input()
t = input()

def id(c):
	if 'a' <= c <= 'z':
		return ord(c) - ord('a')
	return ord(c) - ord('A') + 26
cnt = [0] * 52
Free = [0] * len(s)
(yay, whoops) = (0, 0)
for i in t:
	cnt[id(i)] += 1
for i in range(len(s)):
	if cnt[id(s[i])] > 0:
		yay += 1
		cnt[id(s[i])] -= 1
		Free[i] = 1
for i in range(len(s)):
	if Free[i] == 0:
		if cnt[id(s[i].upper())] > 0:
			whoops += 1
			cnt[id(s[i].upper())] -= 1
		if cnt[id(s[i].lower())] > 0:
			whoops += 1
			cnt[id(s[i].lower())] -= 1
print(yay, whoops)


s = input()
t = input()
yay = 0
whoops = 0
message = {}
newspaper = {}
for i in s:
	message[i] = message.get(i, 0) + 1
for j in t:
	newspaper[j] = newspaper.get(j, 0) + 1
for i in message:
	newspaper[i] = newspaper.get(i, 0)
	used = min(newspaper[i], message[i])
	yay += used
	newspaper[i] -= used
	message[i] -= used
for i in message:
	if i.isupper():
		newspaper[i.lower()] = newspaper.get(i.lower(), 0)
		whoops += min(newspaper[i.lower()], message[i])
	else:
		newspaper[i.upper()] = newspaper.get(i.upper(), 0)
		whoops += min(newspaper[i.upper()], message[i])
print(str(yay) + ' ' + str(whoops))


s = input()
t = input()
arrS = [0] * 70
arrT = [0] * 70
for i in range(len(s)):
	arrS[ord(s[i]) - ord('A')] += 1
for i in range(len(t)):
	arrT[ord(t[i]) - ord('A')] += 1
yay = 0
whoops = 0
for i in range(70):
	temp = min(arrS[i], arrT[i])
	yay += temp
	arrT[i] -= temp
	arrS[i] -= temp
for i in range(28):
	temp = min(arrS[i], arrT[i + 32])
	arrT[i + 32] -= temp
	arrS[i] -= temp
	whoops += temp
for i in range(32, 68):
	temp = min(arrS[i], arrT[i - 32])
	arrT[i - 32] -= temp
	arrS[i] -= temp
	whoops += temp
print('{} {}'.format(yay, whoops))


from collections import Counter

def rev(c):
	return str.upper(c) if str.islower(c) else str.lower(c)
s = Counter(input())
t = Counter(input())
y = 0
o = 0
for k in s:
	d = min(s[k], t[k])
	s[k] -= d
	t[k] -= d
	y += d
for k in s:
	l = rev(k)
	d = min(s[k], t[l])
	o += d
	s[k] -= d
	t[l] -= d
print(y, o)


message = input()
newspaper = input()
dict_letter = {}
dict_letterBoolean = []
yay = 0
whoops = 0
for l in message:
	if l in dict_letter:
		dict_letter[l] = dict_letter[l] + 1
	else:
		dict_letter[l] = 1
for l in newspaper:
	if l in dict_letter and dict_letter[l] > 0:
		dict_letter[l] = dict_letter[l] - 1
		yay = yay + 1
		dict_letterBoolean.append(True)
	else:
		dict_letterBoolean.append(False)
for i in range(len(newspaper)):
	l = newspaper[i]
	lSwapedcase = l.swapcase()
	if lSwapedcase in dict_letter and dict_letter[lSwapedcase] > 0 and (not dict_letterBoolean[i]):
		dict_letter[lSwapedcase] = dict_letter[lSwapedcase] - 1
		whoops = whoops + 1
print(yay, whoops)


def cov(ch):
	if ch >= 'a' and ch <= 'z':
		return ord(ch) - ord('a')
	else:
		return ord(ch) - ord('A') + 26
lt1 = list(map(cov, input()))
lt2 = list(map(cov, input()))
cnt = [0] * 52
for x in lt2:
	cnt[x] += 1
ans0 = 0
ans1 = 0
for i in range(0, len(lt1)):
	x = lt1[i]
	if cnt[x]:
		cnt[x] -= 1
		ans0 += 1
		lt1[i] = -1
for i in range(0, len(lt1)):
	x = lt1[i]
	if x == -1:
		continue
	elif x >= 26:
		x -= 26
	else:
		x += 26
	if cnt[x]:
		cnt[x] -= 1
		ans1 += 1
print(ans0, ans1)


S = input()
T = input()
N = len(S)
deg = [0 for i in range(300)]
for i in range(len(T)):
	deg[ord(T[i])] += 1
yay = 0
whp = 0
used = [False for i in range(3 * 10 ** 5)]
for i in range(N):
	if deg[ord(S[i])] >= 1:
		yay += 1
		deg[ord(S[i])] -= 1
		used[i] = True
for i in range(N):
	if used[i] == False:
		if S[i].isupper():
			tmp = S[i].lower()
			if deg[ord(tmp)] >= 1:
				whp += 1
				deg[ord(tmp)] -= 1
				used[i] = True
		if S[i].islower():
			tmp = S[i].upper()
			if deg[ord(tmp)] >= 1:
				whp += 1
				deg[ord(tmp)] -= 1
				used[i] = True
print(yay, whp)


def main():
	(s, t) = (input(), input())
	mappingS = list(s)
	mappingT = list(t)
	yay = 0
	whoops = 0
	offset = ord('A') - ord('a')
	for i in range(ord('a'), ord('z') + 1, 1):
		sLower = mappingS.count(chr(i))
		tLower = mappingT.count(chr(i))
		sUpper = mappingS.count(chr(i + offset))
		tUpper = mappingT.count(chr(i + offset))
		contribution = min(sLower, tLower) + min(sUpper, tUpper)
		yay += contribution
		whoops += min(tLower + tUpper, sLower + sUpper) - contribution
	print('{0} {1}'.format(yay, whoops))
main()


from sys import stdin
from itertools import combinations
import sys
import math
from collections import defaultdict
sys.setrecursionlimit(15000)

def make_dict(string):
	mydict = dict()
	for i in string:
		if i in mydict:
			mydict[i] += 1
		else:
			mydict[i] = 1
	return mydict

def change_case(char):
	if ord(char) >= 65 and ord(char) <= 90:
		return chr(97 + ord(char) - 65)
	else:
		return chr(65 + ord(char) - 97)
s = list(stdin.readline().strip())
t = list(stdin.readline().strip())
dict1 = make_dict(s)
dict2 = make_dict(t)
Y = 0
W = 0
for i in dict1:
	if i in dict2:
		if dict1[i] < dict2[i]:
			Y += dict1[i]
			dict2[i] -= dict1[i]
			dict1[i] = 0
		else:
			Y += dict2[i]
			dict1[i] -= dict2[i]
			dict2[i] = 0
for i in dict1:
	if dict1[i] > 0:
		ni = change_case(i)
		if ni in dict2:
			if dict1[i] < dict2[ni]:
				W += dict1[i]
				dict2[ni] -= dict1[i]
				dict1[i] = 0
			else:
				W += dict2[ni]
				dict1[i] -= dict2[ni]
				dict2[ni] = 0
print(Y, W)


s = input()
t = input()
s_letters = {}
t_letters = {}
for i in s:
	tt = tuple([i.lower()])
	if tt not in t_letters:
		t_letters[tt] = [0, 0]
	if tt not in s_letters:
		s_letters[tt] = [0, 0]
	if i == i.lower():
		s_letters[tt][0] += 1
	else:
		s_letters[tt][1] += 1
for i in t:
	tt = tuple([i.lower()])
	if i == i.lower():
		if tt in t_letters.keys():
			t_letters[tt][0] += 1
	elif tt in t_letters.keys():
		t_letters[tt][1] += 1
yay = 0
oops = 0
for i in s_letters.keys():
	tmp_yay_lower = min(s_letters[i][0], t_letters[i][0])
	tmp_yay_upper = min(s_letters[i][1], t_letters[i][1])
	tmp_oops = max(0, min(s_letters[i][0] + s_letters[i][1] - tmp_yay_lower - tmp_yay_upper, t_letters[i][0] + t_letters[i][1] - tmp_yay_lower - tmp_yay_upper))
	yay += tmp_yay_lower + tmp_yay_upper
	oops += tmp_oops
print(yay, oops)


import sys
import string
import math
from collections import defaultdict
from functools import lru_cache
from collections import Counter
from fractions import Fraction

def mi(s):
	return map(int, s.strip().split())

def lmi(s):
	return list(mi(s))

def tmi(s):
	return tuple(mi(s))

def mf(f, s):
	return map(f, s)

def lmf(f, s):
	return list(mf(f, s))

def js(lst):
	return ' '.join((str(d) for d in lst))

def jsns(lst):
	return ''.join((str(d) for d in lst))

def line():
	return sys.stdin.readline().strip()

def linesp():
	return line().split()

def iline():
	return int(line())

def mat(n):
	matr = []
	for _ in range(n):
		matr.append(linesp())
	return matr

def matns(n):
	mat = []
	for _ in range(n):
		mat.append([c for c in line()])
	return mat

def mati(n):
	mat = []
	for _ in range(n):
		mat.append(lmi(line()))
	return mat

def pmat(mat):
	for row in mat:
		print(js(row))

def main():
	(S, T) = (line(), line())
	counts = Counter(T)
	yay = 0
	who = 0
	done = set()
	for (e, c) in enumerate(S):
		if counts[c] > 0:
			counts[c] -= 1
			yay += 1
			done.add(e)
	for (e, c) in enumerate(S):
		if e in done:
			continue
		if c.isupper():
			if counts[c.lower()] > 0:
				who += 1
				counts[c.lower()] -= 1
		elif counts[c.upper()] > 0:
			who += 1
			counts[c.upper()] -= 1
	print(yay, who)
main()


s = input()
t = input()
scount = []
tcount = []
yay = 0
whoop = 0
for i in range(130):
	scount.append(0)
	tcount.append(0)
for i in range(len(s)):
	scount[ord(s[i])] += 1
for i in range(len(t)):
	tcount[ord(t[i])] += 1
for i in range(ord('a'), ord('z') + 1):
	lowmin = min(scount[i], tcount[i])
	upmin = min(scount[ord(chr(i).upper())], tcount[ord(chr(i).upper())])
	yay += lowmin + upmin
	scount[i] -= lowmin
	tcount[i] -= lowmin
	scount[ord(chr(i).upper())] -= upmin
	tcount[ord(chr(i).upper())] -= upmin
	whoop += min(scount[i], tcount[ord(chr(i).upper())]) + min(scount[ord(chr(i).upper())], tcount[i])
print(yay, whoop)


import sys
input = sys.stdin.readline
read_tuple = lambda _type: map(_type, input().split(' '))
from collections import Counter

def change_case(letter):
	if letter.islower():
		return letter.upper()
	else:
		return letter.lower()

def solve():
	message = dict(Counter(input().replace('\n', '')))
	paper = dict(Counter(input().replace('\n', '')))
	(h, o) = (0, 0)
	for letter in message:
		if letter in paper:
			diff = min(message[letter], paper[letter])
			h += diff
			message[letter] -= diff
			paper[letter] -= diff
	for letter in message:
		cased = change_case(letter)
		if cased in paper:
			diff = min(message[letter], paper[cased])
			o += diff
			message[letter] -= diff
			paper[cased] -= diff
	print(f'{h} {o}')
solve()


(s, t) = (input(), input())
(yay, whoops) = (0, 0)
(a, b) = ({}, {})
for i in s:
	a[i] = a.get(i, 0) + 1
for i in t:
	b[i] = b.get(i, 0) + 1
for i in a:
	if i not in b:
		continue
	tmp = min(a[i], b[i])
	yay += tmp
	a[i] -= tmp
	b[i] -= tmp
for i in a:
	if i.swapcase() not in b:
		continue
	tmp = min(a[i], b[i.swapcase()])
	whoops += tmp
	a[i] -= tmp
	b[i.swapcase()] -= tmp
print(yay, whoops)


s = list(input())
t = list(input())
count = {}
ans1 = 0
ans2 = 0
for i in range(len(s)):
	a = str.lower(s[i])
	b = str.upper(s[i])
	count[a] = count[b] = 0
for i in range(len(t)):
	a = t[i]
	count[a] = 0
for i in range(len(t)):
	a = t[i]
	count[a] += 1
l = []
for i in range(len(s)):
	a = s[i]
	if count[a] > 0:
		ans1 += 1
		count[a] -= 1
	else:
		l.append(a)
li = l
for i in range(len(li)):
	a = li[i]
	b = str.lower(li[i])
	c = str.upper(li[i])
	if a == b:
		if count[c] > 0:
			ans2 += 1
			count[c] -= 1
	elif count[b] > 0:
		ans2 += 1
		count[b] -= 1
print(ans1, ans2)


s = input()
t = input()
n = len(s)
yay = 0
whoops = 0
dict = {}
for c in s:
	if c in dict:
		dict[c] += 1
	else:
		dict[c] = 1
t2 = ''
for c in t:
	if c in dict:
		yay += 1
		dict[c] -= 1
		if dict[c] == 0:
			del dict[c]
	else:
		t2 += c
for c in t2:
	if c.islower():
		c = c.upper()
	else:
		c = c.lower()
	if c in dict:
		whoops += 1
		dict[c] -= 1
		if dict[c] == 0:
			del dict[c]
print('{0} {1}'.format(yay, whoops))


s = input()
t = input()
yay = 0
whoops = 0
dic = {}
resto = ''

def inverter(c):
	if c.isupper():
		return c.lower()
	else:
		return c.upper()
for c in t:
	try:
		dic[c] += 1
	except:
		dic[c] = 1
for c in s:
	try:
		if dic[c] > 0:
			dic[c] -= 1
			yay += 1
		else:
			resto += c
	except:
		resto += c
for c in resto:
	cInvertido = inverter(c)
	try:
		if dic[cInvertido] > 0:
			dic[cInvertido] -= 1
			whoops += 1
	except:
		continue
print(yay, whoops)


import sys
from functools import lru_cache, cmp_to_key
from heapq import merge, heapify, heappop, heappush
from math import *
from collections import defaultdict as dd, deque, Counter as C
from itertools import combinations as comb, permutations as perm
from bisect import bisect_left as bl, bisect_right as br, bisect
from time import perf_counter
from fractions import Fraction
import copy
import time
starttime = time.time()
mod = int(pow(10, 9) + 7)
mod2 = 998244353

def data():
	return sys.stdin.readline().strip()

def out(*var, end='\n'):
	sys.stdout.write(' '.join(map(str, var)) + end)

def L():
	return list(sp())

def sl():
	return list(ssp())

def sp():
	return map(int, data().split())

def ssp():
	return map(str, data().split())

def l1d(n, val=0):
	return [val for i in range(n)]

def l2d(n, m, val=0):
	return [l1d(n, val) for j in range(m)]
try:
	sys.stdin = open('input.txt', 'r')
except:
	pass

def pmat(A):
	for ele in A:
		print(ele, end='\n')
s = input()
t = input()
cnt = [0] * 300
used = [0] * len(s)
for c in t:
	cnt[ord(c)] += 1
c1 = 0
c2 = 0
for i in range(len(s)):
	c = s[i]
	if cnt[ord(c)] > 0:
		c1 += 1
		cnt[ord(c)] -= 1
		used[i] = 1
for i in range(len(s)):
	c = s[i]
	if used[i] == 0 and cnt[ord(c) ^ 32] > 0:
		c2 += 1
		cnt[ord(c) ^ 32] -= 1
print(c1, c2)
endtime = time.time()


cnt = [0] * 130
s = input()
t = input()
for x in t:
	cnt[ord(x)] += 1
n = len(s)
mark = [True] * n
cnt_Yays = 0
cnt_Whoops = 0
for i in range(n):
	x = s[i]
	if cnt[ord(x)] > 0:
		cnt_Yays += 1
		cnt[ord(x)] -= 1
		mark[i] = False
for i in range(n):
	x = s[i]
	if mark[i] == True:
		if ord(x) >= 97 and cnt[ord(x.upper())] > 0:
			cnt_Whoops += 1
			cnt[ord(x.upper())] -= 1
		if ord(x) < 97 and cnt[ord(x.lower())] > 0:
			cnt_Whoops += 1
			cnt[ord(x.lower())] -= 1
print(cnt_Yays, cnt_Whoops)


s = input()
t = input()
s_letters = dict()
t_letters = dict()
CAPS = 'QWERTYUIOPASDFGHJKLZXCVBNM'
SMALLS = 'qwertyuiopasdfghjklzxcvbnm'
for letter in CAPS:
	s_letters[letter] = 0
	t_letters[letter] = 0
for letter in SMALLS:
	s_letters[letter] = 0
	t_letters[letter] = 0
for letter in s:
	s_letters[letter] += 1
for letter in t:
	t_letters[letter] += 1
hurray = 0
hopa = 0
for i in range(26):
	Letter = CAPS[i]
	letter = SMALLS[i]
	tmp = min(s_letters[Letter], t_letters[Letter])
	hurray += tmp
	s_letters[Letter] -= tmp
	t_letters[Letter] -= tmp
	tmp = min(s_letters[letter], t_letters[letter])
	hurray += tmp
	s_letters[letter] -= tmp
	t_letters[letter] -= tmp
	hopa += min(s_letters[Letter] + s_letters[letter], t_letters[Letter] + t_letters[letter])
print(hurray, hopa)


def main():
	(s, t) = ([0] * 123, [0] * 123)
	for c in input():
		s[ord(c)] += 1
	for c in input():
		t[ord(c)] += 1
	yay = whoops = 0
	for (i, x, y) in zip(range(123), s, t):
		if x > y:
			s[i] = x - y
			t[i] = 0
			yay += y
		else:
			s[i] = 0
			t[i] = y - x
			yay += x
	(t[ord('A'):ord('Z') + 1], t[ord('a'):ord('z') + 1]) = (t[ord('a'):ord('z') + 1], t[ord('A'):ord('Z') + 1])
	for (i, x, y) in zip(range(123), s, t):
		if x > y:
			s[i] = x - y
			t[i] = 0
			whoops += y
		else:
			s[i] = 0
			t[i] = y - x
			whoops += x
	print(yay, whoops)
main()


first = input()
second = input()
dicty = {}
for i in first:
	if i not in dicty:
		dicty[i] = 1
	else:
		dicty[i] += 1
yay = 0
whoops = 0
array_bool = [False for x in second]
for i in range(len(second)):
	if second[i] in dicty and dicty[second[i]] != 0:
		yay += 1
		dicty[second[i]] -= 1
		array_bool[i] = True
for i in range(len(second)):
	if not array_bool[i]:
		if second[i].upper() in dicty and dicty[second[i].upper()] != 0:
			whoops += 1
			dicty[second[i].upper()] -= 1
		elif second[i].lower() in dicty and dicty[second[i].lower()] != 0:
			whoops += 1
			dicty[second[i].lower()] -= 1
print(yay, whoops)


a = list(input())
b = list(input())
cnt = 0
scnt = 0
(a1, b1) = (dict(), dict())
for s in a:
	if s in a1.keys():
		a1[s] += 1
	else:
		a1[s] = 1
for s in b:
	if s in b1.keys():
		b1[s] += 1
	else:
		b1[s] = 1
for s in a1.keys():
	if s in b1.keys():
		if a1[s] < b1[s]:
			cnt += a1[s]
			b1[s] = b1[s] - a1[s]
			a1[s] = 0
		else:
			cnt += b1[s]
			a1[s] = a1[s] - b1[s]
			b1[s] = 0
for s in a1.keys():
	if chr(ord(s) + 32) in b1.keys():
		scnt += min(a1[s], b1[chr(ord(s) + 32)])
	elif chr(ord(s) - 32) in b1.keys():
		scnt += min(a1[s], b1[chr(ord(s) - 32)])
print('%d %d' % (cnt, scnt))


s1 = input()
s2 = input()
ms1 = [0] * 26
ms2 = [0] * 26
ms3 = [0] * 26
ms4 = [0] * 26
m = 0
n = 0
for i in range(len(s1)):
	if ord(s1[i]) in range(ord('A'), ord('Z') + 1):
		ms1[ord(s1[i]) - ord('A')] += 1
	else:
		ms2[ord(s1[i]) - ord('a')] += 1
for i in range(len(s2)):
	if ord(s2[i]) in range(ord('A'), ord('Z') + 1):
		ms3[ord(s2[i]) - ord('A')] += 1
	else:
		ms4[ord(s2[i]) - ord('a')] += 1
for i in range(len(ms1)):
	if ms3[i] and ms1[i]:
		mn = min(ms3[i], ms1[i])
		m += mn
		ms3[i] -= mn
		ms1[i] -= mn
	if ms2[i] and ms4[i]:
		mn = min(ms2[i], ms4[i])
		m += mn
		ms2[i] -= mn
		ms4[i] -= mn
for i in range(len(ms1)):
	if ms3[i] and ms2[i]:
		mn = min(ms2[i], ms3[i])
		n += mn
		ms3[i] -= mn
		ms2[i] -= mn
	if ms1[i] and ms4[i]:
		mn = min(ms1[i], ms4[i])
		n += mn
		ms1[i] -= mn
		ms4[i] -= mn
print(m, n)


s = input()
t = input()
M = {}
for c in t:
	if c not in M:
		M[c] = 0
	M[c] += 1
marked = [False] * len(s)
yay = 0
whoops = 0
for i in range(len(s)):
	c = s[i]
	if marked[i]:
		continue
	if c in M and M[c] > 0:
		yay += 1
		M[c] -= 1
		marked[i] = True
for i in range(len(s)):
	c = s[i]
	if c.islower():
		c = c.upper()
	else:
		c = c.lower()
	if marked[i]:
		continue
	if c in M and M[c] > 0:
		whoops += 1
		M[c] -= 1
		marked[i] = True
print('{} {}'.format(yay, whoops))


from sys import stdin, stdout
from math import ceil, floor

def main():
	yeee = 0
	oops = 0
	s = input()
	t = input()
	code = lambda x: ord(x) - (ord('A') if x.isupper() else ord('a'))
	big = [0] * 32
	small = [0] * 32
	n = len(s)
	ok = [0] * n
	for elem in t:
		if elem.isupper():
			big[code(elem)] += 1
		else:
			small[code(elem)] += 1
	for j in range(n):
		if s[j].isupper():
			if big[code(s[j])] > 0:
				yeee += 1
				ok[j] = 1
				big[code(s[j])] -= 1
		elif small[code(s[j])] > 0:
			yeee += 1
			ok[j] = 1
			small[code(s[j])] -= 1
	for j in range(n):
		if s[j].isupper():
			if small[code(s[j])] > 0 and ok[j] == 0:
				oops += 1
				small[code(s[j])] -= 1
		elif big[code(s[j])] > 0 and ok[j] == 0:
			oops += 1
			big[code(s[j])] -= 1
	print(yeee, oops)
main()


def tanya(s, t):

	def invert(ch):
		if ch.isupper():
			return ch.lower()
		return ch.upper()
	yay = 0
	whoops = 0
	S = {}
	T = {}
	for x in s:
		if x in S:
			S[x] += 1
		else:
			S[x] = 1
	for x in t:
		if x in T:
			T[x] += 1
		else:
			T[x] = 1
	for x in S:
		if x in T:
			if T[x] < S[x]:
				yay += T[x]
				S[x] -= T[x]
				T[x] = 0
			else:
				yay += S[x]
				temp = S[x]
				S[x] = 0
				T[x] = T[x] - temp
		if S[x] < 0:
			S[x] = 0
	for x in S:
		if invert(x) in T:
			if T[invert(x)] < S[x]:
				whoops += T[invert(x)]
			else:
				whoops += S[x]
	print(yay, whoops)
a = input().strip()
b = input().strip()
tanya(a, b)


msg = input()
nwp = input()
aa = [0 for i in range(26)]
bb = [0 for i in range(26)]
cc = [0 for i in range(26)]
dd = [0 for i in range(26)]
for i in msg:
	if ord(i) < 95:
		bb[ord(i) - 65] += 1
	else:
		aa[ord(i) - 97] += 1
for i in nwp:
	if ord(i) < 95:
		dd[ord(i) - 65] += 1
	else:
		cc[ord(i) - 97] += 1
(daba, store) = (0, 0)
(vr, rb) = (0, 0)
for i in range(26):
	vr = min(aa[i], cc[i])
	rb = min(bb[i], dd[i])
	daba += vr
	daba += rb
	store += min(aa[i] + bb[i] - vr - rb, cc[i] + dd[i] - vr - rb)
print(daba, store)


s = input().strip()
t = input().strip()
yay = 0
whoops = 0
yay_map = [0] * 58
whoops_map = [] * 58
slength = len(s)
tlength = len(t)
s_map = [0] * 58
t_map = [0] * 58
up_low_distance = 32
for i in range(slength):
	s_map[ord(s[i]) - 65] += 1
for i in range(tlength):
	t_map[ord(t[i]) - 65] += 1
for i in range(26):
	if t_map[i] >= s_map[i]:
		yay += s_map[i]
		t_map[i] -= s_map[i]
		s_map[i] = 0
	else:
		yay += t_map[i]
		s_map[i] -= t_map[i]
		t_map[i] = 0
	if t_map[i + up_low_distance] >= s_map[i + up_low_distance]:
		yay += s_map[i + up_low_distance]
		t_map[i + up_low_distance] -= s_map[i + up_low_distance]
		s_map[i + up_low_distance] = 0
	else:
		yay += t_map[i + up_low_distance]
		s_map[i + up_low_distance] -= t_map[i + up_low_distance]
		t_map[i + up_low_distance] = 0
	if t_map[i] >= s_map[i + up_low_distance]:
		whoops += s_map[i + up_low_distance]
		t_map[i] -= s_map[i + up_low_distance]
		s_map[i + up_low_distance] = 0
	else:
		whoops += t_map[i]
		s_map[i + up_low_distance] -= t_map[i]
		t_map[i] = 0
	if t_map[i + up_low_distance] >= s_map[i]:
		whoops += s_map[i]
		t_map[i + up_low_distance] -= s_map[i]
		s_map[i] = 0
	else:
		whoops += t_map[i + up_low_distance]
		s_map[i] -= t_map[i + up_low_distance]
		t_map[i + up_low_distance] = 0
print(yay, whoops)


from collections import Counter
s = list(input())
t = list(input())
x = Counter(s)
y = Counter(t)
(a, b) = (0, 0)
for i in x:
	if i in y:
		f = min(x[i], y[i])
		x[i] -= f
		y[i] -= f
		a += f
for i in x:
	if ord(i) <= 90:
		c = chr(ord(i) + 32)
		if c in y:
			b += min(x[i], y[c])
	else:
		z = chr(ord(i) - 32)
		if z in y:
			b += min(x[i], y[z])
print(a, b)


from collections import Counter
s = input()
t = input()
sc = Counter(s)
tc = Counter(t)
FLIP_CASE = ord('a') - ord('A')
(yay, whoops) = (0, 0)
for c in s:
	amount = min(sc[c], tc[c])
	if amount > 0:
		yay += amount
		tc[c] -= amount
		sc[c] -= amount
for c in sc:
	fc = chr(FLIP_CASE ^ ord(c))
	amount = min(sc[c], tc[fc])
	if amount > 0:
		whoops += amount
		tc[fc] -= amount
print(yay, whoops)


from functools import reduce
import os
import sys
from collections import *
from decimal import *
from math import *
from bisect import *
from heapq import *
from io import BytesIO, IOBase
input = lambda : sys.stdin.readline().rstrip('\r\n')

def value():
	return tuple(map(int, input().split()))

def arr():
	return [int(i) for i in input().split()]

def sarr():
	return [int(i) for i in input()]

def starr():
	return [str(x) for x in input().split()]

def inn():
	return int(input())

def svalue():
	return tuple(map(str, input().split()))

def parr():
	return [value() for i in range(n)]

def Ceil(a, b):
	return a // b + int(a % b > 0)
albhabet = 'abcdefghijklmnopqrstuvwxyz'
mo = 1000000007
inf = 1e+18
div = 998244353
s1 = [str(x) for x in input()]
s2 = input()
d = defaultdict(int)
for i in s2:
	d[i] += 1
(yes, no) = (0, 0)
for i in range(len(s1)):
	if d[s1[i]] > 0:
		yes += 1
		d[s1[i]] -= 1
		s1[i] = '-1'
for i in s1:
	if i != '-1':
		val1 = chr(ord(i) - 32)
		val2 = chr(ord(i) + 32)
		if d[val1]:
			no += 1
			d[val1] -= 1
		elif d[val2]:
			no += 1
			d[val2] -= 1
print(yes, no)


from collections import Counter
s = input()
t = input()
yay = 0
whoops = 0
counter_s = Counter(s)
counter_t = Counter(t)
for i in s:
	if counter_t[i] > 0:
		counter_s[i] -= 1
		counter_t[i] -= 1
		yay += 1
for i in s:
	if counter_s[i] > 0 and counter_t[i.swapcase()] > 0:
		counter_s[i] -= 1
		counter_t[i.swapcase()] -= 1
		whoops += 1
print(yay, whoops)


(s, t) = (input(), input())
(a1, a2) = (list(s), list(t))
(r1, r2) = (0, 0)
for i in range(ord('a'), ord('z') + 1, 1):
	l1 = a1.count(chr(i))
	l2 = a2.count(chr(i))
	u1 = a1.count(chr(i + ord('A') - ord('a')))
	u2 = a2.count(chr(i + ord('A') - ord('a')))
	c = min(l1, l2) + min(u1, u2)
	r1 += c
	r2 += min(l2 + u2, l1 + u1) - c
print(r1, r2)


def foo():
	s = input()
	d = {}
	for key in s:
		d[key] = d.get(key, 0) + 1
	return d

def f(s):
	d = {}
	for key in s.keys():
		if ord(key) > ord('Z'):
			c = chr(ord(key) - ord('a') + ord('A'))
			d[c] = d.get(c, 0) + s[key]
		else:
			d[key] = d.get(key, 0) + s[key]
	return d
s = foo()
t = foo()
yr = 0
op = 0
for key in s.keys():
	element = min(s[key], t.get(key, 0))
	yr += element
	s[key] -= element
	if t.get(key):
		t[key] -= element
s = f(s)
t = f(t)
for key in s.keys():
	element = min(s[key], t.get(key, 0))
	op += element
	s[key] -= element
	if t.get(key):
		t[key] -= element
print(yr, op)


s1 = input()
s2 = input()
a = [0] * 52
b = [0] * 52
for ch in s1:
	if 'a' <= ch <= 'z':
		index = ord(ch) - ord('a')
	else:
		index = ord(ch) - ord('A') + 26
	a[index] += 1
for ch in s2:
	if 'a' <= ch <= 'z':
		index = ord(ch) - ord('a')
	else:
		index = ord(ch) - ord('A') + 26
	b[index] += 1
ans1 = ans2 = 0
for i in range(52):
	min_number = min(a[i], b[i])
	ans1 += min_number
	a[i] -= min_number
	b[i] -= min_number
for i in range(52):
	if i < 26:
		ans2 += min(a[i], b[i + 26])
	else:
		ans2 += min(a[i], b[i - 26])
print(ans1, ans2)


s = input()
t = input()
c = -ord('A') + ord('a')
ura = 0
opa = 0
s2 = set()
ind = set()
s1 = dict()
for i in range(len(s)):
	if ord(s[i]) not in s2:
		s2.add(ord(s[i]))
		s1[ord(s[i])] = 1
	else:
		s1[ord(s[i])] += 1
for i in range(len(t)):
	if ord(t[i]) in s2 and s1[ord(t[i])] >= 1:
		s1[ord(t[i])] -= 1
		ura += 1
		ind.add(i)
for i in range(len(t)):
	if i not in ind:
		if ord('z') >= ord(t[i]) >= ord('a'):
			if ord(t[i]) - c in s2 and s1[ord(t[i]) - c] >= 1:
				opa += 1
				s1[ord(t[i]) - c] -= 1
				ind.add(i)
		elif ord(t[i]) + c in s2 and s1[ord(t[i]) + c] >= 1:
			opa += 1
			s1[ord(t[i]) + c] -= 1
			ind.add(i)
print(ura, opa)


from collections import Counter
s1 = input()
s2 = input()
d1 = Counter(s1)
d2 = Counter(s2)
ans1 = 0
ans2 = 0
for e in d1:
	n1 = d1[e]
	if e in d2:
		n2 = d2[e]
		if n2 >= n1:
			ans1 = ans1 + n1
			d2[e] = d2[e] - n1
			d1[e] = 0
		else:
			ans1 = ans1 + n2
			d2[e] = 0
			d1[e] = d1[e] - n2
	else:
		pass
for e in d1:
	n1 = d1[e]
	e = e.swapcase()
	if e in d2:
		n2 = d2[e]
		ans2 = ans2 + min(n1, n2)
		d2[e] = d2[e] - min(n1, n2)
	else:
		pass
print(ans1, ans2)


s = list(input())
t = list(input())
cnt = dict()
for ch in t:
	if not ch in cnt:
		cnt[ch] = 1
	else:
		cnt[ch] = cnt[ch] + 1
yay = 0
check = [False] * len(s)
for i in range(len(s)):
	ch = s[i]
	if ch in cnt and cnt[ch] > 0:
		cnt[ch] -= 1
		check[i] = True
		yay += 1
whoops = 0
for i in range(len(s)):
	if not check[i]:
		if s[i].islower() == True:
			ch = s[i].upper()
		elif s[i].isupper() == True:
			ch = s[i].lower()
		if ch in cnt and cnt[ch] > 0:
			cnt[ch] -= 1
			check[i] = True
			whoops += 1
print(yay, whoops)


__author__ = 'PrimuS'
s = input()
t = input()
sd = {}
td = {}
for x in s:
	sd[x] = sd.get(x, 0) + 1
for x in t:
	td[x] = td.get(x, 0) + 1
res1 = 0
res2 = 0
for x in sd.keys():
	if x not in td:
		continue
	k = min(sd[x], td[x])
	res1 += k
	sd[x] -= k
	td[x] -= k
for x in sd.keys():
	if x.islower():
		y = x.upper()
	else:
		y = x.lower()
	if y not in td:
		continue
	k = min(sd[x], td[y])
	sd[x] -= k
	td[y] -= k
	res2 += k
print(res1, res2)


m = {a: 0 for a in 'qwertyuiopasdfghjklzxcvbnmQWERTYUIOPLKJHGFDSAZXCVBNM'}
m1 = {a: 0 for a in 'qwertyuiopasdfghjklzxcvbnmQWERTYUIOPLKJHGFDSAZXCVBNM'}
(t, s) = (input(), input())
for i in range(len(t)):
	m[t[i]] += 1
for i in range(len(s)):
	m1[s[i]] += 1
ura = 0
opa = 0
for a in 'qwertyuiopasdfghjklzxcvbnmQWERTYUIOPLKJHGFDSAZXCVBNM':
	if m[a] == 0 or m1[a] == 0:
		continue
	temple = min(m[a], m1[a])
	ura += temple
	m[a] -= temple
	m1[a] -= temple
print(ura, end=' ', sep='')
for a in 'qwertyuiopasdfghjklzxcvbnm':
	opa += min(m[a] + m[a.upper()], m1[a] + m1[a.upper()])
print(opa)


a = input()
mapa = {}
per = 0
imp = 0
for i in a:
	if i in mapa:
		mapa[i] += 1
	else:
		mapa[i] = 1
b = input()
c = []
for i in b:
	if i in mapa:
		if mapa[i] != 0:
			mapa[i] -= 1
			per += 1
			c.append(True)
		else:
			c.append(False)
	else:
		c.append(False)
for i in range(len(b)):
	k = b[i]
	if not c[i]:
		k = k.lower() if k.isupper() else k.upper()
		if k in mapa:
			if mapa[k] != 0:
				mapa[k] -= 1
				imp += 1
print(per, imp)


from collections import defaultdict
s = input()
t = input()
dic = defaultdict(int)
for i in t:
	dic[i] += 1
(yay, whoop) = (0, 0)
ans = [-1] * len(s)
for i in range(len(s)):
	if dic[s[i]] > 0:
		ans[i] = 0
		yay += 1
		dic[s[i]] -= 1
for i in range(len(s)):
	if dic[s[i].swapcase()] > 0 and ans[i] == -1:
		whoop += 1
		dic[s[i].swapcase()] -= 1
print(yay, whoop)


from collections import Counter
lettters = [chr(ord('A') + i) for i in range(26)] + [chr(ord('a') + i) for i in range(26)]
s = Counter(input())
t = Counter(input())
yay = 0
whoops = 0
tmp = Counter()
for lettter in lettters:
	tmp[lettter] = min(s[lettter], t[lettter])
s -= tmp
t -= tmp
yay += sum(tmp.values())
tmp = Counter()
for lettter in lettters[:26]:
	tmp[lettter] = min(s[lettter.lower()], t[lettter])
	tmp[lettter.lower()] = min(s[lettter.lower()], t[lettter])
s -= tmp
t -= tmp
whoops += sum(tmp.values()) // 2
tmp = Counter()
for lettter in lettters[26:]:
	tmp[lettter] = min(s[lettter.upper()], t[lettter])
	tmp[lettter.upper()] = min(s[lettter.upper()], t[lettter])
s -= tmp
t -= tmp
whoops += sum(tmp.values()) // 2
print(yay, whoops)


s = input()
t = input()
a = [0] * 26
A = [0] * 26
b = [0] * 26
B = [0] * 26
for i in s:
	o = ord(i)
	if o >= 97:
		a[o - 97] += 1
	else:
		A[o - 65] += 1
for i in t:
	o = ord(i)
	if o >= 97:
		b[o - 97] += 1
	else:
		B[o - 65] += 1
ura = 0
opa = 0
for i in range(26):
	u1 = 0
	o1 = 0
	c = a[i]
	C = A[i]
	d = b[i]
	D = B[i]
	m = min(c, d)
	u1 += m
	c -= m
	d -= m
	m = min(c, D)
	o1 += m
	c -= m
	D -= m
	m = min(C, D)
	u1 += m
	C -= m
	D -= m
	m = min(C, d)
	o1 += m
	C -= m
	D -= m
	u2 = 0
	o2 = 0
	c = a[i]
	C = A[i]
	d = b[i]
	D = B[i]
	m = min(C, D)
	u2 += m
	C -= m
	D -= m
	m = min(C, d)
	o2 += m
	C -= m
	D -= m
	m = min(c, d)
	u2 += m
	c -= m
	d -= m
	m = min(c, D)
	o2 += m
	c -= m
	D -= m
	if u1 > u2 or (u1 == u2 and o1 >= o2):
		ura += u1
		opa += o1
	else:
		ura += u2
		opa += o2
print(ura, opa)


from collections import Counter
i1 = input()
i2 = input()
s1 = Counter(i1)
s2 = Counter(i2)
intersect = s1 & s2
s1.subtract(intersect)
s2.subtract(intersect)
opa = Counter(''.join(s1.elements()).lower()) & Counter(''.join(s2.elements()).lower())
print(sum(intersect.values()), sum(opa.values()))


msg = input()
letters = input()
yays = 0
whoops = 0
alphabet = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
rest = []
leaks = []
i = 0
for l in alphabet:
	original = msg.count(l)
	journal = letters.count(l)
	if journal >= original:
		yays += original
		journal -= original
		if len(rest) < 26:
			rest.append(journal)
			leaks.append(0)
		else:
			rest[i % 26] += journal
	else:
		yays += journal
		original -= journal
		if len(leaks) < 26:
			leaks.append(original)
			rest.append(0)
		else:
			leaks[i % 26] += original
	i += 1
for i in range(26):
	if rest[i] > 0 and leaks[i] > 0:
		if rest[i] >= leaks[i]:
			whoops += leaks[i]
		else:
			whoops += rest[i]
print(yays, whoops)


import math
t = 1
for _ in range(t):
	msg = input()
	news = input()
	newsdict = dict()
	for i in news:
		a = newsdict.get(i, 0)
		newsdict[i] = a + 1
	yay = 0
	remainingdict = dict()
	for i in msg:
		a = newsdict.get(i, 0)
		if a > 0:
			newsdict[i] -= 1
			yay += 1
		else:
			b = remainingdict.get(i, 0)
			remainingdict[i] = b + 1
	whoops = 0
	for i in remainingdict.keys():
		char = i
		othercase = i.swapcase()
		c = newsdict.get(othercase, 0)
		if c > 0:
			whoops += min(remainingdict[i], newsdict[othercase])
	print(yay, whoops)


(a, b) = (input(), input())
from collections import Counter
aa = Counter(a)
bb = Counter(b)
a = list(a)
b = list(b)
(ura, opa) = (0, 0)
swop = lambda s: s.upper() if s.islower() else s.lower()
for i in range(len(a)):
	if bb.get(a[i], 0) > 0:
		ura += 1
		bb[a[i]] -= 1
		a[i] = '#'
for c in a:
	if bb.get(swop(c), 0) > 0:
		opa += 1
		bb[swop(c)] -= 1
print(ura, opa)


def count_letters(word):
	count = {}
	for letter in word:
		count[letter] = count.get(letter, 0) + 1
	return count
s = input()
t = input()
count_s = count_letters(s)
count_t = count_letters(t)
yays = 0
whoopsies = 0
for letter in count_s:
	matches = min(count_s[letter], count_t.get(letter, 0))
	if matches > 0:
		yays += matches
		count_s[letter] -= matches
		count_t[letter] -= matches
for letter in count_s:
	if count_s[letter] > 0:
		matches_upper = min(count_s[letter], count_t.get(letter.upper(), 0))
		if matches_upper > 0:
			whoopsies += matches_upper
			count_s[letter] -= matches_upper
			count_t[letter.upper()] -= matches_upper
		matches_lower = min(count_s[letter], count_t.get(letter.lower(), 0))
		if matches_lower > 0:
			whoopsies += matches_lower
			count_s[letter] -= matches_lower
			count_t[letter.lower()] -= matches_lower
print('%s %s' % (yays, whoopsies))


s = input()
d = dict()
t = input()
for x in t:
	if x in d:
		d[x] += 1
	else:
		d[x] = 1
yay = 0
whoops = 0
mark = [True] * len(s)
i = -1
for x in s:
	i += 1
	if x in d:
		d[x] -= 1
		yay += 1
		if d[x] == 0:
			d.pop(x)
		mark[i] = False
i = -1
for x in s:
	i += 1
	if mark[i] == True:
		if x.islower():
			temp = chr(ord(x) - 32)
			if temp in d:
				whoops += 1
				d[temp] -= 1
				if d[temp] == 0:
					d.pop(temp)
		if x.isupper():
			temp = chr(ord(x) + 32)
			if temp in d:
				whoops += 1
				d[temp] -= 1
				if d[temp] == 0:
					d.pop(temp)
print(yay, whoops)


def invert_case(c):
	if c.isupper():
		return c.lower()
	return c.upper()
letters = {c: 0 for c in 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'}
whoops = 0
yay = 0
message = list(input())
newspaper = list(input())
for c in newspaper:
	letters[c] += 1
for i in range(len(message)):
	if letters[message[i]] > 0:
		letters[message[i]] -= 1
		message[i] = '.'
		yay += 1
for i in range(len(message) - 1, -1, -1):
	if message[i] == '.':
		message.pop(i)
for c in message:
	if letters[invert_case(c)] > 0:
		letters[invert_case(c)] -= 1
		whoops += 1
print(yay, whoops)


A = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
a = A.swapcase()
Al = A + a
numS = [0 for i in Al]
numT = [0 for i in Al]
numT_ = [0 for i in Al]
s = input()
t = input()
t_ = t.swapcase()
yay = 0
whoops = 0
for i in range(len(Al)):
	numS[i] = s.count(Al[i])
	numT[i] = t.count(Al[i])
	numT_[i] += t_.count(Al[i])
	yay += min(numS[i], numT[i])
	if i <= 25:
		k = i + 26
	else:
		k = i - 26
	numT_[k] -= min(numS[i], numT[i])
	numS[i] -= min(numS[i], numT[i])
for i in range(len(Al)):
	whoops += min(numS[i], numT_[i])
print(yay, whoops)


s = input().strip()
t = input().strip()
count_s = [0] * 100
count_t = [0] * 100
(ans1, ans2) = [0, 0]
for i in range(len(t)):
	count_t[ord(t[i]) - ord('A')] += 1
for i in range(len(s)):
	count_s[ord(s[i]) - ord('A')] += 1
for i in range(58):
	Min = min(count_s[i], count_t[i])
	count_s[i] -= Min
	count_t[i] -= Min
	ans1 += Min
for i in range(58):
	Min = min(count_s[i], count_t[(i + 32) % 64])
	count_s[i] -= Min
	count_t[(i + 32) % 64] -= Min
	ans2 += Min
print(ans1, ans2)


alpha = 'abcdefghijklmnopqrstuvwxyz'
alpha += alpha.upper()
h1 = {i: 0 for i in alpha}
h2 = {i: 0 for i in alpha}
for i in input(''):
	h1[i] += 1
for i in input(''):
	h2[i] += 1
y = w = 0
for i in alpha:
	y += min(h1[i], h2[i])
	(h1[i], h2[i]) = (max(0, h1[i] - h2[i]), max(0, h2[i] - h1[i]))
for i in alpha:
	j = i.upper() if i.islower() else i.lower()
	w += min(h1[i], h2[j])
	(h1[i], h2[j]) = (max(0, h1[i] - h2[j]), max(0, h2[j] - h1[i]))
print('{} {}'.format(y, w))


s = set()
sc = set()
t = set()
tc = set()
ms = []
mt = []
for letter in input():
	if letter == letter.lower():
		s.add(letter)
	else:
		sc.add(letter.lower())
	if letter not in ms:
		ms.append(letter)
		ms.append(1)
	else:
		ms[ms.index(letter) + 1] += 1
for letter in input():
	if letter == letter.lower():
		t.add(letter)
	else:
		tc.add(letter.lower())
	if letter not in mt:
		mt.append(letter)
		mt.append(1)
	else:
		mt[mt.index(letter) + 1] += 1
y = 0
w = 0
for letter in s.intersection(t):
	a = ms[ms.index(letter) + 1]
	b = mt[mt.index(letter) + 1]
	rs = set()
	rt = set()
	if a == b:
		y += a
		(ms[ms.index(letter) + 1], mt[mt.index(letter) + 1]) = (0, 0)
		rs.add(letter)
		rt.add(letter)
	elif a > b:
		y += b
		(ms[ms.index(letter) + 1], mt[mt.index(letter) + 1]) = (ms[ms.index(letter) + 1] - mt[mt.index(letter) + 1], 0)
		rt.add(letter)
	else:
		y += a
		(ms[ms.index(letter) + 1], mt[mt.index(letter) + 1]) = (0, mt[mt.index(letter) + 1] - ms[ms.index(letter) + 1])
		rs.add(letter)
	(s, t) = (s - rs, t - rt)
for letter in sc.intersection(tc):
	letter = letter.upper()
	a = ms[ms.index(letter) + 1]
	b = mt[mt.index(letter) + 1]
	rsc = set()
	rtc = set()
	if a == b:
		y += a
		(ms[ms.index(letter) + 1], mt[mt.index(letter) + 1]) = (0, 0)
		rsc.add(letter.lower())
		rtc.add(letter.lower())
	elif a > b:
		y += b
		(ms[ms.index(letter) + 1], mt[mt.index(letter) + 1]) = (ms[ms.index(letter) + 1] - mt[mt.index(letter) + 1], 0)
		rtc.add(letter.lower())
	else:
		y += a
		(ms[ms.index(letter) + 1], mt[mt.index(letter) + 1]) = (0, mt[mt.index(letter) + 1] - ms[ms.index(letter) + 1])
		rsc.add(letter.lower())
	(sc, tc) = (sc - rsc, tc - rtc)
for letter in sc.intersection(t):
	a = ms[ms.index(letter.upper()) + 1]
	b = mt[mt.index(letter) + 1]
	rsc = set()
	rt = set()
	if a == b:
		w += a
		rsc.add(letter)
		rt.add(letter)
	elif a > b:
		w += b
		rt.add(letter)
	else:
		w += a
		rsc.add(letter)
	(sc, t) = (sc - rsc, t - rt)
for letter in s.intersection(tc):
	a = ms[ms.index(letter) + 1]
	b = mt[mt.index(letter.upper()) + 1]
	rs = set()
	rtc = set()
	if a == b:
		w += a
		rs.add(letter)
		rtc.add(letter)
	elif a > b:
		w += b
		rtc.add(letter)
	else:
		w += a
		rs.add(letter)
	(s, tc) = (s - rs, tc - rtc)
print(y, w)


st = input()
d = {}
match = {}
for i in range(26):
	d[chr(i + 65)] = 0
	d[chr(i + 97)] = 0
	match[chr(i + 65)] = chr(i + 97)
	match[chr(i + 97)] = chr(i + 65)
for i in input():
	d[i] += 1
ans1 = ans2 = 0
remain = ''
for i in st:
	if d[i] > 0:
		ans1 += 1
		d[i] -= 1
	else:
		remain += i
for i in remain:
	i = match[i]
	if d[i] > 0:
		ans2 += 1
		d[i] -= 1
print(ans1, ans2)


from collections import Counter
s_set = Counter(input())
t_set = Counter(input())
yay_count = 0
whoops_count = 0
for s in s_set.keys():
	if s in t_set:
		num_to_remove = min(s_set[s], t_set[s])
		s_set[s] -= num_to_remove
		t_set[s] -= num_to_remove
		yay_count += num_to_remove

def flip_case(c):
	if c in 'abcdefghijklmnopqrstuvwxyz':
		return c.upper()
	else:
		return c.lower()
for s in s_set.keys():
	S = flip_case(s)
	if S in t_set:
		num_to_remove = min(s_set[s], t_set[S])
		s_set[s] -= num_to_remove
		t_set[S] -= num_to_remove
		whoops_count += num_to_remove
print(yay_count, whoops_count)


entrada1 = input()
entrada2 = input()
masc1 = [0] * 30
masc2 = [0] * 30
minc1 = [0] * 30
minc2 = [0] * 30
for letra in entrada1:
	if letra.islower():
		minc1[ord(letra) - ord('a')] += 1
	else:
		masc1[ord(letra) - ord('A')] += 1
for letra in entrada2:
	if letra.islower():
		minc2[ord(letra) - ord('a')] += 1
	else:
		masc2[ord(letra) - ord('A')] += 1
yay = 0
whoops = 0
for i in range(len(masc1)):
	caso = min(masc1[i], masc2[i])
	yay += caso
	masc1[i] -= caso
	masc2[i] -= caso
	caso = min(minc1[i], minc2[i])
	yay += caso
	minc1[i] -= caso
	minc2[i] -= caso
	whoops += min(masc1[i], minc2[i])
	whoops += min(minc1[i], masc2[i])
print(yay, whoops)


from collections import Counter as C
F = lambda s, t: sum((C(s) & C(t)).values())
(s, t) = (input(), input())
(n, m) = (F(s, t), F(s.lower(), t.lower()))
print(n, m - n)


from collections import Counter
s1 = input()
s2 = input()
a = Counter(s1)
b = Counter(s2)
total1 = 0
total2 = 0
for i in a:
	if i in b:
		x = min(a[i], b[i])
		a[i] -= x
		b[i] -= x
		total1 += x
for i in a:
	if ord(i) <= 90:
		x = chr(ord(i) + 32)
		if x in b:
			total2 += min(a[i], b[x])
	else:
		x = chr(ord(i) - 32)
		if x in b:
			total2 += min(a[i], b[x])
print(total1, total2)


def to_dict(text):
	out = {}
	for letter in text:
		out[letter] = out.get(letter, 0) + 1
	return out
s = input()
t = input()
parsed_s = to_dict(s)
parsed_t = to_dict(t)
yays = 0
for letter in parsed_s:
	matches = min(parsed_s[letter], parsed_t.get(letter, 0))
	if matches > 0:
		yays += matches
		parsed_s[letter] -= matches
		parsed_t[letter] -= matches
whoopses = 0
for letter in parsed_s:
	missing = parsed_s[letter]
	if missing > 0:
		if letter.islower():
			matches = min(missing, parsed_t.get(letter.upper(), 0))
			if matches > 0:
				whoopses += matches
				parsed_s[letter] -= matches
				parsed_t[letter.upper()] -= matches
		else:
			matches = min(missing, parsed_t.get(letter.lower(), 0))
			if matches > 0:
				whoopses += matches
				parsed_s[letter] -= matches
				parsed_t[letter.lower()] -= matches
print('%s %s' % (yays, whoopses))


s1 = input()
s2 = input()
TAM = 26
a_min = ord('a')
a_mai = ord('A')
ls1_min = [0] * TAM
ls1_mai = [0] * TAM
ls2_min = [0] * TAM
ls2_mai = [0] * TAM
for letra in s1:
	if letra.islower():
		ls1_min[ord(letra) - a_min] += 1
	else:
		ls1_mai[ord(letra) - a_mai] += 1
for letra in s2:
	if letra.islower():
		ls2_min[ord(letra) - a_min] += 1
	else:
		ls2_mai[ord(letra) - a_mai] += 1
yay = 0
whoops = 0
for letra in range(TAM):
	casos = min(ls1_min[letra], ls2_min[letra])
	yay += casos
	ls1_min[letra] -= casos
	ls2_min[letra] -= casos
	casos = min(ls1_mai[letra], ls2_mai[letra])
	yay += casos
	ls1_mai[letra] -= casos
	ls2_mai[letra] -= casos
for letra in range(TAM):
	casos = min(ls1_min[letra], ls2_mai[letra])
	casos += min(ls1_mai[letra], ls2_min[letra])
	whoops += casos
print(yay, whoops)


s = input()
t = input()
(kek, lol) = (dict(), dict())
for x in s:
	kek[x] = kek.get(x, 0) + 1
for x in t:
	lol[x] = lol.get(x, 0) + 1
(res11, res2) = (0, 0)
for x in kek:
	val = min(kek[x], lol.get(x, 0))
	res11 += val
	kek[x] -= val
	lol[x] = lol.get(x, 0) - val
for x in kek:
	if 'a' <= x <= 'z':
		val = min(kek[x], lol.get(x.upper(), 0))
		res2 += val
		lol[x.upper()] = lol.get(x.upper(), 0) - val
	else:
		val = min(kek[x], lol.get(x.lower(), 0))
		res2 += val
		lol[x.lower()] = lol.get(x.lower(), 0) - val
print(res11, res2)


def main():
	s = input()
	t = input()
	arrS = [0] * 70
	arrT = [0] * 70
	count = 0
	count2 = 0
	n = len(s)
	for x in s:
		arrS[ord(x) - 65] += 1
	for x in t:
		arrT[ord(x) - 65] += 1
	for i in range(60):
		temp = min(arrS[i], arrT[i])
		arrS[i] -= temp
		arrT[i] -= temp
		count += temp
	for i in range(28):
		temp = min(arrS[i], arrT[i + 32])
		arrS[i] -= temp
		arrT[i + 32] -= temp
		count2 += temp
	for i in range(32, 68):
		temp = min(arrS[i], arrT[i - 32])
		arrS[i] -= temp
		arrT[i - 32] -= temp
		count2 += temp
	print(count, count2)
main()


import collections
s = list(input())
t = list(input())
freq_t = collections.Counter(t)
(ans1, ans2) = (0, 0)
for (i, c) in enumerate(s):
	if freq_t[c] > 0:
		ans1 += 1
		s[i] = '-'
		freq_t[c] -= 1
for c in s:
	if c == '-':
		continue
	if c.islower():
		c = c.upper()
	else:
		c = c.lower()
	if freq_t[c] > 0:
		ans2 += 1
		freq_t[c] -= 1
print(ans1, ans2)


from collections import defaultdict

def modinv(n, p):
	return pow(n, p - 2, p)

def main():
	s = input()
	t = input()
	counter_s = defaultdict(lambda : 0)
	counter_t = defaultdict(lambda : 0)
	for c in s:
		counter_s[c] += 1
	for c in t:
		counter_t[c] += 1
	yay = 0
	whoops = 0
	for key in counter_s.keys():
		temp = min(counter_s[key], counter_t[key])
		yay += temp
		counter_s[key] -= temp
		counter_t[key] -= temp
	for key in counter_s.keys():
		c = key.swapcase()
		temp = min(counter_s[key], counter_t[c])
		whoops += temp
		counter_s[key] -= temp
		counter_t[c] -= temp
	print(yay, whoops)
py2 = round(0.5)
if py2:
	from future_builtins import ascii, filter, hex, map, oct, zip
	range = xrange
import os, sys
from io import IOBase, BytesIO
BUFSIZE = 8192

class FastIO(BytesIO):
	newlines = 0

	def __init__(self, file):
		self._file = file
		self._fd = file.fileno()
		self.writable = 'x' in file.mode or 'w' in file.mode
		self.write = super(FastIO, self).write if self.writable else None

	def _fill(self):
		s = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
		self.seek((self.tell(), self.seek(0, 2), super(FastIO, self).write(s))[0])
		return s

	def read(self):
		while self._fill():
			pass
		return super(FastIO, self).read()

	def readline(self):
		while self.newlines == 0:
			s = self._fill()
			self.newlines = s.count(b'\n') + (not s)
		self.newlines -= 1
		return super(FastIO, self).readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.getvalue())
			(self.truncate(0), self.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		if py2:
			self.write = self.buffer.write
			self.read = self.buffer.read
			self.readline = self.buffer.readline
		else:
			self.write = lambda s: self.buffer.write(s.encode('ascii'))
			self.read = lambda : self.buffer.read().decode('ascii')
			self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
main()


from collections import Counter as C
(cs, ct) = (C(input()), C(input()))
m = cs & ct
y = sum(m.values())
(a, b) = (cs - m, ct - m)
a = C(dict(((k.swapcase(), v) for (k, v) in a.items())))
w = sum((a & b).values())
print(y, w)


from collections import Counter
string = input()
newspaper = input()
sc = Counter(string)
nc = Counter(newspaper)
yay = 0
whoops = 0
for (key, value) in sc.items():
	nckey = nc[key]
	if nckey >= value:
		yay += value
		nc[key] -= value
		sc[key] -= value
	elif nckey < value:
		yay += nckey
		nc[key] -= nckey
		sc[key] -= nckey
for (key, value) in sc.items():
	if key.isupper():
		nckeyin = nc[key.lower()]
		if nckeyin >= value:
			whoops += value
			nc[key.lower()] -= value
		else:
			whoops += nckeyin
			nc[key.lower()] = 0
	else:
		nckeyin = nc[key.upper()]
		if nckeyin >= value:
			whoops += value
			nc[key.upper()] -= value
		else:
			whoops += nckeyin
			nc[key.upper()] = 0
print(yay, whoops)


w = 'abcdefghijklmnopqrstuvwxyz'
u = str.upper
(s, t) = ({}, {})
(a, b) = (0, 0)
q = input()
e = input()
for i in w + u(w):
	s[i] = q.count(i)
	t[i] = e.count(i)
	p = min(s[i], t[i])
	a += p
	s[i] -= p
	t[i] -= p
for i in w:
	b += min(s[i] + s[u(i)], t[i] + t[u(i)])
print(a, b)


def muda_case(letra):
	if letra.isupper():
		return letra.lower()
	else:
		return letra.upper()
a = input()
b = input()
contagem1 = {i: 0 for i in a}
contagem2 = {i: 0 for i in b}
for e in a:
	contagem1[e] += 1
for e in b:
	contagem2[e] += 1
YAY = WHOOPS = 0
for e in contagem1:
	if e in contagem2:
		while contagem1[e] > 0 and contagem2[e] > 0:
			YAY += 1
			contagem1[e] -= 1
			contagem2[e] -= 1
for e in contagem1:
	casedLetter = muda_case(e)
	if casedLetter in contagem2:
		while contagem1[e] > 0 and contagem2[casedLetter] > 0:
			WHOOPS += 1
			contagem1[e] -= 1
			contagem2[casedLetter] -= 1
print(YAY, WHOOPS)


import sys
sys.setrecursionlimit(100000)

def reverseCase(a):
	if ord(a) >= ord('A') and ord(a) <= ord('Z'):
		return a.lower()
	else:
		return a.upper()

def main():
	mes = input()
	news = input()
	M = dict()
	(n, m) = (len(mes), len(news))
	yay = oops = 0
	for i in range(n):
		if mes[i] in M:
			M[mes[i]] += 1
		else:
			M[mes[i]] = 1
	mark = [False] * m
	for i in range(m):
		if news[i] in M and M[news[i]] != 0:
			M[news[i]] -= 1
			yay += 1
		else:
			mark[i] = True
	for i in range(m):
		if mark[i]:
			tmp = reverseCase(news[i])
			if tmp in M and M[tmp] != 0:
				M[tmp] -= 1
				oops += 1
	print(yay, oops)
main()


from collections import defaultdict
from string import ascii_lowercase
s = input()
t = input()
cntS = defaultdict(int)
for c in s:
	cntS[c] += 1
cntT = defaultdict(int)
for c in t:
	cntT[c] += 1
nAll = 0
for c in set(s):
	cnt = min(cntS[c], cntT[c])
	cntS[c] -= cnt
	cntT[c] -= cnt
	nAll += cnt
newCntS = defaultdict(int)
newCntT = defaultdict(int)
for c in ascii_lowercase:
	newCntS[c] += cntS[c] + cntS[c.upper()]
	newCntT[c] += cntT[c] + cntT[c.upper()]
nOne = 0
for c in ascii_lowercase:
	nOne += min(newCntS[c], newCntT[c])
print('%d %d' % (nAll, nOne))


msg = input()
nsp = input()
yay = 0
whoops = 0
no_yay = []
nsp_l = {}
for l in set(nsp):
	nsp_l[l] = nsp.count(l)
for c in msg:
	if c in nsp_l.keys() and nsp_l[c] > 0:
		nsp_l[c] -= 1
		yay += 1
	else:
		no_yay.append(c)
for c in no_yay:
	if c.islower():
		if c.upper() in nsp_l.keys() and nsp_l[c.upper()] > 0:
			nsp_l[c.upper()] -= 1
			whoops += 1
	if c.isupper():
		if c.lower() in nsp_l.keys() and nsp_l[c.lower()] > 0:
			nsp_l[c.lower()] -= 1
			whoops += 1
print(yay, whoops)


s = input()
t = input()

def count(s):
	d = {}
	for c in s:
		d[c] = d.get(c, 0) + 1
	return d
dt = count(t)
maxY = 0
maxW = 0
arr = [False] * len(s)
for i in range(len(s)):
	c = s[i]
	if c in dt and dt[c] > 0:
		maxY += 1
		dt[c] -= 1
		arr[i] = True
for i in range(len(s)):
	c = s[i]
	opC = c.lower()
	if opC == c:
		opC = c.upper()
	if opC in dt and dt[opC] > 0 and (arr[i] == False):
		dt[opC] -= 1
		maxW += 1
print(maxY, maxW)


s = input()
t = input()
cnt = [0] * 257
used = [0] * (len(s) + 100)
for i in range(len(t)):
	cnt[ord(t[i])] += 1
res1 = 0
res2 = 0
for i in range(len(s)):
	if cnt[ord(s[i])] > 0:
		cnt[ord(s[i])] -= 1
		res1 += 1
		used[i] = 1
for i in range(len(s)):
	if used[i] == 0:
		if cnt[ord(s[i]) ^ 32] > 0:
			cnt[ord(s[i]) ^ 32] -= 1
			used[i] = 1
			res2 += 1
print(res1, res2)


from collections import Counter
s = list(input())
t = list(input())
ct = Counter(t)
y = w = 0
ans = ''
for i in range(len(s)):
	if ct[s[i]] > 0:
		y += 1
		ct[s[i]] -= 1
	else:
		ans += s[i]
for i in ans:
	if i.islower():
		x = i.upper()
	else:
		x = i.lower()
	if ct[x] > 0:
		w += 1
		ct[x] -= 1
print(y, w)


from collections import Counter
cs = Counter(input())
ct = Counter(input())
cc = ct & cs
a = len(list(cc.elements()))
cs -= cc
ct -= cc
cs = Counter(map(str.upper, cs.elements()))
ct = Counter(map(str.upper, ct.elements()))
cc = ct & cs
b = len(list(cc.elements()))
print(a, b)


s = input()
t = input()
oc = {}
yay = 0
whoops = 0
resto = ''
for l1 in t:
	oc[l1] = oc.get(l1, 0) + 1
for l2 in s:
	if oc.get(l2, 0) > 0:
		oc[l2] -= 1
		yay += 1
	else:
		resto += l2
for l3 in resto:
	aux = l3.swapcase()
	if oc.get(aux, 0) > 0:
		oc[aux] -= 1
		whoops += 1
print(yay, whoops)


s = str(input())
t = str(input())
mapa = {}
yays = 0
whoops = 0
for i in t:
	if i in mapa:
		mapa[i] += 1
	else:
		mapa[i] = 1
other = ''
for i in s:
	if i in mapa and mapa[i] > 0:
		yays += 1
		mapa[i] -= 1
	else:
		other += i
for i in other:
	l = i.lower() if i.isupper() else i.upper()
	if l in mapa and mapa[l] > 0:
		whoops += 1
		mapa[l] -= 1
print(yays, whoops)


def main(s1, s2):

	def flip(c):
		if ord(c) in range(ord('a'), ord('z') + 1):
			return chr(ord('A') - ord('a') + ord(c))
		else:
			return chr(ord('a') - ord('A') + ord(c))
	m = [0 for i in range(256)]
	for c in s2:
		m[ord(c)] += 1
	a = 0
	b = 0
	marked = set()
	for (i, c) in enumerate(s1):
		if m[ord(c)] > 0:
			m[ord(c)] -= 1
			a += 1
			marked.add(i)
	for (i, c) in enumerate(s1):
		if i in marked:
			continue
		if m[ord(flip(c))] > 0:
			m[ord(flip(c))] -= 1
			b += 1
	return '{} {}'.format(a, b)
print(main(input(), input()))


s = input()
t = input()
s = list(s)
d = {}
for i in range(len(t)):
	if t[i] in d:
		d[t[i]] += 1
	else:
		d[t[i]] = 1
(yay, whoop) = (0, 0)
for i in range(len(s)):
	if s[i] in d and d[s[i]] > 0:
		yay += 1
		d[s[i]] -= 1
		s[i] = ' '
for i in range(len(s)):
	if 65 <= ord(s[i]) <= 90:
		x = chr(ord(s[i]) + 32)
	else:
		x = chr(ord(s[i]) - 32)
	if x in d and d[x] > 0:
		whoop += 1
		d[x] -= 1
print(yay, whoop)


from collections import Counter

def to_dict(s):
	d = Counter()
	for c in s:
		d[c] += 1
	return d

def change_case(c):
	if c.islower():
		return c.upper()
	else:
		return c.lower()
yay_total = 0
whoops_total = 0
tanya = to_dict(input())
newspaper = to_dict(input())
for k in tanya:
	curr_yay = min(tanya[k], newspaper[k])
	yay_total += curr_yay
	tanya[k] -= curr_yay
	newspaper[k] -= curr_yay
	k_changed_case = change_case(k)
	curr_yay = min(tanya[k_changed_case], newspaper[k_changed_case])
	yay_total += curr_yay
	if tanya[k_changed_case] > 0:
		tanya[k_changed_case] -= curr_yay
	newspaper[k_changed_case] -= curr_yay
	curr_whoops = min(tanya[k], newspaper[k_changed_case])
	whoops_total += curr_whoops
	tanya[k] -= curr_whoops
	newspaper[k_changed_case] -= curr_whoops
	curr_whoops = min(tanya[k_changed_case], newspaper[k])
	whoops_total += curr_whoops
	if tanya[k_changed_case] > 0:
		tanya[k_changed_case] -= curr_whoops
	newspaper[k] -= curr_whoops
print(yay_total, whoops_total)


import sys
from collections import Counter

def main():
	test = sys.stdin.readlines()
	letter = test[0].strip()
	journal = Counter(test[1].strip())
	a = b = 0
	idx2 = []
	for (i, c) in enumerate(letter):
		if journal[c] > 0:
			a += 1
			journal[c] -= 1
		else:
			idx2.append(i)
	for i in idx2:
		other_case = letter[i].swapcase()
		if journal[other_case] > 0:
			b += 1
			journal[other_case] -= 1
	print(a, b)
main()


s = input()
t = input()
(a, b) = ({}, [])
for i in t:
	if i in a:
		a[i] += 1
	else:
		a[i] = 1
for i in s:
	b.append(i)
(res1, res2) = (0, 0)
for i in range(len(b)):
	if b[i] in a and a[b[i]] > 0:
		res1 += 1
		a[b[i]] -= 1
		b[i] = '0'
for i in b:
	t = i
	if i.islower():
		t = i.upper()
	elif i.isupper():
		t = i.lower()
	if t in a and a[t] > 0:
		res2 += 1
		a[t] -= 1
print(res1, res2)


u = input()
v = input()
a = [0 for i in range(200)]
b = [0 for i in range(200)]
m = 0
n = 0
d = ord('a') - ord('A')
for i in u:
	a[ord(i)] += 1
for i in v:
	b[ord(i)] += 1
for i in range(ord('A'), ord('Z') + 1):
	r = min(a[i], b[i]) + min(a[i + d], b[i + d])
	n += r
	m += min(a[i] + a[i + d], b[i] + b[i + d]) - r
print(n, m)


def solve():
	d = {}
	s = input()
	t = input()
	n = len(s)
	m = len(t)
	for i in range(0, 26):
		d[chr(ord('a') + i)] = 0
		d[chr(ord('A') + i)] = 0
	for i in range(0, m):
		d[t[i]] += 1
	y = 0
	w = 0
	x = [0] * n
	for i in range(0, n):
		if d[s[i]] > 0:
			x[i] = 1
			y += 1
			d[s[i]] -= 1
	for i in range(0, n):
		if x[i]:
			continue
		if ord(s[i]) <= ord('z') and ord(s[i]) >= ord('a'):
			if d[chr(ord(s[i]) - ord('a') + ord('A'))] > 0:
				w += 1
				d[chr(ord(s[i]) - ord('a') + ord('A'))] -= 1
		elif d[chr(ord(s[i]) - ord('A') + ord('a'))] > 0:
			w += 1
			d[chr(ord(s[i]) - ord('A') + ord('a'))] -= 1
	print(y, w)
t = 1
for _ in range(t):
	solve()


message = input()
newspaper = input()
a = dict([(i, 0) for i in range(52)])
b = dict([(i, 0) for i in range(52)])
for ch in message:
	id = ord(ch) - 65
	if ch > 'Z':
		id = ord(ch) - 97 + 26
	if not id in a:
		a[id] = 1
	else:
		a[id] += 1
for ch in newspaper:
	id = ord(ch) - 65
	if ch > 'Z':
		id = ord(ch) - 97 + 26
	if not id in b:
		b[id] = 1
	else:
		b[id] += 1
yay = 0
whoops = 0
for i in range(52):
	tmp = min(a[i], b[i])
	yay += tmp
	a[i] -= tmp
	b[i] -= tmp
for i in range(26):
	whoops += min(a[i], b[i + 26]) + min(a[i + 26], b[i])
print('%d %d' % (yay, whoops))


s = input()
t = input()
ds = {}
for i in range(len(s)):
	key = s[i]
	if key in ds:
		ds[key] += 1
	else:
		ds[key] = 1
dt = {}
for i in range(len(t)):
	key = t[i]
	if key in dt:
		dt[key] += 1
	else:
		dt[key] = 1
(y, w) = (0, 0)
for i in range(len(s)):
	if s[i] in dt and dt[s[i]] > 0:
		dt[s[i]] -= 1
		ds[s[i]] -= 1
		y += 1
for i in range(len(s)):
	if ds[s[i]] > 0:
		if s[i].isupper():
			if s[i].lower() in dt and dt[s[i].lower()] > 0:
				w += 1
				ds[s[i]] -= 1
				dt[s[i].lower()] -= 1
		elif s[i].islower():
			if s[i].upper() in dt and dt[s[i].upper()] > 0:
				w += 1
				ds[s[i]] -= 1
				dt[s[i].upper()] -= 1
print(y, w)


def count_correct_case():
	global dict_s, dict_t
	correctCase = 0
	for char in dict_s:
		if char in dict_t:
			yay = min(dict_s[char], dict_t[char])
			correctCase += yay
			dict_s[char] -= yay
			dict_t[char] -= yay
	return correctCase

def count_wrong_case():
	wrongCase = 0
	for char in dict_s:
		if dict_s[char] > 0:
			if char <= 'Z' and chr(ord(char) + 32) in dict_t:
				wrongCase += min(dict_s[char], dict_t[chr(ord(char) + 32)])
			elif char >= 'a' and chr(ord(char) - 32) in dict_t:
				wrongCase += min(dict_s[char], dict_t[chr(ord(char) - 32)])
	return wrongCase
s = input()
t = input()
dict_s = {}
dict_t = {}
for char in s:
	if not char in dict_s:
		dict_s[char] = 1
	else:
		dict_s[char] += 1
for char in t:
	if not char in dict_t:
		dict_t[char] = 1
	else:
		dict_t[char] += 1
print(count_correct_case(), count_wrong_case())


from collections import Counter
from string import ascii_lowercase as ascii
s = Counter(input())
t = Counter(input())
a = 0
b = 0
for x in ascii:
	lower_need = s[x]
	upper_need = s[x.upper()]
	lower_exist = t[x]
	upper_exist = t[x.upper()]
	x = min(lower_need, lower_exist)
	a += x
	lower_need -= x
	lower_exist -= x
	x = min(upper_need, upper_exist)
	a += x
	upper_need -= x
	upper_exist -= x
	b += min(lower_need + upper_need, lower_exist + upper_exist)
print(a, b)


r = input()
h = input()
r_dic = {}
h_dic = {}
for c in r:
	h_dic[c] = 0
	if c in r_dic:
		r_dic[c] += 1
	else:
		r_dic[c] = 1
for c in h:
	if c in h_dic:
		h_dic[c] += 1
	else:
		h_dic[c] = 1
y = 0
o = 0
for (k, v) in r_dic.items():
	if r_dic[k] > h_dic[k]:
		r_dic[k] -= h_dic[k]
		y += h_dic[k]
		h_dic[k] = 0
	elif r_dic[k] < h_dic[k]:
		h_dic[k] -= r_dic[k]
		y += r_dic[k]
		r_dic[k] = 0
	else:
		y += r_dic[k]
		r_dic[k] = 0
		h_dic[k] = 0
for (k, v) in r_dic.items():
	if r_dic[k] > 0:
		k_t = k
		if k_t.islower():
			tmep_k = k_t.upper()
		else:
			tmep_k = k_t.lower()
		if tmep_k in h_dic:
			if r_dic[k] < h_dic[tmep_k]:
				o += r_dic[k]
				h_dic[tmep_k] -= r_dic[k]
				r_dic[k] = 0
			elif r_dic[k] > h_dic[tmep_k]:
				o += h_dic[tmep_k]
				r_dic[k] -= h_dic[tmep_k]
				h_dic[tmep_k] = 0
			else:
				o += r_dic[k]
				r_dic[k] = 0
				h_dic[tmep_k] = 0
print(y, end=' ')
print(o, end=' ')


from collections import defaultdict

class CodeforcesTask518BSolution:

	def __init__(self):
		self.result = ''
		self.s = ''
		self.t = ''

	def read_input(self):
		self.s = input()
		self.t = input()

	def process_task(self):
		letters = defaultdict(int)
		for c in self.t:
			letters[c] += 1
		yays = 0
		whoops = 0
		done = [0] * len(self.s)
		for x in range(len(self.s)):
			c = self.s[x]
			if letters[c]:
				done[x] = 1
				letters[c] -= 1
				yays += 1
		for x in range(len(self.s)):
			if not done[x]:
				c = self.s[x].swapcase()
				if letters[c]:
					letters[c] -= 1
					whoops += 1
		self.result = f'{yays} {whoops}'

	def get_result(self):
		return self.result
Solution = CodeforcesTask518BSolution()
Solution.read_input()
Solution.process_task()
print(Solution.get_result())


s = input()
t = input()
occur = [0 for i in range(len(s))]
t_freq = {}
for i in t:
	try:
		t_freq[i] += 1
	except:
		t_freq[i] = 1
y_count = 0
w_count = 0
for i in range(len(s)):
	try:
		if t_freq[s[i]] > 0:
			y_count += 1
			t_freq[s[i]] -= 1
			occur[i] = 1
	except:
		pass
for i in range(len(s)):
	try:
		if s[i].islower() and t_freq[s[i].upper()] and (not occur[i]):
			w_count += 1
			t_freq[s[i].upper()] -= 1
	except:
		pass
	try:
		if s[i].isupper() and t_freq[s[i].lower()] and (not occur[i]):
			w_count += 1
			t_freq[s[i].lower()] -= 1
	except:
		pass
print(y_count, w_count)


from collections import *
(s, t) = (deque(input()), input())
(mem, a1, a2) = (Counter(t), 0, 0)
for i in range(len(s)):
	if mem[s[0]]:
		a1 += 1
		mem[s[0]] -= 1
		s.popleft()
	else:
		s.rotate(-1)
for i in s:
	if i.isupper() and mem[i.lower()]:
		a2 += 1
		mem[i.lower()] -= 1
	elif i.islower() and mem[i.upper()]:
		a2 += 1
		mem[i.upper()] -= 1
print(a1, a2)


import sys
from collections import defaultdict

def solve(ts, ns):
	tsDict = defaultdict(int)
	nsDict = defaultdict(int)
	whoops = 0
	yay = 0
	for i in ts:
		tsDict[i] += 1
	for i in ns:
		nsDict[i] += 1
	alphabet = 'abcdefghijklmnopqrstuvwxyz'
	for i in alphabet:
		k = i.upper()
		cutOut = min(tsDict[i], nsDict[i])
		cutOutUpper = min(tsDict[k], nsDict[k])
		yay += cutOut + cutOutUpper
		tsDict[i] -= cutOut
		nsDict[i] -= cutOut
		tsDict[k] -= cutOutUpper
		nsDict[k] -= cutOutUpper
	for i in alphabet:
		k = i.upper()
		remaining = tsDict[i] + tsDict[k]
		available = nsDict[i] + nsDict[k]
		whoops += min(remaining, available)
	return (yay, whoops)

def readinput():
	tanyaString = sys.stdin.readline().rstrip()
	newsp = sys.stdin.readline().rstrip()
	(x, y) = solve(tanyaString, newsp)
	print(x, y)
readinput()


s = input().strip()
t = input().strip()
ls = len(s)
lt = len(t)
d = {}
yays = 0
whoops = 0
missed = []
for c in t:
	if c not in d:
		d[c] = 0
	d[c] += 1
for c in s:
	if c in d and d[c]:
		yays += 1
		d[c] -= 1
	else:
		missed.append(c)
for c in missed:
	k = c.swapcase()
	if k in d and d[k]:
		whoops += 1
		d[k] -= 1
print('{0} {1}'.format(yays, whoops))


x = input()
y = input()
g1 = {}
g2 = {}
g3 = {}
g4 = {}
for i in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ':
	g2[i] = 0
	g4[i] = 0
for i in 'abcdefghijklmnopqrstuvwxyz':
	g1[i] = 0
	g3[i] = 0
e = 0
f = 0
u = []
l = []
u2 = []
l2 = []
for i in x:
	if i in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ':
		u.append(i)
		g2[i] += 1
	else:
		l.append(i)
		g1[i] += 1
for i in y:
	if i in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ':
		u2.append(i)
		g4[i] += 1
	else:
		l2.append(i)
		g3[i] += 1
for i in g1:
	ct = g1[i]
	can = g3[i]
	if ct != 0 and can != 0:
		if ct > can:
			g1[i] = ct - can
			g3[i] = 0
			e += can
		else:
			g3[i] = can - ct
			e += g1[i]
			g1[i] = 0
for i in g2:
	ct = g2[i]
	can = g4[i]
	if ct != 0 and can != 0:
		if ct > can:
			g2[i] = ct - can
			g4[i] = 0
			e += can
		else:
			g4[i] = can - ct
			e += g2[i]
			g2[i] = 0
for i in g1:
	ct = g1[i]
	can = g4[i.upper()]
	if ct != 0 and can != 0:
		if ct > can:
			g1[i] = ct - can
			g4[i.upper()] = 0
			f += can
		else:
			g4[i.upper()] = can - ct
			f += g1[i]
			g1[i] = 0
for i in g2:
	ct = g2[i]
	can = g3[i.lower()]
	if ct != 0 and can != 0:
		if ct > can:
			g2[i] = ct - can
			g3[i.lower()] = 0
			f += can
		else:
			g3[i.lower()] = can - ct
			f += g2[i]
			g2[i] = 0
print(e, f)


from collections import Counter

def main():
	letter = Counter(input())
	journal = Counter(input())
	a = b = 0
	for k in letter:
		d = min(letter[k], journal[k])
		letter[k] -= d
		journal[k] -= d
		a += d
	for k in letter:
		c = k.swapcase()
		d = min(letter[k], journal[c])
		letter[k] -= d
		journal[c] -= d
		b += d
	print(a, b)
main()


def change(x):
	if x == x.upper():
		return x.lower()
	if x == x.lower():
		return x.upper()
(s, t) = (input(), input())
L = [0] * 256
for i in t:
	L[ord(i)] += 1
ans1 = ans2 = 0
P = []
for i in s:
	x = ord(i)
	if L[x] > 0:
		L[x] -= 1
		ans1 += 1
	else:
		P.append(i)
for i in P:
	x = ord(change(i))
	if L[x] > 0:
		L[x] -= 1
		ans2 += 1
print(ans1, ans2)


from collections import Counter

def main():
	letter = input().strip()
	journal = input().strip()
	cnt = Counter(journal)
	a = b = 0
	idx2discard = set()
	for (i, c) in enumerate(letter):
		if cnt[c] > 0:
			a += 1
			cnt[c] -= 1
			idx2discard.add(i)
	for (i, c) in enumerate(letter):
		if i not in idx2discard:
			other_case = c.swapcase()
			if cnt[other_case] > 0:
				b += 1
				cnt[other_case] -= 1
	print(a, b)
main()


s = input()
t = input()
n = len(s)
made = [False] * n
d = dict()
for c in t:
	if c in d:
		d[c] += 1
	else:
		d[c] = 1
yays = whoops = 0
for i in range(n):
	if s[i] in d and d[s[i]] > 0:
		d[s[i]] -= 1
		yays += 1
		made[i] = True
for i in range(n):
	if made[i] == False:
		c = s[i]
		if c.upper() in d and d[c.upper()] > 0:
			d[c.upper()] -= 1
			whoops += 1
		elif c.lower() in d and d[c.lower()] > 0:
			d[c.lower()] -= 1
			whoops += 1
print(yays, whoops)


s = input()
t = input()
visit = list()
lis = list()
for i in range(60):
	visit.append(0)
yay = 0
whoops = 0
for i in range(len(t)):
	visit[ord(t[i]) - ord('a')] += 1
for i in range(len(s)):
	if visit[ord(s[i]) - ord('a')] > 0:
		yay += 1
		visit[ord(s[i]) - ord('a')] -= 1
	else:
		lis.append(s[i])
for i in range(len(lis)):
	if visit[ord(lis[i].upper()) - ord('a')] > 0:
		whoops += 1
		visit[ord(lis[i].upper()) - ord('a')] -= 1
	elif visit[ord(lis[i].lower()) - ord('a')] > 0:
		whoops += 1
		visit[ord(lis[i].lower()) - ord('a')] -= 1
print(yay, whoops)


msg = input()
l = input()
msg = list(msg)
d = {}
y = 0
w = 0
for i in l:
	if i not in d:
		d[i] = 0
	d[i] += 1
for j in range(len(msg)):
	i = msg[j]
	if i in d and d[i] > 0:
		d[i] -= 1
		y += 1
		msg[j] = chr(30)
for i in msg:
	if ord(i) >= 97:
		if chr(ord(i) - 32) in d and d[chr(ord(i) - 32)] > 0:
			w += 1
			d[chr(ord(i) - 32)] -= 1
	elif chr(ord(i) + 32) in d and d[chr(ord(i) + 32)] > 0:
		d[chr(ord(i) + 32)] -= 1
		w += 1
print(y, w)


import string
s = input()
t = input()
dictS = {}
dictT = {}
for c in string.ascii_letters:
	dictT[c] = 0
	dictS[c] = 0
for c in s:
	dictS[c] += 1
for c in t:
	dictT[c] += 1
yay = 0
whoops = 0
for item in dictS.items():
	(c, s_count) = item
	t_count = dictT[c]
	yay_c = t_count if t_count < s_count else s_count
	yay += yay_c
	dictS[c] -= yay_c
	dictT[c] -= yay_c
for item in dictS.items():
	(c, s_count) = item
	c_other = c.lower() if c.isupper() else c.upper()
	t_count = dictT[c_other]
	whoops_c = t_count if t_count < s_count else s_count
	whoops += whoops_c
print(yay, whoops)


from collections import Counter
s = Counter(input())
t = Counter(input())
r1 = 0
for k in s:
	d = min(s[k], t[k])
	s[k] -= d
	t[k] -= d
	r1 += d
r2 = 0
for k in s:
	if k.islower():
		l = k.upper()
	else:
		l = k.lower()
	d = min(s[k], t[l])
	r2 += d
	s[k] -= d
	t[l] -= d
print(r1, r2)


from itertools import permutations
from collections import defaultdict
from math import *
import os
import sys
from io import BytesIO, IOBase
from heapq import nlargest
from bisect import *
import copy
import itertools
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))

def input():
	return sys.stdin.readline().rstrip('\r\n')
s = input()
t = input()
s = sorted(s)
d = defaultdict(int)
for i in range(len(t)):
	d[t[i]] += 1
(y, w) = (0, 0)
for i in range(len(s)):
	if d[s[i]] > 0:
		d[s[i]] -= 1
		s[i] = '/'
		y += 1
for i in range(len(s)):
	if d[s[i].lower()] > 0:
		d[s[i].lower()] -= 1
		w += 1
	elif d[s[i].upper()] > 0:
		d[s[i].upper()] -= 1
		w += 1
print(y, w)


desejadas = input()
recortadas = input()
YAY = 0
WHOOPS = 0
desejo = {}
possuo = {}
for rec in desejadas:
	if rec not in desejo:
		desejo[rec] = 1
	else:
		desejo[rec] += 1
for rec in recortadas:
	if rec not in possuo:
		possuo[rec] = 1
	else:
		possuo[rec] += 1
for chave in desejo:
	if chave in possuo:
		minimo = min(desejo[chave], possuo[chave])
		desejo[chave] -= minimo
		possuo[chave] -= minimo
		YAY += minimo
if len(desejo) < len(possuo):
	for chave in desejo:
		if chave.isupper():
			chaveCase = chave.lower()
		else:
			chaveCase = chave.upper()
		if chaveCase in possuo:
			minimo = min(desejo[chave], possuo[chaveCase])
			desejo[chave] -= minimo
			possuo[chaveCase] -= minimo
			WHOOPS += minimo
else:
	for chave in possuo:
		if chave.isupper():
			chaveCase = chave.lower()
		else:
			chaveCase = chave.upper()
		if chaveCase in desejo:
			minimo = min(desejo[chaveCase], possuo[chave])
			desejo[chaveCase] -= minimo
			possuo[chave] -= minimo
			WHOOPS += minimo
print(str(YAY) + ' ' + str(WHOOPS))


from collections import Counter
s = input()
mark = s
s = Counter(s)
t = Counter(input())
for i in s.keys():
	if t.get(i):
		temp = s[i]
		s[i] -= t[i]
		t[i] -= temp
yay = 0
whoops = 0
z = 0
for i in s.keys():
	z += max(0, s[i])
	if i.islower() and s[i] > 0 and t.get(i.upper()) and (t[i.upper()] > 0):
		if t[i.upper()] >= s[i]:
			whoops += s[i]
		else:
			whoops += t[i.upper()]
	elif i.isupper() and s[i] > 0 and t.get(i.lower()) and (t[i.lower()] > 0):
		if t[i.lower()] >= s[i]:
			whoops += s[i]
		else:
			whoops += t[i.lower()]
yay = len(mark) - z
print(yay, whoops)


s = input()
t = input()
n = len(s)
made = [False] * n
a = [0] * 130
for c in t:
	a[ord(c)] += 1
yay = whoops = 0
for i in range(n):
	if a[ord(s[i])] > 0:
		a[ord(s[i])] -= 1
		yay += 1
		made[i] = True
for i in range(n):
	if made[i] == False:
		c = s[i]
		if c.islower() and a[ord(c.upper())] > 0:
			a[ord(c.upper())] -= 1
			whoops += 1
		elif c.isupper() and a[ord(c.lower())] > 0:
			a[ord(c.lower())] -= 1
			whoops += 1
print(yay, whoops)


from collections import Counter
(massage, newspaper) = (input(), input())
(massageCounter, newsCounter) = (Counter(massage), Counter(newspaper))
(yay, whoops) = (0, 0)
for i in range(ord('a'), ord('z') + 1):
	yay += min(massageCounter[chr(i)], newsCounter[chr(i)])
for i in range(ord('A'), ord('Z') + 1):
	yay += min(massageCounter[chr(i)], newsCounter[chr(i)])
for i in range(ord('a'), ord('z') + 1):
	totalNew = newsCounter[chr(i)] + newsCounter[chr(i).upper()]
	totalMess = massageCounter[chr(i)] + massageCounter[chr(i).upper()]
	totalUsed = min(massageCounter[chr(i)], newsCounter[chr(i)]) + min(massageCounter[chr(i).upper()], newsCounter[chr(i).upper()])
	whoops += min(totalNew - totalUsed, totalMess - totalUsed)
print(yay, whoops)


from collections import Counter as c
mes = c(input())
new = c(input())
m = mes & new
ans = sum(m.values())
mes = mes - m
new = new - m
mes = c(dict(((k.swapcase(), v) for (k, v) in mes.items())))
ans1 = sum((mes & new).values())
print(ans, ans1)


s = input().strip()
t = input().strip()
d = {}
for i in s:
	if i in d:
		d[i] += 1
	else:
		d[i] = 1
x1 = 0
x2 = 0
e = [True for i in range(len(t))]
for i in range(len(t)):
	if t[i] in d and d[t[i]] > 0:
		d[t[i]] -= 1
		x1 += 1
		e[i] = False
t = t.swapcase()
for i in range(len(t)):
	if t[i] in d and e[i] and (d[t[i]] > 0):
		d[t[i]] -= 1
		x2 += 1
print(x1, x2)


alpha = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']
dict_s = {}
dict_news = {}
s = list(input())
newspaper = list(input())
for i in alpha:
	dict_s.update({i: s.count(i)})
	dict_news.update({i: newspaper.count(i)})
ny = 0
for k in alpha:
	if dict_s[k] <= dict_news[k]:
		ny += dict_s[k]
		dict_news[k] -= dict_s[k]
		dict_s[k] = 0
	else:
		ny += dict_news[k]
		dict_s[k] -= dict_news[k]
		dict_news[k] = 0
nw = 0
for k in alpha:
	if k.isupper() and dict_s[k] != 0:
		kl = k.lower()
		nw += min([dict_s[k], dict_news[kl]])
	if k.islower() and dict_s[k] != 0:
		ku = k.upper()
		nw += min([dict_s[k], dict_news[ku]])
print(ny, nw)


s1 = input()
s2 = input()
lista1 = [0] * 150
lista2 = [0] * 150
for i in range(len(s1)):
	lista1[ord(s1[i]) - ord('A')] += 1
for i in range(len(s2)):
	lista2[ord(s2[i]) - ord('A')] += 1
ans1 = 0
for i in range(100):
	matchs = min(lista1[i], lista2[i])
	ans1 += matchs
	lista1[i] -= matchs
	lista2[i] -= matchs
ans2 = 0
for i in range(100):
	ans2 += min(lista1[i], lista2[i + 32])
	ans2 += min(lista1[i + 32], lista2[i])
print(ans1, ans2)


from collections import defaultdict as dd
st = dd(int)
av = dd(int)
s = input()
t = input()
se = set()
for i in s:
	se.add(i.lower())
for i in t:
	av[i] += 1
for i in s:
	st[i] += 1
(y, w) = (0, 0)
for i in se:
	j = i.upper()
	(a, b) = (min(st[i], av[i]), min(st[j], av[j]))
	y += a + b
	st[i] -= a
	st[j] -= b
	av[i] -= a
	av[j] -= b
	(c, d) = (min(st[i], av[j]), min(st[j], av[i]))
	w += c + d
print(y, w)


def getIndex(ch):
	if ord('Z') >= ord(ch) >= ord('A'):
		return ord(ch) - ord('A')
	else:
		return 26 + ord(ch) - ord('a')
s = input().strip()
t = input().strip()
l = [0] * 52
yay = 0
whoop = 0
ls = [0] * len(s)
for i in range(len(t)):
	l[getIndex(t[i])] += 1
for i in range(len(s)):
	if l[getIndex(s[i])] > 0 and ls[i] > -1:
		yay += 1
		l[getIndex(s[i])] -= 1
		ls[i] = -1
for i in range(len(s)):
	if ls[i] > -1:
		tmp = ''
		if ord('Z') >= ord(s[i]) >= ord('A'):
			tmp = s[i].lower()
		else:
			tmp = s[i].upper()
		if l[getIndex(tmp)] > 0:
			whoop += 1
			l[getIndex(tmp)] -= 1
print('{0} {1}'.format(yay, whoop))


s = input()
t = input()
dict_t = dict()
for letter in t:
	dict_t[letter] = dict_t.get(letter, 0) + 1
yay = 0
whoops = 0
remaining = ''
for letter in s:
	if letter in dict_t and dict_t[letter] > 0:
		yay += 1
		dict_t[letter] -= 1
	else:
		remaining += letter
for letter in remaining:
	if letter.isupper() and letter.lower() in dict_t and (dict_t[letter.lower()] > 0):
		whoops += 1
		dict_t[letter.lower()] -= 1
	if letter.islower() and letter.upper() in dict_t and (dict_t[letter.upper()] > 0):
		whoops += 1
		dict_t[letter.upper()] -= 1
print(yay, whoops)


def tanya_and_postcard(tanya_message, newspaper_letters):
	difference = ord('a') - ord('A')
	yays_count = 0
	whoopses_count = 0
	letters_counts = get_letters_counts(newspaper_letters)
	tanya_message = list(tanya_message)
	for index in range(0, len(tanya_message)):
		letter = tanya_message[index]
		if letter in letters_counts and letters_counts[letter] > 0:
			letters_counts[letter] -= 1
			yays_count += 1
			tanya_message[index] = chr(0)
	for letter in tanya_message:
		letter = get_letter_in_opposite_casing(letter)
		if letter in letters_counts and letters_counts[letter] > 0:
			letters_counts[letter] -= 1
			whoopses_count += 1
	return {'yays_count': yays_count, 'whoopses_count': whoopses_count}

def get_letters_counts(letters):
	letters_counts = {}
	for letter in letters:
		if letter in letters_counts:
			letters_counts[letter] += 1
		else:
			letters_counts[letter] = 1
	return letters_counts

def get_letter_in_opposite_casing(letter):
	if letter.islower():
		return letter.upper()
	else:
		return letter.lower()

def main():
	tanya_message = input()
	newspaper_letters = input()
	result = tanya_and_postcard(tanya_message, newspaper_letters)
	print('{0} {1}'.format(result['yays_count'], result['whoopses_count']))

def __starting_point():
	main()
__starting_point()


import sys
import math
s = input()
t = input()
AlphaUp = [0] * 26
AlphaLow = [0] * 26
AlphaUp2 = [0] * 26
AlphaLow2 = [0] * 26
a = 0
b = 0
for i in range(len(t)):
	if t[i].islower():
		AlphaLow[ord(t[i]) - ord('a')] += 1
	else:
		AlphaUp[ord(t[i]) - ord('A')] += 1
for i in range(len(s)):
	if s[i].islower():
		AlphaLow2[ord(s[i]) - ord('a')] += 1
	else:
		AlphaUp2[ord(s[i]) - ord('A')] += 1
for i in range(26):
	v = AlphaLow[i] - AlphaLow2[i]
	ost = 0
	need = 0
	if v >= 0:
		ost += v
		a += AlphaLow2[i]
	else:
		need += -v
		a += AlphaLow[i]
	k = AlphaUp[i] - AlphaUp2[i]
	if k >= 0:
		ost += k
		a += AlphaUp2[i]
	else:
		need += -k
		a += AlphaUp[i]
	b += min(ost, need)
print(a, b)


import string

def main():
	(s, t) = (input(), input())
	m = {}
	for c in string.ascii_letters:
		m[c] = 0
	for c in t:
		m[c] += 1
	(yay, whoops) = (0, 0)
	mark = [False] * len(s)
	for i in range(len(s)):
		if m[s[i]] > 0:
			m[s[i]] -= 1
			yay += 1
			mark[i] = True
	for i in range(len(s)):
		if mark[i]:
			continue
		if s[i] in string.ascii_lowercase and m[s[i].upper()] > 0:
			whoops += 1
			m[s[i].upper()] -= 1
		elif s[i] in string.ascii_uppercase and m[s[i].lower()] > 0:
			whoops += 1
			m[s[i].lower()] -= 1
	print(yay, whoops)
main()


import math
s = input()
t = input()
lenS = len(s)
lenT = len(t)
yes = 0
no = 0

def change_register(l):
	if ord(l) > 96:
		return chr(ord(l) - 32)
	else:
		return chr(ord(l) + 32)
map1 = {}
for i in s:
	if map1.get(i, None) is None:
		map1[i] = 1
	else:
		map1[i] += 1
map2 = {}
for i in t:
	if map2.get(i, None) is None:
		map2[i] = 1
	else:
		map2[i] += 1
for i in map1:
	if map1.get(i, None) is None or map2.get(i, None) is None:
		continue
	diff = map1[i] - map2.get(i, 0)
	if diff > 0:
		yes += map1[i] - diff
		map2[i] -= map1[i] - diff
		map1[i] -= map1[i] - diff
	else:
		yes += map1[i]
		map2[i] -= map1[i]
		map1[i] = 0
for w in map1:
	i = change_register(w)
	if map1.get(w, None) is None or map2.get(i, None) is None:
		continue
	diff = map1[w] - map2.get(i, 0)
	if diff > 0:
		no += map1[w] - diff
		map2[i] = -(map1[w] - diff)
		map1[w] = -(map1[w] - diff)
	else:
		no += map1[w]
		map2[i] -= map1[w]
		map1[w] = 0
print(str(yes) + ' ' + str(no))


s = input()
t = input()
a = [0] * 200
b = [0] * 200
for i in range(len(s)):
	a[ord(s[i])] += 1
for i in range(len(t)):
	b[ord(t[i])] += 1
ans1 = ans2 = 0
for i in range(ord('A'), ord('Z') + 1):
	r = min(a[i], b[i]) + min(a[i + 32], b[i + 32])
	ans1 += r
	ans2 += min(a[i] + a[i + 32], b[i] + b[i + 32]) - r
print(ans1, ans2)


s = input()
t = input()
from collections import Counter as C
import string
lower = string.ascii_lowercase
upper = string.ascii_uppercase
cS = C(s)
cT = C(t)
yay = 0
whoops = 0
for (c, cnt) in cS.items():
	if c in cT.keys():
		subtract = min(cnt, cT[c])
		yay += subtract
		cS[c] -= subtract
		cT[c] -= subtract
for (c, cnt) in cS.items():
	if cnt == 0:
		continue
	if c in lower:
		c2 = c.upper()
	else:
		c2 = c.lower()
	if c2 in cT.keys():
		subtract = min(cnt, cT[c2])
		whoops += subtract
		cS[c] -= subtract
		cT[c2] -= subtract
print('{} {}'.format(yay, whoops))


def upc(c):
	if c >= 'a' and c <= 'z':
		c = chr(ord(c) - ord('a') + ord('A'))
	return c
(a1, a2) = ({}, {})
for i in input():
	if i in a1:
		a1[i] += 1
	else:
		a1[i] = 1
for i in input():
	if i in a2:
		a2[i] += 1
	else:
		a2[i] = 1
(r1, r2) = (0, 0)
(a3, a4) = ({}, {})
for k in a1:
	v = a1[k]
	if not k in a2:
		continue
	c = min(v, a2[k])
	a2[k] -= c
	a1[k] -= c
	r1 += c
for k in a1:
	v = a1[k]
	c = upc(k)
	if c in a3:
		a3[c] += v
	else:
		a3[c] = v
for k in a2:
	v = a2[k]
	c = upc(k)
	if c in a4:
		a4[c] += v
	else:
		a4[c] = v
for k in a3:
	if not k in a4:
		continue
	v = a3[k]
	c = min(v, a4[k])
	a3[k] -= c
	a4[k] -= c
	r2 += c
print(r1, r2)


alth = 'abcdefghijklmnopqrstuvwxyz'
alth2 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
s2 = [[0] * 26 for i in range(2)]
s3 = [[0] * 26 for i in range(2)]
s = input()
t = input()
num = 0
num2 = 0
for i in s:
	temp = alth.find(i)
	if temp != -1:
		s2[0][temp] += 1
	temp = alth2.find(i)
	if temp != -1:
		s2[1][temp] += 1
for i in t:
	temp = alth.find(i)
	if temp != -1:
		s3[0][temp] += 1
	temp = alth2.find(i)
	if temp != -1:
		s3[1][temp] += 1
for i in range(2):
	for j in range(26):
		x = min(s2[i][j], s3[i][j])
		num += x
		s2[i][j] -= x
		s3[i][j] -= x
for i in range(2):
	for j in range(26):
		num2 += min(s2[i][j], s3[1 - i][j])
print(num, num2)


(s, t) = (input(), input())
count = dict()
for c in t + s:
	count[c.upper()] = 0
	count[c.lower()] = 0
for c in t:
	count[c] += 1
(yay, woops) = (0, 0)
temp = ''
for c in s:
	if count[c] > 0:
		yay += 1
		count[c] -= 1
	else:
		temp += c
for c in temp:
	if c == c.upper() and count[c.lower()] > 0:
		woops += 1
		count[c.lower()] -= 1
	elif c == c.lower() and count[c.upper()] > 0:
		woops += 1
		count[c.upper()] -= 1
print(yay, woops)


s = input()
t = input()
alp = []
countalp = []
salp = []
scountalp = []
yay = 0
woops = 0
for (i, x) in enumerate(s):
	if x not in alp:
		alp.append(x)
		n = s.count(x)
		countalp.append(n)
for (i, x) in enumerate(t):
	if x not in salp:
		salp.append(x)
		n = t.count(x)
		scountalp.append(n)
for (b, y) in enumerate(alp):
	tcount = t.count(y)
	if tcount > 0:
		if abs(countalp[b] - tcount) == 0:
			yay += tcount
			scountalp[salp.index(y)] -= tcount
			countalp[b] -= tcount
		else:
			yay += min(countalp[b], tcount)
			if countalp[b] - tcount < 0:
				scountalp[salp.index(y)] -= countalp[b]
				countalp[b] = 0
			else:
				countalp[b] -= tcount
				scountalp[salp.index(y)] = 0
for (k, z) in enumerate(alp):
	if z.swapcase() in salp and countalp[k] > 0 and (scountalp[salp.index(z.swapcase())] > 0):
		woops += min(scountalp[salp.index(z.swapcase())], countalp[k])
print(yay, woops)


text = input()
letters = input()
d = {}
for ch in letters:
	d[ch] = d.get(ch, 0) + 1
a = []
for ch in text:
	a.append(False)
yaycount = 0
whoopscount = 0
for i in range(len(text)):
	ch = text[i]
	if ch in d and d[ch] > 0:
		yaycount = yaycount + 1
		d[ch] = d[ch] - 1
		a[i] = True
for i in range(len(text)):
	ch = text[i]
	if a[i] == False:
		if ch.lower() == ch:
			upper = ch.upper()
			if upper in d and d[upper] > 0:
				whoopscount = whoopscount + 1
				d[upper] = d[upper] - 1
		elif ch.upper() == ch:
			lower = ch.lower()
			if lower in d and d[lower] > 0:
				whoopscount = whoopscount + 1
				d[lower] = d[lower] - 1
print(str(yaycount) + ' ' + str(whoopscount))


def solve():
	d1 = {}
	d2 = {}
	yay = 0
	whoops = 0
	s1 = input()
	s2 = input()
	for i in s2:
		d2[i] = d2.get(i, 0) + 1
	for i in s1:
		d1[i] = d1.get(i, 0) + 1
	for i in range(26):
		k = chr(i + 97)
		c1 = d1.get(k, 0)
		c2 = d2.get(k, 0)
		cnt = min(c1, c2)
		yay += cnt
		if k in d1:
			d1[k] -= cnt
			if d1[k] == 0:
				d1.pop(k)
		if k in d2:
			d2[k] -= cnt
			if d2[k] == 0:
				d2.pop(k)
		k = k.upper()
		c1 = d1.get(k, 0)
		c2 = d2.get(k, 0)
		cnt = min(c1, c2)
		yay += cnt
		if k in d1:
			d1[k] -= cnt
			if d1[k] == 0:
				d1.pop(k)
		if k in d2:
			d2[k] -= cnt
			if d2[k] == 0:
				d2.pop(k)
	for i in range(26):
		k = chr(i + 97)
		j = k.upper()
		c1 = d1.get(k, 0)
		c2 = d2.get(j, 0)
		cnt = min(c1, c2)
		whoops += cnt
		if k in d1:
			d1[k] -= cnt
			if d1[k] == 0:
				d1.pop(k)
		if j in d2:
			d2[j] -= cnt
			if d2[j] == 0:
				d2.pop(j)
		(k, j) = (j, k)
		c1 = d1.get(k, 0)
		c2 = d2.get(j, 0)
		cnt = min(c1, c2)
		whoops += cnt
		if k in d1:
			d1[k] -= cnt
			if d1[k] == 0:
				d1.pop(k)
		if j in d2:
			d2[j] -= cnt
			if d2[j] == 0:
				d2.pop(j)
	print(yay, whoops)
	return

def main():
	t = 1
	for _ in range(t):
		solve()
main()


from collections import Counter

def changeCase(letter):
	if letter.isupper():
		return letter.lower()
	else:
		return letter.upper()
s = input()
t = input()
n = len(s)
visited_index_s = [False] * n
journal = Counter(t)
(yes, no) = (0, 0)
for i in range(n):
	letter = s[i]
	if letter in journal and journal[letter] != 0:
		yes += 1
		journal[letter] -= 1
		visited_index_s[i] = True
for i in range(n):
	letter = changeCase(s[i])
	if not visited_index_s[i] and journal[letter] != 0:
		no += 1
		journal[letter] -= 1
print(yes, no)


s = input()
t = input()

def count(s):
	d = {}
	for c in s:
		d[c] = d.get(c, 0) + 1
	return d

def compare(h1, h2):
	y = 0
	for (key, val) in h2.items():
		if key in h1:
			y += min(h1[key], val)
	return y
dt = count(t)
ds = count(s)
maxY = compare(dt, ds)
dt = count(t.lower())
ds = count(s.lower())
temp = compare(dt, ds)
maxW = temp - maxY
print(maxY, maxW)


s = str(input())
t = str(input())
(y, w) = (0, 0)

def oposto(caractere):
	if caractere.isupper():
		return caractere.lower()
	else:
		return caractere.upper()
hasht = {}
for i in t:
	if i in hasht:
		hasht[i] += 1
	else:
		hasht[i] = 1
hashs = {}
for i in s:
	if i in hashs:
		hashs[i] += 1
	else:
		hashs[i] = 1
for i in s:
	if i in hasht and hasht[i] > 0 and (hashs[i] > 0):
		y += 1
		hashs[i] -= 1
		hasht[i] -= 1
for i in s:
	if oposto(i) in hasht and hasht[oposto(i)] > 0 and (hashs[i] > 0):
		w += 1
		hasht[oposto(i)] -= 1
		hashs[i] -= 1
print(str(y) + ' ' + str(w))


import math, sys, bisect, heapq
from collections import defaultdict, Counter, deque
from itertools import groupby, accumulate
int1 = lambda x: int(x) - 1
input = iter(sys.stdin.buffer.read().decode().splitlines()).__next__
ilele = lambda : map(int, input().split())
alele = lambda : list(map(int, input().split()))
ilelec = lambda : map(int1, input().split())
alelec = lambda : list(map(int1, input().split()))

def list2d(a, b, c):
	return [[c] * b for i in range(a)]

def list3d(a, b, c, d):
	return [[[d] * c for j in range(b)] for i in range(a)]

def Y(c):
	print(['NO', 'YES'][c])

def y(c):
	print(['no', 'yes'][c])

def Yy(c):
	print(['No', 'Yes'][c])
s = input()
t = input()
C2 = Counter(t)
a = 0
b = 0
stri = ''
for i in s:
	z = C2.get(i, 0)
	if z > 0:
		a += 1
		C2[i] -= 1
	else:
		stri += i
for i in stri:
	if i.islower():
		x = i.upper()
		z = C2.get(x, 0)
		if z > 0:
			C2[x] -= 1
			b += 1
	elif i.isupper():
		x = i.lower()
		z = C2.get(x, 0)
		if z > 0:
			C2[x] -= 1
			b += 1
print(a, b)


sm = 'abcdefghijklmnopqrstuvwxyz'
la = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
s1 = input()
s2 = input()
d1 = {}
d2 = {}
ya = wh = 0
for i in s1:
	if i in d1:
		d1[i] += 1
	else:
		d1[i] = 1
for i in s2:
	if i in d2:
		d2[i] += 1
	else:
		d2[i] = 1
for i in d1:
	if i in d2:
		t = min(d1[i], d2[i])
		d1[i] -= t
		d2[i] -= t
		ya += t
for i in d1:
	j = i
	j = j.swapcase()
	if j in d2:
		t = min(d1[i], d2[j])
		d1[i] -= t
		d2[j] -= t
		wh += t
print(ya, wh)


def process(str):
	d = {}
	for c in str:
		d[c] = d.setdefault(c, 0) + 1
	return d

def match(d1, d2, case):
	ans = 0
	for c in d1:
		if case(c) not in d2:
			continue
		m = min(d1[c], d2[case(c)])
		ans += m
		d1[c] -= m
		d2[case(c)] -= m
	return ans
sd = process(input())
td = process(input())
yay = match(sd, td, lambda x: x)
whoops = match(sd, td, lambda x: x.lower() if x.isupper() else x.upper())
print(yay, whoops)


s = input()
t = input()
alf = 'qwertyuiopasdfghjklzxcvbnm'
ALF = 'QWERTYUIOPASDFGHJKLZXCVBNM'
(d, di) = ({}, {})
for (i, x) in enumerate(alf):
	d[x] = ALF[i]
	di[ALF[i]] = x
(T, res1, res2) = ({}, 0, 0)
for (i, x) in enumerate(t):
	if T.get(x) == None:
		T[x] = 0
	T[x] += 1
new = ''
for (i, x) in enumerate(s):
	if T.get(x) != None:
		T[x] -= 1
		res1 += 1
		if T[x] == 0:
			T.pop(x)
	else:
		new += x
for (i, x) in enumerate(new):
	if d.get(x) == None:
		y = di[x]
	else:
		y = d[x]
	if T.get(y) != None:
		T[y] -= 1
		res2 += 1
		if T[y] == 0:
			T.pop(y)
print(res1, res2)


s = input()
t = input()
cnt = [0] * 300
used = [0] * len(s)
for c in t:
	cnt[ord(c)] += 1
c1 = 0
c2 = 0
for i in range(len(s)):
	c = s[i]
	if cnt[ord(c)] > 0:
		c1 += 1
		cnt[ord(c)] -= 1
		used[i] = 1
for i in range(len(s)):
	c = s[i]
	if used[i] == 0 and cnt[ord(c) ^ 32] > 0:
		c2 += 1
		cnt[ord(c) ^ 32] -= 1
print(c1, c2)


s1 = list(input())
s2 = list(input())
n = len(s1)
d1 = dict()
for i in s1:
	try:
		d1[i] += 1
	except:
		d1[i] = 1
d2 = dict()
for i in s2:
	try:
		d2[i] += 1
	except:
		d2[i] = 1
for i in d1:
	try:
		m = min(d1[i], d2[i])
		d1[i] -= m
		d2[i] -= m
	except:
		pass
sum = 0
for i in d1:
	sum += d1[i]
a = n - sum
n = sum
sum = 0
for i in d1:
	try:
		if d1[i] > 0:
			if i.islower():
				x = i.upper()
			else:
				x = i.lower()
			d1[i] -= min(d1[i], d2[x])
			d2[x] -= min(d1[i], d2[x])
	except:
		pass
for i in d1:
	sum += d1[i]
b = n - sum
print(a, b)


from sys import stdin
from collections import defaultdict

def main():
	s = stdin.readline().strip()
	t = stdin.readline().strip()
	ds = defaultdict(int)
	for c in s:
		ds[c] += 1
	dt = defaultdict(int)
	for c in t:
		dt[c] += 1
	a = b = 0
	alpha = 'abcdefghijklmnopqrstuvwxyz'
	for c in alpha + alpha.upper():
		x = min(ds[c], dt[c])
		ds[c] -= x
		dt[c] -= x
		a += x
	for c in alpha:
		ds[c] += ds[c.upper()]
		dt[c] += dt[c.upper()]
		x = min(ds[c], dt[c])
		b += x
	print(a, b)
main()


from collections import Counter, defaultdict
from string import ascii_letters, ascii_lowercase
s = input()
t = input()
(yay, whoops) = (0, 0)
ds = Counter(s)
dt = Counter(t)
for char in ascii_letters:
	tmp = min(ds[char], dt[char])
	ds[char] -= tmp
	dt[char] -= tmp
	yay += tmp
for char in ascii_lowercase:
	ds[char] += ds[char.upper()]
	dt[char] += dt[char.upper()]
	tmp = min(ds[char], dt[char])
	ds[char] -= tmp
	dt[char] -= tmp
	whoops += tmp
print(yay, whoops)


from collections import Counter
s = Counter(input())
t = Counter(input())
yay = 0
whoops = 0
for i in range(97, 123):
	a = s[chr(i)]
	b = t[chr(i)]
	c = s[chr(i - 32)]
	d = t[chr(i - 32)]
	minm = min(a, b) + min(c, d)
	yay += minm
	whoops += min(a + c, b + d) - minm
print(yay, whoops)


from collections import Counter
write = Counter(input())
paper = Counter(input())

def other(ch):
	if ch.isupper():
		return ch.lower()
	return ch.upper()
ura = 0
for ch in write:
	nUra = min(write[ch], paper[ch])
	ura += nUra
	write[ch] -= nUra
	paper[ch] -= nUra
opa = 0
for ch in write:
	nOpa = min(write[ch], paper[other(ch)])
	opa += nOpa
print('%d %d' % (ura, opa))


import os
import sys
from math import *
from collections import *
from fractions import *
from bisect import *
from heapq import *
from io import BytesIO, IOBase

def vsInput():
	sys.stdin = open('input.txt', 'r')
	sys.stdout = open('output.txt', 'w')
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')

def value():
	return tuple(map(int, input().split()))

def array():
	return [int(i) for i in input().split()]

def Int():
	return int(input())

def Str():
	return input()

def arrayS():
	return [i for i in input().split()]
text = input()
news = input()
text_count = defaultdict(lambda : [0, 0])
news_count = defaultdict(lambda : [0, 0])
for i in text:
	key = i.lower()
	if i.isupper():
		text_count[key][1] += 1
	else:
		text_count[key][0] += 1
for i in news:
	key = i.lower()
	if i.isupper():
		news_count[key][1] += 1
	else:
		news_count[key][0] += 1
yay = 0
whoops = 0
for i in text_count:
	(need_L, need_U) = text_count[i]
	(have_L, have_U) = news_count[i]
	k1 = min(have_L, need_L)
	k2 = min(have_U, need_U)
	have_U -= k2
	have_L -= k1
	need_L -= k1
	need_U -= k2
	need = need_L + need_U
	have = have_L + have_U
	yay += k1 + k2
	whoops += min(have, need)
print(yay, whoops)


from collections import Counter
s = list(input())
t = list(input())
d1 = {}
d2 = {}
(ans1, ans2) = (0, 0)
c1 = Counter(s)
c2 = Counter(t)
for i in c1:
	if i in c2:
		x = min(c1[i], c2[i])
		c1[i] -= x
		c2[i] -= x
		ans1 += x
for i in c1:
	if ord(i) <= 90:
		y = chr(ord(i) + 32)
		if y in c2:
			ans2 += min(c1[i], c2[y])
	else:
		y = chr(ord(i) - 32)
		if y in c2:
			ans2 += min(c1[i], c2[y])
print(ans1, ans2)


from collections import Counter as c
(s, t) = (c(input()), c(input()))
(r, v) = (0, 0)
for i in s:
	tmp = min(s[i], t[i])
	r += tmp
	s[i] = s[i] - tmp
	t[i] = t[i] - tmp
for i in s:
	tmp = min(s[i], t[i.swapcase()])
	s[i] -= tmp
	t[i.swapcase()] -= tmp
	v += tmp
print(r, v)


x = input()
t = input()
d = dict()
for i in t:
	if i in d:
		d[i] += 1
	else:
		d[i] = 1
s = []
for i in x:
	s.append([i, 0])
s.sort(reverse=True)
ura = 0
opa = 0
for i in range(len(s)):
	if s[i][0] in d:
		if d[s[i][0]] > 0:
			ura += 1
			s[i][1] = 1
			d[s[i][0]] -= 1
for i in range(len(s)):
	if chr(ord(s[i][0]) - ord('a') + ord('A')) in d and s[i][1] == 0:
		if d[chr(ord(s[i][0]) - ord('a') + ord('A'))] > 0:
			opa += 1
			s[i][1] = 1
			d[chr(ord(s[i][0]) - ord('a') + ord('A'))] -= 1
for i in range(len(s)):
	if chr(ord(s[i][0]) - ord('A') + ord('a')) in d and s[i][1] == 0:
		if d[chr(ord(s[i][0]) - ord('A') + ord('a'))] > 0:
			opa += 1
			s[i][1] = 1
			d[chr(ord(s[i][0]) - ord('A') + ord('a'))] -= 1
print(ura, opa)