We call a string good, if after merging all the consecutive equal characters, the resulting string is palindrome. For example, "aabba" is good, because after the merging step it will become "aba".

Given a string, you have to find two values:  the number of good substrings of even length;  the number of good substrings of odd length. 


-----Input-----

The first line of the input contains a single string of length n (1 ≤ n ≤ 10^5). Each character of the string will be either 'a' or 'b'.


-----Output-----

Print two space-separated integers: the number of good substrings of even length and the number of good substrings of odd length.


-----Examples-----
Input
bb

Output
1 2

Input
baab

Output
2 4

Input
babb

Output
2 5

Input
babaa

Output
2 7



-----Note-----

In example 1, there are three good substrings ("b", "b", and "bb"). One of them has even length and two of them have odd length.

In example 2, there are six good substrings (i.e. "b", "a", "a", "b", "aa", "baab"). Two of them have even length and four of them have odd length.

In example 3, there are seven good substrings (i.e. "b", "a", "b", "b", "bb", "bab", "babb"). Two of them have even length and five of them have odd length.

Definitions

A substring s[l, r] (1 ≤ l ≤ r ≤ n) of string s = s_1s_2... s_{n} is string s_{l}s_{l} + 1... s_{r}.

A string s = s_1s_2... s_{n} is a palindrome if it is equal to string s_{n}s_{n} - 1... s_1.

Difficulty: HARD
Tags: Mathematics

Starter code:

Solutions:
def R():
	return map(int, input().split())

def I():
	return int(input())

def S():
	return str(input())

def L():
	return list(R())
from collections import Counter
import math
import sys
from itertools import permutations
import bisect
mod = 10 ** 9 + 7
s = S()
l = len(s)
A = [0] * 2
B = [0] * 2
for i in range(2):
	A[i] = [0] * (l + 3)
	B[i] = [0] * (l + 3)
for i in range(l):
	for j in range(2):
		if i % 2 != j:
			A[j][i] = A[j][i - 1]
			B[j][i] = B[j][i - 1]
		else:
			A[j][i] = A[j][i - 2] + (s[i] == 'a')
			B[j][i] = B[j][i - 2] + (s[i] == 'b')
ans = [0] * 2
for i in range(l):
	if s[i] == 'a':
		ans[0] += A[1 - i % 2][i]
		ans[1] += A[i % 2][i]
	else:
		ans[0] += B[1 - i % 2][i]
		ans[1] += B[i % 2][i]
print(ans[0], ans[1])


s = input()
blocks = []
evenA = [0]
oddA = [0]
evenB = [0]
oddB = [0]
even = True
for x in s:
	evenA.append(evenA[-1])
	oddA.append(oddA[-1])
	evenB.append(evenB[-1])
	oddB.append(oddB[-1])
	if x == 'a':
		if even:
			evenA[-1] += 1
		else:
			oddA[-1] += 1
	elif even:
		evenB[-1] += 1
	else:
		oddB[-1] += 1
	even = not even
even = True
totalE = 0
totalO = 0
for x in range(len(s)):
	if s[x] == 'a':
		if x % 2 == 0:
			totalE += evenA[-1] - evenA[x]
			totalO += oddA[-1] - oddA[x]
		else:
			totalE += oddA[-1] - oddA[x]
			totalO += evenA[-1] - evenA[x]
	elif x % 2 == 0:
		totalE += evenB[-1] - evenB[x]
		totalO += oddB[-1] - oddB[x]
	else:
		totalE += oddB[-1] - oddB[x]
		totalO += evenB[-1] - evenB[x]
print(totalO, totalE)


s = input()
a = []
for c in s:
	a.append(ord(c) - ord('a'))
cnt = [[0, 0], [0, 0]]
ans = [0, 0]
for i in range(len(a)):
	cnt[a[i]][i % 2] += 1
	ans[0] += cnt[a[i]][i % 2]
	ans[1] += cnt[a[i]][1 - i % 2]
print(ans[1], ans[0])


def main():
	s = input()
	a = [0, 0]
	b = [0, 0]
	res = [0, 0]
	for (i, c) in enumerate(s, 1):
		(ii, ij) = (i % 2, (i + 1) % 2)
		_a = a if c == 'a' else b
		res[1] += _a[ii] + 1
		res[0] += _a[ij]
		_a[ii] += 1
	print(*res)

def __starting_point():
	main()
__starting_point()


