import java.io.BufferedReader;
	import java.io.IOException;
	import java.io.InputStreamReader;
	import java.util.HashMap;
	import java.util.Iterator;
	import java.util.Map;
	import java.util.Map.Entry;
	import java.util.Set;
	import java.util.Vector;
	import java.util.concurrent.atomic.AtomicInteger;

	public class Main {

		/**
		 * Only supports element numbers that are one/two digit(s)...
		 * @param args
		 */
		public static void main(String[] args) {
			try (BufferedReader br = new BufferedReader(new InputStreamReader(System.in))) {
				String line;
				while ((line = br.readLine()) != null) {
					evaluate(line, expand(line));
				}
			} catch (IOException e) {
				e.printStackTrace();
			} catch (NumberFormatException e) {
				e.printStackTrace();
			}
		}

		/**
		 * Counts the number of elements in a chemical formula
		 * @param line: Line consisting of the elements
		 */
		private static void evaluate(String orig, String line) {
			Map<String, AtomicInteger> map = new HashMap<String, AtomicInteger>();
			for (int i = 0; i < line.length(); i++) {
				char cur = line.charAt(i);
				if (i + 1 < line.length()) {
					char next = line.charAt(i + 1);
					if (next >= 'A' && next <= 'Z') {
						String ele = new StringBuilder("").append(cur).toString();
						if (map.containsKey(ele)) {
							map.get(ele).incrementAndGet();
						} else {
							map.put(ele, new AtomicInteger(1));
						}
					} else if (next >= 'a' && next <= 'z') {
						if (i + 2 < line.length()) {
							char possibleNum = line.charAt(i + 2);
							int possibleNum2 = -1;
							if (i + 3 < line.length())
								possibleNum2 = (int) line.charAt(i + 3);
							String ele = new StringBuilder("").append(cur).append(next).toString();
							if (possibleNum >= '0' && possibleNum <= '9') {
								StringBuilder number = new StringBuilder("").append(possibleNum);
								if ((char) possibleNum2 >= '0' && (char) possibleNum2 <= '9') {
									number.append((char) possibleNum2);
									i++;
								}
								int num = Integer.parseInt(number.toString());
								if (map.containsKey(ele)) {
									for (int j = 0; j < num; j++)
										map.get(ele).incrementAndGet();
								} else {
									map.put(ele, new AtomicInteger(num));
								}
								i += 2;
							} else {
								if (map.containsKey(ele)) {
									map.get(ele).incrementAndGet();
								} else {
									map.put(ele, new AtomicInteger(1));
								}
								i++;
							}
						} else {
							String ele = new StringBuilder("").append(cur).append(next).toString();
							if (map.containsKey(ele)) {
								map.get(ele).incrementAndGet();
							} else {
								map.put(ele, new AtomicInteger(1));
								
							}
							i++;
						}
					} else if (next >= '0' && next <= '9') {
						String ele = new StringBuilder("").append(cur).toString();
						StringBuilder number = new StringBuilder("").append(next);
						
						if (i + 2 < line.length()) {
							if (line.charAt(i + 2) >= '0' && line.charAt(i + 2) <= '9') {
								number.append(line.charAt(i + 2));
								i++;
							}
						}
						int num = Integer.parseInt(number.toString());
						if (map.containsKey(cur + "")) {
							for (int j = 0; j < num; j++)
								map.get(ele).incrementAndGet();
						} else {
							map.put(ele, new AtomicInteger(num));
						}
						i++;
					}
				} else {
					// we are on the last element, it must be a single letter
					String ele = new StringBuilder("").append(cur).toString();
					if (map.containsKey(ele)) {
						map.get(ele).incrementAndGet();
					} else {
						map.put(ele, new AtomicInteger(1));
					}
				}
			}
			
			print(orig, map);
		}
		
		/**
		 * Prints the map
		 * @param line
		 * @param map
		 */
		private static void print(String line, Map<String, AtomicInteger> map) {
			System.out.printf("%s\n", line);
			Set<Entry<String, AtomicInteger>> entries = map.entrySet();
			Iterator<Entry<String, AtomicInteger>> it = entries.iterator();
			while (it.hasNext()) {
				Entry<String, AtomicInteger> e = it.next();
				System.out.println("\t" + e.getKey() + ": " + e.getValue().get());
			}
			System.out.printf("\n");
		}

		/**
		 * Method expands 'tougher' chemical compounds consisting of
		 * multiple inner molecules
		 * 
		 * I.E.
		 * 	C4H8(OH)2 -> C4H8OHOH
		 * @param line: Line consisting of the elements
		 * @return String: expanded line
		 * 
		 * PRECONDITION: Parentheses are balanced and contain at least
		 * 				 one element
		 */
		private static String expand(String line) throws NumberFormatException {
			if (!line.contains("("))
				return line;
			// find the indexes of the parentheses and create a
			// stringbuilder object
			Vector<Integer> vec = getOpenClose(line);
			int open = vec.get(0);
			int closed = vec.get(1);
			StringBuilder newString = new StringBuilder("");
			
			// append the beginning of the formula
			for (int i = 0; i < open; i++) {
				newString.append(line.charAt(i));
			}
			
			// repeat the elements in the parenthese's the repeated
			// number of times
			int repeat = Integer.parseInt(line.charAt(closed + 1) + "");
			for (int i = 0; i < repeat; i++) {
				for (int j = open + 1; j < closed; j++) {
					newString.append(line.charAt(j));
				}
			}
			
			// append the rest of the string onto the new string
			for (int i = closed + 2; i < line.length(); i++) {
				newString.append(line.charAt(i));
			}
			
			// recurse through in case we have another pair of parentheses
			return expand(newString.toString());
		}
		
		/**
		 * Gets the index of the inner-most set of parentheses
		 * @param line: line to search
		 * @return Vector<Integer>: vector of the two indexes
		 */
		public static Vector<Integer> getOpenClose(String line) {
			Vector<Integer> vec = new Vector<Integer>();
			int open = -1;
			int closed = -1;
			for (int i = 0; i < line.length(); i++) {
				if (line.charAt(i) == ')') {
					closed = i;
					break;
				}
			}
			stop: for (int i = closed; i >= 0; i--) {
				if (line.charAt(i) == '(') {
					open = i;
					break stop;
				}
			}
			
			vec.add(0, open);
			vec.add(1, closed);
			return vec;
		}
	}