#![feature(iterator_fold_self)]
use std::collections::HashSet;
use std::hash::Hash;
use std::io::{self, Read};
fn main() {
let mut input = String::new();
io::stdin().read_to_string(&mut input).unwrap();
part1(&input);
part2(&input);
}
fn part1(input: &str) {
let mut vec_set: Vec<HashSet<char>> = Vec::new();
for para in input.split("\n\n") {
let mut set: HashSet<char> = HashSet::new();
for c in para.chars() {
if !c.is_alphabetic() {
continue;
}
set.insert(c);
}
vec_set.push(set);
}
let sum: usize = vec_set.iter().map(|set| set.len()).sum();
println!("{}", sum);
}
fn intersection<'a, T: Clone + Eq + Hash + 'a>(
sets: impl IntoIterator<Item = &'a HashSet<T>>,
) -> Option<HashSet<T>> {
let mut sets = sets.into_iter();
let mut first = sets.next()?.clone();
sets.for_each(|set| first.retain(|elem| set.contains(elem)));
Some(first)
}
fn part2(input: &str) {
let mut acc = 0;
for para in input.split("\n\n") {
let mut vec_set: Vec<HashSet<char>> = Vec::new();
for line in para.lines() {
let mut set: HashSet<char> = HashSet::new();
line.chars().for_each(|c| {
if c.is_alphabetic() {
set.insert(c);
}
});
vec_set.push(set);
}
acc += intersection(&vec_set).unwrap().len();
}
println!("{}", acc);
}