#include <bits/stdc++.h>
using namespace std;
enum lexem { _ta, _taend, _tr, _trend, _td, _tdend, _end };
string s;
struct _curent {
  lexem cur;
  int pos;
  void next();
} curent;
bool checknext(int pos, const string& temp) {
  for (int i = 0; i < temp.size(); i++) {
    if (pos + i >= s.size()) return false;
    if (s[pos + i] != temp[i]) return false;
  }
  return true;
}
void _curent::next() {
  if (pos == s.size()) {
    cur = _end;
    return;
  }
  if (checknext(pos, "<table>")) {
    cur = _ta;
    pos += 7;
    return;
  }
  if (checknext(pos, "</table>")) {
    cur = _taend;
    pos += 8;
    return;
  }
  if (checknext(pos, "<td>")) {
    cur = _td;
    pos += 4;
    return;
  }
  if (checknext(pos, "</td>")) {
    cur = _tdend;
    pos += 5;
    return;
  }
  if (checknext(pos, "<tr>")) {
    cur = _tr;
    pos += 4;
    return;
  }
  if (checknext(pos, "</tr>")) {
    cur = _trend;
    pos += 5;
    return;
  }
  assert(false);
}
vector<int> answer;
int gettd();
int gettr();
void gettable();
int gettd() {
  assert(curent.cur == _td);
  curent.next();
  if (curent.cur == _ta) {
    gettable();
  }
  assert(curent.cur == _tdend);
  curent.next();
  return 1;
}
int gettr() {
  assert(curent.cur == _tr);
  curent.next();
  int cnt = 0;
  while (curent.cur == _td) {
    cnt += gettd();
  }
  assert(curent.cur == _trend);
  curent.next();
  return cnt;
}
void gettable() {
  assert(curent.cur == _ta);
  int ans = 0;
  curent.next();
  while (curent.cur == _tr) {
    ans += gettr();
  }
  assert(curent.cur == _taend);
  curent.next();
  answer.push_back(ans);
}
void read() {
  for (char c; scanf(" %c ", &c) == 1;) s += c;
}
int main() {
  read();
  curent.pos = 0;
  curent.next();
  gettable();
  assert(curent.cur == _end);
  sort(answer.begin(), answer.end());
  for (int i = 0; i < answer.size(); i++)
    printf("%d%c", answer[i], " \n"[i + 1 == answer.size()]);
  return 0;
}