s = input()
m = [2 * [0] for _ in range(2)]
(odd, even) = (0, 0)
for i in range(len(s)):
	m[1 if s[i] == 'a' else 0][i % 2] += 1
	odd += m[1 if s[i] == 'a' else 0][i % 2]
	even += m[1 if s[i] == 'a' else 0][not i % 2]
print(even, odd)


s = input()
d = dict()
d['a'] = [0, 0]
d['b'] = [0, 0]
odd = even = 0
for i in range(len(s)):
	d[s[i]][i & 1] += 1
	odd += d[s[i]][i & 1]
	even += d[s[i]][1 - i & 1]
print(even, odd)


from sys import stdin, stdout, setrecursionlimit
input = stdin.readline
inf = float('inf')
from functools import cmp_to_key
from collections import defaultdict as dd
from collections import Counter, deque
from heapq import *
import math
from math import floor, ceil, sqrt

def geti():
	return map(int, input().strip().split())

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

def getis():
	return map(str, input().strip().split())

def getls():
	return list(map(str, input().strip().split()))

def gets():
	return input().strip()

def geta():
	return int(input())

def print_s(s):
	stdout.write(s + '\n')

def solve():
	s = gets()
	n = len(s)
	even = odd = odd_a = odd_b = even_a = even_b = 0
	for i in range(n):
		if s[i] == 'a':
			if i & 1:
				odd += odd_a
				even += even_a
			else:
				even += odd_a
				odd += even_a
		elif i & 1:
			odd += odd_b
			even += even_b
		else:
			even += odd_b
			odd += even_b
		if i & 1:
			if s[i] == 'b':
				odd_b += 1
			else:
				odd_a += 1
		elif s[i] == 'b':
			even_b += 1
		else:
			even_a += 1
	print(even, odd + n)
solve()


from sys import stdin
s = input()
ppcnt = 0
prevcnt = 0
i = 0
one = s[0]
two = s[0]
onec = [0, 0]
twoc = [0, 0]
od = ev = 0
for i in range(len(s)):
	if s[i] == one:
		onec[i % 2] += 1
		od += onec[i % 2 ^ 1]
		ev += onec[i % 2]
	else:
		twoc[i % 2] += 1
		od += twoc[i % 2 ^ 1]
		ev += twoc[i % 2]
print(od, ev)


s = input()
last_a = -1
last_b = -1
odd = [1 for c in s]
even = [0 for c in s]
for i in range(len(s)):
	if s[i] == 'a':
		if last_a == -1:
			last_a = i
			continue
		dis = i - last_a
		if dis % 2 == 0:
			odd[i] += odd[last_a]
			even[i] += even[last_a]
		else:
			odd[i] += even[last_a]
			even[i] += odd[last_a]
		last_a = i
	elif s[i] == 'b':
		if last_b == -1:
			last_b = i
			continue
		dis = i - last_b
		if dis % 2 == 0:
			odd[i] += odd[last_b]
			even[i] += even[last_b]
		else:
			odd[i] += even[last_b]
			even[i] += odd[last_b]
		last_b = i
print(sum(even), sum(odd))


import os
import sys
from io import BytesIO, IOBase
import heapq as h
from bisect import bisect_left, bisect_right
from types import GeneratorType
BUFSIZE = 8192

class SortedList:

	def __init__(self, iterable=[], _load=200):
		values = sorted(iterable)
		self._len = _len = len(values)
		self._load = _load
		self._lists = _lists = [values[i:i + _load] for i in range(0, _len, _load)]
		self._list_lens = [len(_list) for _list in _lists]
		self._mins = [_list[0] for _list in _lists]
		self._fen_tree = []
		self._rebuild = True

	def _fen_build(self):
		self._fen_tree[:] = self._list_lens
		_fen_tree = self._fen_tree
		for i in range(len(_fen_tree)):
			if i | i + 1 < len(_fen_tree):
				_fen_tree[i | i + 1] += _fen_tree[i]
		self._rebuild = False

	def _fen_update(self, index, value):
		if not self._rebuild:
			_fen_tree = self._fen_tree
			while index < len(_fen_tree):
				_fen_tree[index] += value
				index |= index + 1

	def _fen_query(self, end):
		if self._rebuild:
			self._fen_build()
		_fen_tree = self._fen_tree
		x = 0
		while end:
			x += _fen_tree[end - 1]
			end &= end - 1
		return x

	def _fen_findkth(self, k):
		_list_lens = self._list_lens
		if k < _list_lens[0]:
			return (0, k)
		if k >= self._len - _list_lens[-1]:
			return (len(_list_lens) - 1, k + _list_lens[-1] - self._len)
		if self._rebuild:
			self._fen_build()
		_fen_tree = self._fen_tree
		idx = -1
		for d in reversed(range(len(_fen_tree).bit_length())):
			right_idx = idx + (1 << d)
			if right_idx < len(_fen_tree) and k >= _fen_tree[right_idx]:
				idx = right_idx
				k -= _fen_tree[idx]
		return (idx + 1, k)

	def _delete(self, pos, idx):
		_lists = self._lists
		_mins = self._mins
		_list_lens = self._list_lens
		self._len -= 1
		self._fen_update(pos, -1)
		del _lists[pos][idx]
		_list_lens[pos] -= 1
		if _list_lens[pos]:
			_mins[pos] = _lists[pos][0]
		else:
			del _lists[pos]
			del _list_lens[pos]
			del _mins[pos]
			self._rebuild = True

	def _loc_left(self, value):
		if not self._len:
			return (0, 0)
		_lists = self._lists
		_mins = self._mins
		(lo, pos) = (-1, len(_lists) - 1)
		while lo + 1 < pos:
			mi = lo + pos >> 1
			if value <= _mins[mi]:
				pos = mi
			else:
				lo = mi
		if pos and value <= _lists[pos - 1][-1]:
			pos -= 1
		_list = _lists[pos]
		(lo, idx) = (-1, len(_list))
		while lo + 1 < idx:
			mi = lo + idx >> 1
			if value <= _list[mi]:
				idx = mi
			else:
				lo = mi
		return (pos, idx)

	def _loc_right(self, value):
		if not self._len:
			return (0, 0)
		_lists = self._lists
		_mins = self._mins
		(pos, hi) = (0, len(_lists))
		while pos + 1 < hi:
			mi = pos + hi >> 1
			if value < _mins[mi]:
				hi = mi
			else:
				pos = mi
		_list = _lists[pos]
		(lo, idx) = (-1, len(_list))
		while lo + 1 < idx:
			mi = lo + idx >> 1
			if value < _list[mi]:
				idx = mi
			else:
				lo = mi
		return (pos, idx)

	def add(self, value):
		_load = self._load
		_lists = self._lists
		_mins = self._mins
		_list_lens = self._list_lens
		self._len += 1
		if _lists:
			(pos, idx) = self._loc_right(value)
			self._fen_update(pos, 1)
			_list = _lists[pos]
			_list.insert(idx, value)
			_list_lens[pos] += 1
			_mins[pos] = _list[0]
			if _load + _load < len(_list):
				_lists.insert(pos + 1, _list[_load:])
				_list_lens.insert(pos + 1, len(_list) - _load)
				_mins.insert(pos + 1, _list[_load])
				_list_lens[pos] = _load
				del _list[_load:]
				self._rebuild = True
		else:
			_lists.append([value])
			_mins.append(value)
			_list_lens.append(1)
			self._rebuild = True

	def discard(self, value):
		_lists = self._lists
		if _lists:
			(pos, idx) = self._loc_right(value)
			if idx and _lists[pos][idx - 1] == value:
				self._delete(pos, idx - 1)

	def remove(self, value):
		_len = self._len
		self.discard(value)
		if _len == self._len:
			raise ValueError('{0!r} not in list'.format(value))

	def pop(self, index=-1):
		(pos, idx) = self._fen_findkth(self._len + index if index < 0 else index)
		value = self._lists[pos][idx]
		self._delete(pos, idx)
		return value

	def bisect_left(self, value):
		(pos, idx) = self._loc_left(value)
		return self._fen_query(pos) + idx

	def bisect_right(self, value):
		(pos, idx) = self._loc_right(value)
		return self._fen_query(pos) + idx

	def count(self, value):
		return self.bisect_right(value) - self.bisect_left(value)

	def __len__(self):
		return self._len

	def __getitem__(self, index):
		(pos, idx) = self._fen_findkth(self._len + index if index < 0 else index)
		return self._lists[pos][idx]

	def __delitem__(self, index):
		(pos, idx) = self._fen_findkth(self._len + index if index < 0 else index)
		self._delete(pos, idx)

	def __contains__(self, value):
		_lists = self._lists
		if _lists:
			(pos, idx) = self._loc_left(value)
			return idx < len(_lists[pos]) and _lists[pos][idx] == value
		return False

	def __iter__(self):
		return (value for _list in self._lists for value in _list)

	def __reversed__(self):
		return (value for _list in reversed(self._lists) for value in reversed(_list))

	def __repr__(self):
		return 'SortedList({0})'.format(list(self))

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		import os
		self.os = os
		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 = self.os.read(self._fd, max(self.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 = self.os.read(self._fd, max(self.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:
			self.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')
import collections as col
import math, string

def getInts():
	return [int(s) for s in input().split()]

def getInt():
	return int(input())

def getStrs():
	return [s for s in input().split()]

def getStr():
	return input()

def listStr():
	return list(input())
MOD = 10 ** 9 + 7
t = 1
p = 10 ** 9 + 7

def ncr_util():
	inv[0] = inv[1] = 1
	fact[0] = fact[1] = 1
	for i in range(2, 300001):
		inv[i] = inv[i % p] * (p - p // i) % p
	for i in range(1, 300001):
		inv[i] = inv[i - 1] * inv[i] % p
		fact[i] = fact[i - 1] * i % p

def solve():
	d = {}
	d['a'] = []
	d['b'] = []
	o = {}
	e = {}
	o['a'] = 0
	o['b'] = 0
	e['a'] = 0
	e['b'] = 0
	for i in range(len(s)):
		d[s[i]].append(i)
		if i % 2 == 0:
			e[s[i]] += 1
		else:
			o[s[i]] += 1
	(ans_odd, ans_even) = (len(s), 0)
	for i in range(len(s)):
		if i % 2 == 0:
			e[s[i]] -= 1
			ans_odd += e[s[i]]
			ans_even += o[s[i]]
		else:
			o[s[i]] -= 1
			ans_even += e[s[i]]
			ans_odd += o[s[i]]
	return (ans_even, ans_odd)
for _ in range(t):
	s = input()
	print(*solve())


s = input()
odd = 0
even = 0
cntE = [0, 0]
cntO = [0, 0]
for i in range(len(s)):
	cur = 0 + int(s[i] == 'b')
	odd += 1
	if i % 2 == 0:
		odd += cntE[cur]
		even += cntO[cur]
		cntE[cur] += 1
	else:
		odd += cntO[cur]
		even += cntE[cur]
		cntO[cur] += 1
print(even, odd)


import sys
import collections as cc
input = sys.stdin.readline
I = lambda : list(map(int, input().split()))
s = input().strip()
f = cc.defaultdict(list)
f['a'] = [0, 0]
f['b'] = [0, 0]
od = 0
ev = 0
for i in range(len(s)):
	if i % 2 == 0:
		od += f[s[i]][0]
		ev += f[s[i]][1]
	else:
		od += f[s[i]][1]
		ev += f[s[i]][0]
	f[s[i]][i % 2] += 1
print(ev, od + len(s))


t = input()
n = len(t)
t = [-1] + [i for i in range(n - 1) if t[i] != t[i + 1]] + [n - 1]
n = len(t) - 1
(u, v) = ([0] * n, [0] * n)
for i in range(n):
	d = t[i + 1] - t[i]
	k = d // 2
	u[i] = v[i] = k
	if d & 1:
		if t[i] & 1:
			v[i] += 1
		else:
			u[i] += 1
	i += 1
a = sum((u[i] for i in range(0, n, 2)))
b = sum((v[i] for i in range(0, n, 2)))
c = sum((u[i] for i in range(1, n, 2)))
d = sum((v[i] for i in range(1, n, 2)))
print(a * b + c * d, (a * (a + 1) + b * (b + 1) + c * (c + 1) + d * (d + 1)) // 2)


s = input()
oddc = {'a': 0, 'b': 0}
evenc = {'a': 0, 'b': 0}
odd = 0
even = 0
for i in range(len(s)):
	odd += 1
	if i % 2 == 0:
		even += oddc[s[i]]
		odd += evenc[s[i]]
		evenc[s[i]] += 1
	else:
		even += evenc[s[i]]
		odd += oddc[s[i]]
		oddc[s[i]] += 1
print(str(even) + ' ' + str(odd))


from sys import stdin

def solve():
	s = stdin.readline().strip()
	n = len(s)
	sfa = [[0, 0] for i in range(n + 1)]
	sfb = [[0, 0] for i in range(n + 1)]
	for i in range(n - 1, -1, -1):
		sfa[i][:] = sfa[i + 1][:]
		sfb[i][:] = sfb[i + 1][:]
		if s[i] == 'a':
			sfa[i][i % 2] += 1
		else:
			sfb[i][i % 2] += 1
	ans = [0, 0]
	for i in range(n):
		if s[i] == 'a':
			ans[0] += sfa[i + 1][i % 2]
			ans[1] += sfa[i + 1][(i + 1) % 2]
		else:
			ans[0] += sfb[i + 1][i % 2]
			ans[1] += sfb[i + 1][(i + 1) % 2]
	print(ans[1], ans[0] + n)
solve()


s = input()
(ep, op, enp, onp) = (0, 0, 0, 0)
prev = ''
(totalE, totalO) = (0, 0)
for c in s:
	if prev == c:
		(ep, op, enp, onp) = (op, ep + 1, onp, enp)
	else:
		(ep, op, enp, onp) = (onp, 1 + enp, op, ep)
	(totalO, totalE) = (totalO + op, totalE + ep)
	prev = c
print(totalE, totalO)


string = input()
length = len(string)
goodbad = [[1, 0, 0, 0] for x in range(length)]
for i in range(length - 1):
	if string[i] == string[i + 1]:
		goodbad[i + 1][0] += goodbad[i][2]
		goodbad[i + 1][2] += goodbad[i][0]
		goodbad[i + 1][1] += goodbad[i][3]
		goodbad[i + 1][3] += goodbad[i][1]
	else:
		goodbad[i + 1][3] += goodbad[i][0]
		goodbad[i + 1][0] += goodbad[i][3]
		goodbad[i + 1][1] += goodbad[i][2]
		goodbad[i + 1][2] += goodbad[i][1]
oddct = 0
evenct = 0
for i in range(len(goodbad)):
	oddct += goodbad[i][0]
	evenct += goodbad[i][2]
print(evenct, oddct)


s = input()
cntodda = 0
cntoddb = 0
cntevena = 0
cntevenb = 0
evencnt = 0
oddcnt = 0
for i in range(len(s)):
	oddcnt += 1
	if i % 2 == 0:
		if s[i] == 'a':
			evencnt += cntodda
			oddcnt += cntevena
		else:
			evencnt += cntoddb
			oddcnt += cntevenb
		if s[i] == 'a':
			cntevena += 1
		else:
			cntevenb += 1
	else:
		if s[i] == 'a':
			evencnt += cntevena
			oddcnt += cntodda
		else:
			evencnt += cntevenb
			oddcnt += cntoddb
		if s[i] == 'a':
			cntodda += 1
		else:
			cntoddb += 1
print(evencnt, oddcnt)


import os
from io import BytesIO, IOBase
import sys

def main():
	s = input().rstrip()
	n = len(s)
	(a, b, ans) = ([0, 0], [0, 0], [0, 0])
	for i in range(n):
		if s[i] == 'a':
			if i & 1:
				ans[1] += a[1]
				ans[0] += a[0]
				a[1] += 1
			else:
				ans[1] += a[0]
				ans[0] += a[1]
				a[0] += 1
		elif i & 1:
			ans[1] += b[1]
			ans[0] += b[0]
			b[1] += 1
		else:
			ans[1] += b[0]
			ans[0] += b[1]
			b[0] += 1
		ans[1] += 1
	print(*ans)
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')
main()


import sys
input = sys.stdin.readline
s = input().rstrip()
n = len(s)
pos_a_odd = 0
pos_a_even = 0
pos_b_odd = 0
pos_b_even = 0
(ans_even, ans_odd) = (0, 0)
for i in range(n):
	if s[i] == 'a':
		if i % 2:
			pos_a_odd += 1
			ans_odd += pos_a_odd
			ans_even += pos_a_even
		else:
			pos_a_even += 1
			ans_odd += pos_a_even
			ans_even += pos_a_odd
	elif i % 2:
		pos_b_odd += 1
		ans_odd += pos_b_odd
		ans_even += pos_b_even
	else:
		pos_b_even += 1
		ans_odd += pos_b_even
		ans_even += pos_b_odd
print(ans_even, ans_odd)


from sys import stdin
string = list(stdin.readline().strip())
odd_a = 0
even_a = 0
odd_b = 0
even_b = 0
even = 0
odd = 0
for i in string:
	if i == 'a':
		temp = odd_a
		odd_a = even_a + 1
		even_a = temp
		(even_b, odd_b) = (odd_b, even_b)
		odd += odd_a
		even += even_a
	else:
		temp = odd_b
		odd_b = even_b + 1
		even_b = temp
		(even_a, odd_a) = (odd_a, even_a)
		odd += odd_b
		even += even_b
print(even, odd)


from __future__ import division, print_function
import os, sys
from io import BytesIO, IOBase
if sys.version_info[0] < 3:
	from __builtin__ import xrange as range
	from future_builtins import ascii, filter, hex, map, oct, zip

def ii():
	return int(input())

def si():
	return input()

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

def msi():
	return map(str, input().strip().split(' '))

def li():
	return list(mi())

def dmain():
	sys.setrecursionlimit(1000000)
	threading.stack_size(1024000)
	thread = threading.Thread(target=main)
	thread.start()
abc = 'abcdefghijklmnopqrstuvwxyz'
abd = {'a': 0, 'b': 1, 'c': 2, 'd': 3, 'e': 4, 'f': 5, 'g': 6, 'h': 7, 'i': 8, 'j': 9, 'k': 10, 'l': 11, 'm': 12, 'n': 13, 'o': 14, 'p': 15, 'q': 16, 'r': 17, 's': 18, 't': 19, 'u': 20, 'v': 21, 'w': 22, 'x': 23, 'y': 24, 'z': 25}
mod = 1000000007
inf = float('inf')
vow = ['a', 'e', 'i', 'o', 'u', 'y']
(dx, dy) = ([-1, 1, 0, 0], [0, 0, 1, -1])

def getKey(item):
	return item[1]

def sort2(l):
	return sorted(l, key=getKey, reverse=True)

def d2(n, m, num):
	return [[num for x in range(m)] for y in range(n)]

def isPowerOfTwo(x):
	return x and (not x & x - 1)

def decimalToBinary(n):
	return bin(n).replace('0b', '')

def ntl(n):
	return [int(i) for i in str(n)]

def ncr(n, r):
	return factorial(n) // (factorial(r) * factorial(max(n - r, 1)))

def ceil(x, y):
	if x % y == 0:
		return x // y
	else:
		return x // y + 1

def powerMod(x, y, p):
	res = 1
	x %= p
	while y > 0:
		if y & 1:
			res = res * x % p
		y = y >> 1
		x = x * x % p
	return res

def gcd(x, y):
	while y:
		(x, y) = (y, x % y)
	return x

def isPrime(n):
	if n <= 1:
		return False
	if n <= 3:
		return True
	if n % 2 == 0 or n % 3 == 0:
		return False
	i = 5
	while i * i <= n:
		if n % i == 0 or n % (i + 2) == 0:
			return False
		i = i + 6
	return True

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

def main():
	s = si()
	n = len(s)
	a = []
	b = []
	for i in range(n):
		if s[i] == 'a':
			a.append(i)
		else:
			b.append(i)
	ans1 = 0
	ans2 = n
	even = 0
	odd = 0
	for i in range(1, len(a)):
		if (a[i] - a[0]) % 2 == 1:
			even += 1
		else:
			odd += 1
	ans1 += even
	ans2 += odd
	for i in range(1, len(a)):
		if (a[i] - a[0]) % 2 == 1:
			even -= 1
			ans1 += odd
			ans2 += even
		else:
			odd -= 1
			ans1 += even
			ans2 += odd
	even = 0
	odd = 0
	a = b[:]
	for i in range(1, len(a)):
		if (a[i] - a[0]) % 2 == 1:
			even += 1
		else:
			odd += 1
	ans1 += even
	ans2 += odd
	for i in range(1, len(a)):
		if (a[i] - a[0]) % 2 == 1:
			even -= 1
			ans1 += odd
			ans2 += even
		else:
			odd -= 1
			ans1 += even
			ans2 += odd
	print(ans1, ans2)
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')

def print(*args, **kwargs):
	(sep, file) = (kwargs.pop('sep', ' '), kwargs.pop('file', sys.stdout))
	at_start = True
	for x in args:
		if not at_start:
			file.write(sep)
		file.write(str(x))
		at_start = False
	file.write(kwargs.pop('end', '\n'))
	if kwargs.pop('flush', False):
		file.flush()
if sys.version_info[0] < 3:
	(sys.stdin, sys.stdout) = (FastIO(sys.stdin), FastIO(sys.stdout))
else:
	(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
main()


cnt = [[0 for col in range(2)] for row in range(2)]
ans = [0 for col in range(2)]
strx = input()
length = len(strx)
for i in range(length):
	if strx[i] == 'a':
		cnt[0][i & 1] = cnt[0][i & 1] + 1
		ans[0] += cnt[0][i & 1 ^ 1]
		ans[1] += cnt[0][i & 1]
	else:
		cnt[1][i & 1] = cnt[1][i & 1] + 1
		ans[0] += cnt[1][i & 1 ^ 1]
		ans[1] += cnt[1][i & 1]
print(ans[0], ans[1])