Problem:
Problem C:
Chinese Classics
Taro, a junior high school student, is working on his homework. Today's homework is to read Chinese classic texts.
As you know, Japanese language shares the (mostly) same Chinese characters but the order of words is a bit different. Therefore the notation called "returning marks" was invented in order to read Chinese classic texts in the order similar to Japanese language.
There are two major types of returning marks: 'Re' mark and jump marks. Also there are a couple of jump marks such as one-two-three marks, top-middle-bottom marks. The marks are attached to letters to describe the reading order of each letter in the Chinese classic text. Figure 1 is an example of a Chinese classic text annotated with returning marks, which are the small letters at the bottom-left of the big Chinese letters.
Figure 1: a Chinese classic text
Taro generalized the concept of jump marks, and summarized the rules to read Chinese classic texts with returning marks as below. Your task is to help Taro by writing a program that interprets Chinese classic texts with returning marks following his rules, and outputs the order of reading of each letter.
When two (or more) rules are applicable in each step, the latter in the list below is applied first, then the former.
Basically letters are read downwards from top to bottom, i.e. the first letter should be read (or skipped) first, and after the
i
-th letter is read or skipped, (
i
+ 1)-th letter is read next.
Each jump mark has a
type
(represented with a string consisting of lower-case letters) and a
number
(represented with a positive integer). A letter with a jump mark whose number is 2 or larger must be skipped.
When the
i
-th letter with a jump mark of type
t
, number
n
is read, and when there exists an unread letter
L
at position less than
i
that has a jump mark of type
t
, number
n
+ 1, then
L
must be read next. If there is no such letter
L
, the (
k
+ 1)-th letter is read, where
k
is the index of the most recently read letter with a jump mark of type
t
, number 1.
A letter with a 'Re' mark must be skipped.
When the
i
-th letter is read and (
i
- 1)-th letter has a 'Re' mark, then (
i
- 1)-th letter must be read next.
No letter may be read twice or more. Once a letter is read, the letter must be skipped in the subsequent steps.
If no letter can be read next, finish reading.
Let's see the first case of the sample input. We begin reading with the first letter because of the rule 1. However, since the first letter has a jump mark '
onetwo2
', we must follow the rule 2 and skip the letter. Therefore the second letter, which has no returning mark, will be read first.
Then the third letter will be read. The third letter has a jump mark '
onetwo1
', so we must follow rule 3 and read a letter with a jump mark `onetwo2' next, if exists. The first letter has the exact jump mark, so it will be read third. Similarly, the fifth letter is read fourth, and then the sixth letter is read.
Although we have tw
...(truncated)

Submitted solutions:

code_snippet: // AOJ #2322 Chinese Classics
// 2025.3.1

#include <bits/stdc++.h>
using namespace std;

#define gc() getchar_unlocked()
#define pc(c) putchar_unlocked(c)

int Cin() {  // 整数の入力
	int n = 0, c = gc();
	do n = 10*n + (c & 0xf), c = gc(); while (c >= '0');
	return n;
}

char temp[100];
string Cins() { // 文字列の入力　スペース以下の文字で入力終了
    char *s = temp;
	do *s = gc();
	while (*s++ > ' ');
	*(s-1) = 0;
    string input(temp); // 文字配列からstringを作成
    return input;
}

void Cout(int n) { // 整数の表示（出力）
	char b[30];
	if (!n) pc('0');
	else {
		if (n < 0) pc('-'), n = -n;
		int i = 0; while (n) b[i++] = n % 10 + '0', n /= 10;
		while (i--) pc(b[i]);
	}
	pc('\n');
}

struct MarkInfo {
    bool hasRe;
    string jumpType;
    int jumpNum;
    bool read;
};

const int NOT_JUMP = -1;

vector<MarkInfo> info;
int N;
vector<int> readOrder;
unordered_map<string,int> lastReadOfType;

int cur = 1;

pair<string,int> parseJumpMark(const string &s) {
    if (s == "-") return make_pair("", NOT_JUMP);
    bool hasV = false;
    string tmp = s;
    if (!tmp.empty() && tmp.back() == 'v') {
        hasV = true;
        tmp.pop_back();
    }
    int pos = (int)tmp.size() - 1;
    while (pos >= 0 && isdigit(tmp[pos])) pos--;
    string t = tmp.substr(0, pos+1);
    string numStr = tmp.substr(pos+1);
    int num = stoi(numStr);
    return make_pair(t, num);
}

void readLetter(int i) {
    if (info[i].read) return;

    info[i].read = true;
    readOrder.push_back(i);

    if (i > 1) {
        if (!info[i-1].read && info[i-1].hasRe) readLetter(i-1);
    }

    if (info[i].jumpNum != NOT_JUMP) {
        string t = info[i].jumpType;
        int n = info[i].jumpNum;
        int candidate = -1;
        for (int j = i-1; j >= 1; j--) {
            if (!info[j].read &&
                info[j].jumpType == t &&
                info[j].jumpNum == (n+1)) {
                candidate = j;
                break;
            }
        }
        if (candidate != -1) readLetter(candidate);
        else {
            if (lastReadOfType.find(t) != lastReadOfType.end()) {
                int k = lastReadOfType[t];
                if (1 <= k+1 && k+1 <= N) cur = min(cur, k+1);
            }
        }
        if (n == 1) lastReadOfType[t] = i;
    }
}

int main(){
    while (true) {
        N = Cin();
        if (N == 0) break;

        info.assign(N+1, MarkInfo());
        readOrder.clear();
        lastReadOfType.clear();
        cur = 1;

        for (int i = 1; i <= N; i++) {
            string s = Cins();
            info[i].hasRe = false;
            info[i].jumpType = "";
            info[i].jumpNum = NOT_JUMP;
            info[i].read = false;

            if (s == "-") continue;
            if (s == "v") {
                info[i].hasRe = true;
                continue;
            }
            auto p = parseJumpMark(s);
            info[i].jumpType = p.first;
            info[i].jumpNum  = p.second;
            if (!s.empty() && s.back() == 'v') info[i].hasRe = true;
        }
        while (true) {
            bool found = false;
            for (; cur <= N; cur++) {
                if (!info[cur].read) {
                    if (info[cur].hasRe) continue;
                    if (info[cur].jumpNum >= 2) continue;
                    readLetter(cur);
                    found = true;
                    cur++;
                    break;
                }
            }
            if (!found) break;
        }
        for (int i = 0; i < (int)readOrder.size(); i++) Cout(readOrder[i]);
    }
    return 0;
}
accuracy: 1
time_ms: 100
memory_kb: 5444
final_rank: 12

code_snippet: // AOJ #2322 Chinese Classics
// 2025.3.1

#include <bits/stdc++.h>
using namespace std;

struct MarkInfo {
    bool hasRe;
    string jumpType;
    int jumpNum;
    bool read;
};

const int NOT_JUMP = -1;

vector<MarkInfo> info;
int N;
vector<int> readOrder;
unordered_map<string,int> lastReadOfType;

int cur = 1;

pair<string,int> parseJumpMark(const string &s) {
    if (s == "-") return make_pair("", NOT_JUMP);
    bool hasV = false;
    string tmp = s;
    if (!tmp.empty() && tmp.back() == 'v') {
        hasV = true;
        tmp.pop_back();
    }
    int pos = (int)tmp.size() - 1;
    while (pos >= 0 && isdigit(tmp[pos])) pos--;
    string t = tmp.substr(0, pos+1);
    string numStr = tmp.substr(pos+1);
    int num = stoi(numStr);
    return make_pair(t, num);
}

void readLetter(int i) {
    if (info[i].read) return;

    info[i].read = true;
    readOrder.push_back(i);

    if (i > 1) {
        if (!info[i-1].read && info[i-1].hasRe) readLetter(i-1);
    }

    if (info[i].jumpNum != NOT_JUMP) {
        string t = info[i].jumpType;
        int n = info[i].jumpNum;
        int candidate = -1;
        for (int j = i-1; j >= 1; j--) {
            if (!info[j].read &&
                info[j].jumpType == t &&
                info[j].jumpNum == (n+1)) {
                candidate = j;
                break;
            }
        }
        if (candidate != -1) readLetter(candidate);
        else {
            if (lastReadOfType.find(t) != lastReadOfType.end()) {
                int k = lastReadOfType[t];
                if (1 <= k+1 && k+1 <= N) cur = min(cur, k+1);
            }
        }
        if (n == 1) lastReadOfType[t] = i;
    }
}

int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);

    while (true) {
        cin >> N;
        if (N == 0) break;

        info.assign(N+1, MarkInfo());
        readOrder.clear();
        lastReadOfType.clear();
        cur = 1;

        for (int i = 1; i <= N; i++) {
            string s;
            cin >> s;
            info[i].hasRe = false;
            info[i].jumpType = "";
            info[i].jumpNum = NOT_JUMP;
            info[i].read = false;

            if (s == "-") continue;
            if (s == "v") {
                info[i].hasRe = true;
                continue;
            }
            auto p = parseJumpMark(s);
            info[i].jumpType = p.first;
            info[i].jumpNum  = p.second;
            if (!s.empty() && s.back() == 'v') info[i].hasRe = true;
        }
        while (true) {
            bool found = false;
            for (; cur <= N; cur++) {
                if (!info[cur].read) {
                    if (info[cur].hasRe) continue;
                    if (info[cur].jumpNum >= 2) continue;
                    readLetter(cur);
                    found = true;
                    cur++;
                    break;
                }
            }
            if (!found) break;
        }

        for (int i = 0; i < (int)readOrder.size(); i++) {
            cout << readOrder[i] << endl;
        }
    }
    return 0;
}
accuracy: 1
time_ms: 150
memory_kb: 5760
final_rank: 15

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 4000000000000000000 //オーバーフローに注意
#define MOD 1000000007
#define EPS 0.000000001




#define SIZE 10005

int N;
string word[SIZE];
bool used[SIZE],is_Re[SIZE];
int label[SIZE];
map<pair<string,int>,vector<int>> MAP;


bool is_word(char ch){

	return ch >= 'a' && ch <= 'z';
}

void dfs(int ind){

	printf("%d\n",ind+1);
	used[ind] = true;

	if(ind > 0 && !used[ind-1] && is_Re[ind-1]){

		dfs(ind-1);
	}

	if(label[ind] == -1)return;

	vector<int> vec = MAP[make_pair(word[ind],label[ind]+1)];
	if(vec.size() == 0)return;

	int loc = lower_bound(vec.begin(),vec.end(),ind)-vec.begin();

	if(loc == 0)return;

	loc--;
	int next = vec[loc];

	vec.erase(vec.begin()+loc);

	MAP[make_pair(word[ind],label[ind]+1)] = vec;

	dfs(next);
}

void func(){

	MAP.clear();

	vector<int> vec;
	for(int i = 0; i < N; i++){

		vec.push_back(i);
		used[i] = false;
		is_Re[i] = false;
		label[i] = -1;
	}

	for(int i = 0; i < N; i++){

		cin >> word[i];

		if(word[i].length() == 1){

			if(word[i][0] == 'v'){

				is_Re[i] = true;
			}

			continue;
		}

		int len = word[i].length();
		if(word[i][len-1] == 'v'){

			is_Re[i] = true;
			word[i] = word[i].substr(0,len-1);
			len--;
		}

		string tmp_str = "";

		int index = 0;

		for(; index < len && is_word(word[i][index]); index++){

			tmp_str += word[i][index];
		}

		int num = 0;
		for(int k = index; k < len; k++){

			num = 10*num + (word[i][k]-'0');
		}

		MAP[make_pair(tmp_str,num)].push_back(i);

		word[i] = tmp_str;
		label[i] = num;
	}

	for(int i = 0; i < N; i++){
		if(used[i]||label[i] >= 2 ||is_Re[i])continue;

		dfs(i);
	}
}

int main(){

	while(true){

		scanf("%d",&N);
		if(N == 0)break;

		func();
	}

	return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 9484
final_rank: 18

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 4000000000000000000 //オーバーフローに注意
#define MOD 1000000007
#define EPS 0.000000001




#define SIZE 10005

int N;
string word[SIZE];
bool used[SIZE],is_Re[SIZE];
int label[SIZE];
map<pair<string,int>,vector<int>> MAP;


bool is_word(char ch){

	return ch >= 'a' && ch <= 'z';
}

void dfs(int ind){

	printf("%d\n",ind+1);
	used[ind] = true;

	if(ind > 0 && !used[ind-1] && is_Re[ind-1]){

		dfs(ind-1);
	}

	if(label[ind] == -1)return;

	vector<int> vec = MAP[make_pair(word[ind],label[ind]+1)];
	if(vec.size() == 0)return;

	int loc = lower_bound(vec.begin(),vec.end(),ind)-vec.begin();

	if(loc == 0)return;

	loc--;
	int next = vec[loc];

	vec.erase(vec.begin()+loc);

	MAP[make_pair(word[ind],label[ind]+1)] = vec;

	dfs(next);
}

void func(){

	MAP.clear();
	//MAP[(ジャンプ文字,番号)] = 行番号

	vector<int> vec;
	for(int i = 0; i < N; i++){

		vec.push_back(i);
		used[i] = false;
		is_Re[i] = false;
		label[i] = -1;
	}

	for(int i = 0; i < N; i++){

		cin >> word[i];

		if(word[i].length() == 1){

			if(word[i][0] == 'v'){

				is_Re[i] = true;
			}

			continue;
		}

		int len = word[i].length();
		if(word[i][len-1] == 'v'){

			is_Re[i] = true;
			word[i] = word[i].substr(0,len-1);
			len--;
		}

		string tmp_str = "";

		int index = 0;

		for(; index < len && is_word(word[i][index]); index++){

			tmp_str += word[i][index];
		}

		int num = 0;
		for(int k = index; k < len; k++){

			num = 10*num + (word[i][k]-'0');
		}

		MAP[make_pair(tmp_str,num)].push_back(i); //★同じジャンプ命令が複数回出現し得る★

		word[i] = tmp_str;
		label[i] = num;

		//printf("i:%d word:%s label:%d\n",i,tmp_str.c_str(),num);
	}

	for(int i = 0; i < N; i++){
		if(used[i]||label[i] >= 2 ||is_Re[i])continue;

		dfs(i);
	}


	//次に読める文字がなければ終了

	//ある文字を読むのは1回まで。既読文字は以後読み飛ばす

	//i番目の文字を読んで、(i-1)番目の文字に[Re]がついていたら、次に(i-1)番目の文字を読む

	//[Re]マーク付きの文字は読み飛ばす

	/*
	 * i行目にタイプtの番号nのジャンプ命令があり、i-1行目以前に未読の[タイプtの番号n+1]のジャンプ命令が
	 * あれば、i行目の次にそれを読む。もしそのような命令がなければ、最後に読んだタイプtの命令の次の文字を読む
	 * (数字1の場合は、次の文字を読む)
	 * */

	/*
	 *番号が2以上のジャンプマークは読み飛ばす
	 *
	 **/



}

int main(){

	while(true){

		scanf("%d",&N);
		if(N == 0)break;

		func();
	}

	return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 9368
final_rank: 17

code_snippet: #include <bits/stdc++.h>

#define rep(i,n) for(int i=0; i<n; i++)
#define reep(i,a,b) for(int i=a; i<b; i++)

using namespace std;


void solve(int n){
	vector<string> v(n);
	rep(i,n){
		cin>>v[i];
	}
	map<string,int> used;
	vector<int> type(n),num(n);
	vector<int> par(n,-1);
	vector<int> start(n, 1);
	rep(i,n){
		string t = v[i];
		int val = 0;
		int pp = 1;
		if(t.back() == 'v'){
			t = t.substr(0, t.size()-1);
			par[i+1] = i;
			start[i] = 0;
		}
		if(t.size() == 0){
			continue;
		}
		if(t == "-"){
			continue;
		}
		int len = t.size();
		while(isdigit(t[len-1])){
			len--;
			val += pp*(t[len]-'0');
			pp *= 10;
		}
		t = t.substr(0, len);
		if(val > 1){
			start[i] = 0;
		}
		if(used.count(t) == 0){
			if(val > 1){
				used[t] = i;
			}
		}
		else{
			par[i] = used[t];
			if(val > 1){
				used[t] = i;
			}
			else{
				used.erase(t);
			}
		}
	}
	/*
	rep(i,n){
		cout<<i<<" "<<par[i]<<endl;
	}
	cout<<endl;
	*/
	int pos = 0;
	while(pos < n){
		if(start[pos]){
			int t = pos;
			while(t >= 0){
				cout<<t+1<<endl;
				t = par[t];
			}			
		}
		pos++;
	}
}			
					



int main(){
	int n;
	while(cin>>n, n){
		solve(n);
	}
}
accuracy: 1
time_ms: 100
memory_kb: 4348
final_rank: 11

code_snippet: /*
 * 2322.cc: Chinese Classics
 */

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<string>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<list>
#include<queue>
#include<deque>
#include<algorithm>
#include<numeric>
#include<utility>
#include<complex>
#include<functional>
 
using namespace std;

/* constant */

const int MAX_N = 10000;

/* typedef */

typedef vector<int> vi;
typedef map<string,int> msi;

/* global variables */

bool res[MAX_N], used[MAX_N];
msi types;
int tn, ts[MAX_N], nums[MAX_N];
vi jmps[MAX_N];

/* subroutines */

void read(int k) {
  if (used[k]) return;
  printf("%d\n", k + 1);
  used[k] = true;
    
  if (k > 0 && res[k - 1]) read(k - 1);
  if (nums[k] > 0) {
    vi &jv = jmps[ts[k]];
    if (jv.size() > nums[k]) read(jv[nums[k]]);
  }
}

void parse(string &s, string &type, int &num, bool &re) {
  type = "";
  num = 0;
  re = false;
  if (s == "-") return;
  
  int n = s.size();
  
  if (s[n - 1] == 'v') {
    n--;
    re = true;
  }

  int pos = 0;
  while (pos < n && s[pos] >= 'a' && s[pos] <= 'z')
    type += s[pos++];
  while (pos < n && s[pos] >= '0' && s[pos] <= '9')
    num = num * 10 + (s[pos++] - '0');
}

/* main */

int main() {
  for (;;) {
    int n;
    cin >> n;
    if (n == 0) break;

    memset(res, false, sizeof(res));
    memset(used, false, sizeof(used));
    memset(ts, -1, sizeof(ts));
    memset(nums, 0, sizeof(nums));
    types.clear();
    tn = 0;

    for (int i = 0; i < n; i++) {
      string s, type;
      cin >> s;
      parse(s, type, nums[i], res[i]);

      if (nums[i] > 0) {
	msi::iterator mit = types.find(type);
	if (mit == types.end() || jmps[mit->second][0] >= 0) {
	  ts[i] = types[type] = tn++;
	  jmps[ts[i]].assign(nums[i], -1);
	  jmps[ts[i]][nums[i] - 1] = i;
	}
	else {
	  ts[i] = mit->second;
	  jmps[ts[i]][nums[i] - 1] = i;
	}
      }
    }
    
    for (int pc = 0; pc < n; pc++)
      if (! res[pc] && nums[pc] <= 1) read(pc);
  }

  return 0;
}
accuracy: 1
time_ms: 70
memory_kb: 2552
final_rank: 3

code_snippet: #pragma comment(linker, "/STACK:500000000") 
#include <functional>
#include <algorithm> 
#include <iostream> 
#include <string.h> 
#include <stdlib.h>
#include <limits.h>
#include <numeric>
#include <sstream> 
#include <fstream>
#include <ctype.h> 
#include <stdio.h> 
#include <bitset>
#include <vector> 
#include <string> 
#include <math.h> 
#include <time.h> 
#include <queue> 
#include <stack> 
#include <list>
#include <map> 
#include <set> 
#define Int long long 
#define eps 1e-9
using namespace std;
typedef pair<int, int> pii;

#define MAXN 11111

int N;
string mark[MAXN];
int used[MAXN], nex[MAXN];
map<string, int> M;
vector<int> ans;

void read(int cur)
{
	while (!used[cur])
	{
		ans.push_back(cur);
		used[cur] = 1;
		if (nex[cur] == -1)
			break;
		cur = nex[cur];
	}
}

int main()
{
	while (cin >> N && N)
	{
		for (int i = 0; i < N; i++)
			cin >> mark[i];
		fill(used, used + 10010, 0);
		fill(nex, nex + 10010, -1);
		M.clear();
		ans.clear();

		for (int i = 0; i < N; i++)
		{
			if (mark[i] == "-")
				read(i);
			else if (mark[i] == "v")
				nex[i + 1] = i;
			else
			{
				string type;
				int number = 0;
				int x = 0;
				while (islower(mark[i][x]))
				{
					type += mark[i][x];
					x++;
				}
				while (x<mark[i].size() && isdigit(mark[i][x]))
				{
					number = number * 10 + mark[i][x] - '0';
					x++;
				}
				if (M.find(type) != M.end())
					nex[i] = M[type];
				
				if (number > 1)
					M[type] = i;
				else 
					M.erase(type);

				if (x < mark[i].size())
					nex[i + 1] = i;
				else if (number == 1)
					read(i);
			}
		}
		for (int i = 0; i < N; i++)
			cout << ans[i] + 1 << endl;
	}
}
accuracy: 1
time_ms: 140
memory_kb: 2856
final_rank: 7

code_snippet: #define _CRT_SECURE_NO_WARNINGS
#pragma comment(linker, "/STACK:500000000") 
#include <functional>
#include <algorithm>
#include <iostream> 
#include <string.h> 
#include <stdlib.h>
#include <complex>
#include <sstream> 
#include <numeric>
#include <ctype.h> 
#include <stdio.h> 
#include <bitset>
#include <vector> 
#include <string> 
#include <math.h> 
#include <time.h> 
#include <queue> 
#include <stack> 
#include <list>
#include <map> 
#include <set> 
#define Int long long 
#define INF 0x3F3F3F3F 
#define eps 1e-9
using namespace std;


#pragma comment(linker, "/STACK:500000000") 
#include <functional>
#include <algorithm> 
#include <iostream> 
#include <string.h> 
#include <stdlib.h>
#include <limits.h>
#include <numeric>
#include <sstream> 
#include <fstream>
#include <ctype.h> 
#include <stdio.h> 
#include <bitset>
#include <vector> 
#include <string> 
#include <math.h> 
#include <time.h> 
#include <queue> 
#include <stack> 
#include <list>
#include <map> 
#include <set> 
#define Int long long 
#define eps 1e-9
using namespace std;
typedef pair<int, int> pii;

#define MAXN 11111

int N;
string mark[MAXN];
int used[MAXN], nex[MAXN];
map<string, int> M;
vector<int> ans;

void read(int cur)
{
	while (!used[cur])
	{
		ans.push_back(cur);
		used[cur] = 1;
		if (nex[cur] == -1)
			break;
		cur = nex[cur];
	}
}

int main()
{
	while (cin >> N && N)
	{
		for (int i = 0; i < N; i++)
			cin >> mark[i];
		fill(used, used + 10010, 0);
		fill(nex, nex + 10010, -1);
		M.clear();
		ans.clear();

		for (int i = 0; i < N; i++)
		{
			if (mark[i] == "-")
				read(i);
			else if (mark[i] == "v")
				nex[i + 1] = i;
			else
			{
				string type;
				int number = 0;
				int x = 0;
				while (islower(mark[i][x]))
				{
					type += mark[i][x];
					x++;
				}
				while (x<mark[i].size() && isdigit(mark[i][x]))
				{
					number = number * 10 + mark[i][x] - '0';
					x++;
				}
				if (M.find(type) != M.end())
					nex[i] = M[type];
				
				if (number > 1)
					M[type] = i;
				else 
					M.erase(type);

				if (x < mark[i].size())
					nex[i + 1] = i;
				else if (number == 1)
					read(i);
			}
		}
		for (int i = 0; i < N; i++)
			cout << ans[i] + 1 << endl;
	}
}
accuracy: 1
time_ms: 130
memory_kb: 2860
final_rank: 6

code_snippet: #include <vector>
#include <list>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <deque>
#include <algorithm>
#include <utility>
#include <functional>
#include <sstream>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <ctime>
#include <climits>
#include <cassert>
#include <memory>
#include <time.h>
using namespace std;
inline int toInt(string s) {int v; istringstream sin(s);sin>>v;return v;}
template<class T> inline string toString(T x) {ostringstream sout;sout<<x;return sout.str();}
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<string> vs;
typedef pair<int, int> pii;
typedef long long ll;
#define ALL(a) (a).begin(),(a).end()
#define RALL(a) (a).rbegin(),(a).rend()
#define EXIST(s,e) ((s).find(e)!=(s).end())
#define EXIST2(s,e) (find(ALL(s),(e))!=(s).end())
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,n) FOR(i,0,n)
const double EPS = 1e-9;
const double PI = acos(-1.0);


void read(int i,vi &ans,vi &done,bool &has_read){
	ans.push_back(i);
	done[i]=1;
	has_read=true;
}

pair<string,int> get_type_and_num(vs &marks,int i){
	string type;
	int num;
	REP(j,marks[i].size()){
		if(isdigit(marks[i][j])){
			type=marks[i].substr(0,j);
			num=toInt(marks[i].substr(j));
			break;
		}
	}
	return make_pair(type,num);
}

int main(){
	int n;
	while(cin>>n,n){
		vs marks(n);
		map<string,map<int,vi > > pos;
		REP(i,n){
			cin>>marks[i];
			if(marks[i]!="v"&&marks[i]!="-"){
				pair<string,int> p=get_type_and_num(marks,i);
				pos[p.first][p.second].push_back(i);
			}
		}
		int cur=0;
		int last=0;
		bool has_read=false;
		vi done(n);
		vi ans;
		int i=0;
		while(i<n){
			if(!has_read&&done[i]){
				//6. No letter may be read twice or more. Once a letter is read, the letter must be skipped in the subsequent steps. 
				i++;
				continue;
			}
			if(has_read&&i>0&&marks[i-1][marks[i-1].size()-1]=='v'){
				//5. When the i-th letter is read and (i - 1)-th letter has a 'Re' mark, then (i - 1)-th letter must be read next.
				read(i-1,ans,done,has_read);
				i--;
				continue;
			}
			if(!has_read&&marks[i][marks[i].size()-1]=='v'){
				//4. A letter with a 'Re' mark must be skipped.
				i++;
				has_read=false;
				continue;
			}
			if(marks[i]!="-"){
				pair<string,int> p=get_type_and_num(marks,i);
				string type=p.first;
				int num=p.second;
				if(has_read){
					//3. When the i-th letter with a jump mark of type t, number n is read, and when there exists an unread letter L at position less than i that has a jump mark of type t, number n + 1, then L must be read next. If there is no such letter L, the (k + 1)-th letter is read, where k is the index of the most recently read letter with a jump mark of type t, number 1.
					vi &v=pos[type][num+1];
					vi::iterator it=lower_bound(ALL(v),i);
					if(it==v.begin()){
						i=last+1;
						has_read=false;
						continue;
					}else{
						i=*(it-1);
						read(i,ans,done,has_read);
						continue;
					}
				}else{
					//2. Each jump mark has a type (represented with a string consisting of lower-case letters) and a number (represented with a positive integer). A letter with a jump mark whose number is 2 or larger must be skipped. 
					if(num==1){
						last=i;
						read(i,ans,done,has_read);
						continue;
					}else{
						i++;
						has_read=false;
						continue;
					}
				}
			}
			if(marks[i]=="-"){
				//1. Basically letters are read downwards from top to bottom, i.e. the first letter should be read (or skipped) first, and after the i-th letter is read or skipped, (i + 1)-th letter is read next. 
				if(has_read){
					i++;
					has_read=false;
					continue;
				}else{
					read(i,ans,done,has_read);
					continue;
				}
			}
		}
		REP(i,ans.size()){
			cout<<ans[i]+1<<endl;
		}
	}
}
accuracy: 1
time_ms: 230
memory_kb: 4284
final_rank: 16

code_snippet: #include<iostream>
#include<stack>
#include<map>
#include<cstdio>
#include<utility>
#include<vector>
#include<algorithm>

using namespace std;

pair<string,int> split(string s){
  char t[99];
  int d;
  sscanf(s.c_str(),"%[a-z]%d",t,&d);
  return make_pair(string(t),d);
}

int main(){
  for(int N;cin>>N,N;){
    int cnt=0;
    stack<int> s;
    string m[10001];
    map<pair<string,int>,vector<int> > mmap;
    for(int i=1;i<=N;i++){
      cin>>m[i];
      if(m[i].back()=='v'){
      }else if(m[i].size()>1){
	auto p=split(m[i]);
	if(p.second==1){
	  s.push(i);
	}else{
	  mmap[p].push_back(i);
	}
      }else{
	s.push(i);
      }
      while(!s.empty()){
	int x=s.top();
	s.pop();
	if(x>0){
	  cout<<x<<endl;
	  cnt++;
	  if(m[x].size()>1){
	    s.push(-x);
	  }
	  if(x&&m[x-1].back()=='v'){
	    s.push(x-1);
	  }
	}else{
	  x=-x;
	  auto p=split(m[x]);
	  p.second++;
	  if(!mmap[p].empty()){
	    auto it=upper_bound(begin(mmap[p]),end(mmap[p]),x);
	    if(it!=begin(mmap[p])){
	      s.push(*--it);
	      mmap[p].erase(it);
	    }
	  }
	}
      }
    }
    //    cerr<<cnt<<' '<<N<<endl;
  }
}
accuracy: 1
time_ms: 220
memory_kb: 3636
final_rank: 14

code_snippet: #include <bits/stdc++.h>
using namespace std;

#define dump(n) cout<<"# "<<#n<<'='<<(n)<<endl
#define repi(i,a,b) for(int i=int(a);i<int(b);i++)
#define peri(i,a,b) for(int i=int(b);i-->int(a);)
#define rep(i,n) repi(i,0,n)
#define per(i,n) peri(i,0,n)
#define all(c) begin(c),end(c)
#define mp make_pair
#define mt make_tuple

typedef unsigned int uint;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<double> vd;
typedef vector<vd> vvd;
typedef vector<string> vs;

const int INF=1e9;
const int MOD=1e9+7;
const double EPS=1e-9;

template<typename T1,typename T2>
ostream& operator<<(ostream& os,const pair<T1,T2>& p){
	return os<<'('<<p.first<<','<<p.second<<')';
}
template<typename T>
ostream& operator<<(ostream& os,const vector<T>& a){
	os<<'[';
	rep(i,a.size()) os<<(i?" ":"")<<a[i];
	return os<<']';
}

int main()
{
	for(int n;cin>>n && n;){
		vs lines(n);
		rep(i,n) cin>>lines[i];
		
		vi prev(n,-1);
		rep(i,n) if(lines[i].back()=='v'){
			prev[i]=i+1;
			//lines[i].pop_back();
			lines[i].erase(end(lines[i])-1);
		}
		map<string,int> f;
		per(i,n) if(lines[i].size() && isdigit(lines[i].back()))
			rep(j,lines[i].size())
				if(isdigit(lines[i][j])){
					string tag=lines[i].substr(0,j);
					int x=stoi(lines[i].substr(j));
					if(x>1) prev[i]=f[tag];
					f[tag]=i;
				}
		
		vvi pathes;
		vi vis(n);
		rep(i,n) if(!vis[i]){
			vi path;
			for(int v=i;v!=-1;v=prev[v]){
				path.push_back(v);
				vis[v]=1;
			}
			reverse(all(path));
			pathes.push_back(path);
		}
		sort(all(pathes));
		
		rep(i,pathes.size()) rep(j,pathes[i].size())
			cout<<pathes[i][j]+1<<endl;
	}
}
accuracy: 1
time_ms: 140
memory_kb: 2956
final_rank: 9

code_snippet: #include <cstdio>
#include <cstdlib>
#include <cstring>
#include <climits>
#include <cmath>
#include <ctime>
#include <cassert>
#include <iostream>
#include <fstream>
#include <sstream>
#include <iomanip>
#include <complex>
#include <string>
#include <vector>
#include <list>
#include <deque>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <bitset>
#include <iterator>
#include <functional>
#include <utility>
#include <algorithm>
#include <numeric>
#include <typeinfo>

using namespace std;

#define dump(n) cerr<<"# "<<#n<<"="<<(n)<<endl
#define repi(i,a,b) for(int i=int(a);i<int(b);i++)
#define rep(i,n) repi(i,0,n)
#define iter(c) __typeof((c).begin())
#define foreach(i,c) for(iter(c) i=(c).begin();i!=(c).end();++i)
#define allof(c) (c).begin(),(c).end()
#define mp make_pair

typedef unsigned int uint;
typedef long long ll;
typedef unsigned long long ull;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<double> vd;
typedef vector<vd> vvd;
typedef vector<string> vs;
typedef pair<int,int> pii;

int main()
{
	char buf[21];
	for(int n;scanf("%d ",&n),n;){
		vs lines(n);
		rep(i,n){
			gets(buf);
			lines[i]=buf;
		}
		
		vs tags(n);
		vi marks(n),isre(n);
		rep(i,n){
			int j=lines[i].size()-1;
			if(lines[i][j]=='v'){
				isre[i]=1;
				j--;
			}
			int k=j;
			while(k>=0 && isdigit(lines[i][k]))
				k--;
			k++;
			if(k<=j)
				marks[i]=atoi(lines[i].c_str()+k);
			tags[i]=lines[i].substr(0,k);
		}
		
		map<string,int> q;
		vi prev(n,-1);
		for(int i=n;i--;){
			if(marks[i]>0){
				int& cur=q[tags[i]];
				if(marks[i]>1)
					prev[i]=cur;
				cur=i;
			}
		}
		rep(i,n)
			if(isre[i])
				prev[i]=i+1;
		
		vvi paths;
		vi flgs(n);
		rep(i,n){
			if(flgs[i])
				continue;
			vi path;
			for(int j=i;j!=-1;j=prev[j]){
				path.push_back(j);
				flgs[j]=1;
			}
			reverse(allof(path));
			paths.push_back(path);
		}
		
		sort(allof(paths));
		
		vi perm(n);
		int k=0;
		rep(i,paths.size()) rep(j,paths[i].size())
			perm[k++]=paths[i][j];
		
		rep(i,n)
			printf("%d\n",perm[i]+1);
	}
	
	return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 3208
final_rank: 2

code_snippet: #include <algorithm>
#include <cctype>
#include <iostream>
#include <map>
#include <vector>
using namespace std;

pair<string, int> parse(const string &letter) {
	int idx = 0;
	while(isalpha(letter[idx])) ++idx;
	return make_pair(letter.substr(0, idx), stoi(letter.substr(idx)));
}

void print(int idx, const vector<int> &next) {
	while(next[idx] != idx) {
		cout << idx + 1 << "\n";
		idx = next[idx];
	}
	cout << idx + 1 << "\n";
}

int main() {
	cin.tie(nullptr);
	ios::sync_with_stdio(false);

	for(int n; cin >> n && n;) {
		map<pair<string, int>, int> jump;
		vector<int> next(n);

		iota(next.begin(), next.end(), 0);

		for(int i = 0; i < n; ++i) {
			string letter;
			cin >> letter;

			if(letter == "-") {
				print(i, next);
			}
			else {
				const bool re_mark = letter.back() == 'v';
				if(re_mark) {
					next[i + 1] = i;
					letter.erase(letter.begin() + letter.size() - 1);
				}

				if(letter.size() > 1) {
					const auto cur = parse(letter);
					const auto dest = make_pair(cur.first, cur.second + 1);
					const auto it = jump.find(dest);

					if(it != jump.end()) {
						const int dest_idx = it->second;
						jump.erase(it);
						next[i] = dest_idx;
					}

					if(cur.second > 1) {
						jump.insert(make_pair(cur, i));
					}
					else if(!re_mark) {
						print(i, next);
					}
				}
			}
		}
	}

	return EXIT_SUCCESS;
}
accuracy: 1
time_ms: 30
memory_kb: 1908
final_rank: 1

code_snippet: #include <algorithm>
#include <cctype>
#include <iostream>
#include <map>
#include <vector>
using namespace std;

pair<string, int> parse(const string &letter) {
	int idx = 0;
	while(isalpha(letter[idx])) ++idx;
	return {letter.substr(0, idx), stoi(letter.substr(idx))};
}

void print(int idx, const vector<int> &next) {
	while(next[idx] != idx) {
		cout << idx + 1 << "\n";
		idx = next[idx];
	}
	cout << idx + 1 << "\n";
}

int main() {
	for(int n; cin >> n && n;) {
		map<pair<string, int>, int> jump;
		vector<int> next(n);

		iota(next.begin(), next.end(), 0);

		for(int i = 0; i < n; ++i) {
			string letter;
			cin >> letter;

			if(letter == "-") {
				print(i, next);
			}
			else {
				const bool re_mark = letter.back() == 'v';
				if(re_mark) {
					next[i + 1] = i;
					letter.erase(letter.begin() + letter.size() - 1);
				}

				if(letter.size() > 1) {
					const auto cur = parse(letter);
					const auto dest = make_pair(cur.first, cur.second + 1);

					if(jump.count(dest)) {
						const int dest_idx = jump.at(dest);
						jump.erase(dest);
						next[i] = dest_idx;
					}

					if(cur.second > 1) {
						jump[cur] = i;
					}
					else if(!re_mark) {
						print(i, next);
					}
				}
			}
		}
	}

	return EXIT_SUCCESS;
}
accuracy: 1
time_ms: 100
memory_kb: 1896
final_rank: 4

code_snippet: #include<iostream>
#include<cstdlib>
#include<sstream>

using namespace std;

#define rep(i, n) for (int i = 0; i < int(n); ++i)

int main() {
  while (true){
    int n;
    cin >> n;
    if (n == 0) break;
    string str[n];
    rep (i, n) cin >> str[i];
    rep (i, n) if (str[i] == "-") str[i] = "";
    bool re[n];
    rep (i, n) {
      if (str[i][str[i].size() - 1] == 'v') {
	re[i] = true;
	str[i] = str[i].substr(0, str[i].size() - 1);
      } else {
	re[i] = false;
      }
    }
    int num[n];
    rep (i, n) num[i] = 0;
    rep (i, n) if (str[i].size()) {
      int k = 0;
      while (isalpha(str[i][k])) ++k;
      stringstream ss;
      ss << str[i].substr(k);
      ss >> num[i];
      str[i] = str[i].substr(0, k);
    }
    bool used[n];
    rep (i, n) used[i] = false;
    //rep (i, n) cerr << str[i] << " " << num[i] << " " << re[i] << endl;
    int pos = -1;
    while (true) {
      ++pos;
      if (pos == n) break;
      if (used[pos]) continue;
      if (re[pos]) continue;
      if (num[pos] > 1) continue;
      cout << pos + 1 << endl;
      used[pos] = true;
      int nn = num[pos];
      if (nn == 1) {
	int p = pos;
	nn = 2;
	while (p > 0) {
	  --p;
	  if (used[p]) continue;
	  if (str[pos] != str[p]) continue;
	  if (nn != num[p]) break;
	  ++nn;
	  pos = p;
	  used[pos] = true;
	  cout << p + 1 << endl;
	}
      }
      if (pos != 0 && re[pos - 1]) {
	pos -= 2;
	re[pos + 1] = false;
      }
    }
  }
  return 0;
}
accuracy: 1
time_ms: 360
memory_kb: 2164
final_rank: 19

code_snippet: #include <iostream>
#include <algorithm>
#include <cstdlib>
#include <vector>
#include <map>
#include <stack>
#include <cstdio>
using namespace std;

struct Node {
  bool re;
  bool onetwo;
  int prev;
};

const int MAXN = 10002;
int N;
Node ns[MAXN];
bool vis[MAXN];

string toS(int x) {
  char buff[100];
  sprintf(buff, "%d", x);
  return string(buff);
}

bool canRead(int pos) {
  return !ns[pos].re && !ns[pos].onetwo;
}

void read(int pos) {
  vis[pos] = true;
  cout << pos+1 << endl;
  if(pos && !vis[pos-1] && ns[pos-1].re) {
    read(pos-1);
  }
  if(ns[pos].prev != -1 && !vis[ns[pos].prev]) {
    read(ns[pos].prev);
  }
}

int main() {
  while(cin >> N && N) {
    map<string, stack<int> > onetwo;
    for(int i = 0; i < N; ++i) {
      string s;
      cin >> s;
      Node &n = ns[i];
      if(s == "v") {
	n.re = true;
	n.onetwo = false;
	n.prev = -1;
      } else if(s == "-") {
	n.re = false;
	n.onetwo = false;
	n.prev = -1;
      } else {
	if(*s.rbegin() == 'v') {
	  n.re = true;
	  s.erase(s.end()-1);
	} else {
	  n.re = false;
	}
	int k = (int)s.size()-1;
	while(isdigit(s[k])) --k;
	++k;
	string t = s.substr(0, k);
	int num = atoi(s.substr(k).c_str());
	string p = t + toS(num+1);
	if(onetwo[p].size()) {
	  n.prev = onetwo[p].top();
	  onetwo[p].pop();
	} else {
	  n.prev = -1;
	}
	if(num != 1) {
	  n.onetwo = true;
	  onetwo[s].push(i);
	} else {
	  n.onetwo = false;
	}
      }
    }
    fill(vis, vis+MAXN, false);
    for(int i = 0; i < N; ++i) {
      if(!vis[i] && canRead(i)) {
	read(i);
      }
    }
  }
  return 0;
}
accuracy: 1
time_ms: 190
memory_kb: 9716
final_rank: 20

code_snippet: #include<iostream>
#include<sstream>
#include<algorithm>
#include<set>
#include<map>
#include<queue>
#include<complex>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cassert>

#define rep(i,n) for(int i=0;i<(int)n;i++)
#define all(c) (c).begin(),(c).end()
#define mp make_pair
#define pb push_back
#define each(i,c) for(__typeof((c).begin()) i=(c).begin();i!=(c).end();i++)
#define dbg(x) cerr<<__LINE__<<": "<<#x<<" = "<<(x)<<endl

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef pair<int,int> pi;
const int inf = (int)1e9;
const double INF = 1e12, EPS = 1e-9;

int n, next[10001];
bool ok[10001];

int main(){
	while(cin >> n, n){
		vi ans;
		map<string, int> m;
		rep(i, n) next[i] = -1, ok[i] = 0;
		rep(i, n){
			bool skip = 0;
			string s;
			cin >> s;
			if(s[s.size() - 1] == 'v'){
				next[i + 1] = i;
				s.erase(s.end() - 1);
				skip = 1;
			}
			if(s != "-"){
				int d = 0, ten = 1;
				while(s.size() && isdigit(s[s.size() - 1])){
					d += (s[s.size() - 1] - '0') * ten;
					s.erase(s.end() - 1);
					ten *= 10;
				}
				if(m.count(s)) next[i] = m[s];
				m[s] = i;
				if(d > 1) skip = 1;
				else m.erase(s);
			}
			if(!skip) for(int j = i; j >= 0 && !ok[j]; j = next[j]){
				ans.pb(j);
				ok[j] = 1;
			}
		}
		rep(i, n) cout << ans[i] + 1 << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 140
memory_kb: 1800
final_rank: 5

code_snippet: #include <iostream>
#include <sstream>
#include <string>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cassert>

using namespace std;

#define FOR(i,k,n) for(int i=(k); i<(int)(n); ++i)
#define REP(i,n) FOR(i,0,n)
#define FORIT(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)

template<class T> void debug(T begin, T end){ for(T i = begin; i != end; ++i) cerr<<*i<<" "; cerr<<endl; }
inline bool valid(int x, int y, int W, int H){ return (x >= 0 && y >= 0 && x < W && y < H); }

typedef long long ll;
const int INF = 100000000;
const double EPS = 1e-8;
const int MOD = 1000000007;
int dx[8] = {1, 0, -1, 0, 1, -1, -1, 1};
int dy[8] = {0, 1, 0, -1, 1, 1, -1, -1};

int main(){
  int N;
  while(cin >> N){
    vector<string> mark(N);
    REP(i, N) cin >> mark[i];
    vector<bool> re(N);
    REP(i, N) if(mark[i][mark[i].size() - 1] == 'v'){
      re[i] = true;
      mark[i] = mark[i].substr(0, mark[i].size() - 1);
    }
    vector<string> name(N);
    vector<int> val(N);
    REP(i, N) if(mark[i] != "-" && mark[i] != ""){
      REP(j, mark[i].size())if(isdigit(mark[i][j])){
        name[i] = mark[i].substr(0, j);
        val[i] = atoi(mark[i].substr(j).c_str());
        break;
      }
    }
    map<string, vector<int> > indexes;
    map<int, vector<int> > jump;
    vector<bool> used(N);
    vector<int> ans;
    REP(i, N){
      if(val[i] >= 2){
        indexes[name[i]].push_back(i);
        continue;
      }
      if(val[i] == 1){
        jump[i] = indexes[name[i]];
        indexes[name[i]].clear();
      }
      if(re[i]){ continue; }

      stack<int> stk;
      stk.push(i);
      while(!stk.empty()){
        int k = stk.top(); stk.pop();
        if(used[k]) continue;
        ans.push_back(k);
        used[k] = true;
        REP(j, jump[k].size()){
          stk.push(jump[k][j]);
        }
        if(k - 1 >= 0 && re[k - 1]){
          stk.push(k - 1);
        }
      }
    }
    assert(ans.size() == N);
    REP(i, N) cout << ans[i] + 1 << endl;
  }
  return 0;
}
accuracy: 1
time_ms: 160
memory_kb: 4396
final_rank: 13

code_snippet: #include <iostream>
#include <fstream>
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <iomanip>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <sstream>
#include <string>
#include <vector>
using namespace std;

#pragma comment(linker, "/STACK:400000000")

#define EPS 1e-9
#define INF MOD
#define MOD 1000000007LL
#define fir first
#define foreach(it,X) for(it=X.begin();it!=X.end();it++)
#define iss istringstream
#define ite iterator
#define ll long long
#define mp make_pair
#define rep(i,n) rep2(i,0,n)
#define rep2(i,m,n) for(int i=m;i<n;i++)
#define pi pair<int,int>
#define pb push_back
#define sec second
#define sst stringstream
#define sz size()
#define vc vector
typedef vc<int> vi;
typedef vc<ll> vl;
typedef vc<string> vs;

int N;
string mark[10010];
int used[10010],nex[10010];
map<string,int> M;
vi ans;

void read(int cur){
	if(used[cur])return;
	ans.pb(cur);
	used[cur]=1;
	if(nex[cur]!=-1)read(nex[cur]);
}

int main(){
	while(cin>>N && N){
		rep(i,N)cin>>mark[i];
		fill(used,used+N,0);
		fill(nex,nex+N,-1);
		M.clear();
		ans.clear();
		
		rep(i,N){
			if(mark[i]=="-"){
				read(i);
			}else if(mark[i]=="v"){
				nex[i+1]=i;
			}else{
				string type;
				int number=0;
				int x=0;
				while(islower(mark[i][x])){
					type+=mark[i][x];
					x++;
				}
				while(x<mark[i].sz && isdigit(mark[i][x])){
					number=number*10+mark[i][x]-'0';
					x++;
				}
				if(M.find(type)!=M.end()){
					nex[i]=M[type];
				}
				if(number>1)M[type]=i;
				else M.erase(type);
				if(x<mark[i].sz)nex[i+1]=i;
				else if(number==1)read(i);
			}
		}
		
		rep(i,N)cout<<ans[i]+1<<endl;
	}
}
accuracy: 1
time_ms: 140
memory_kb: 3120
final_rank: 10

code_snippet: #include <iostream>
#include <fstream>
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <iomanip>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <sstream>
#include <string>
#include <vector>
using namespace std;

#pragma comment(linker, "/STACK:400000000")

#define EPS 1e-9
#define INF MOD
#define MOD 1000000007LL
#define fir first
#define foreach(it,X) for(it=X.begin();it!=X.end();it++)
#define iss istringstream
#define ite iterator
#define ll long long
#define mp make_pair
#define rep(i,n) rep2(i,0,n)
#define rep2(i,m,n) for(int i=m;i<n;i++)
#define pi pair<int,int>
#define pb push_back
#define sec second
#define sst stringstream
#define sz size()
#define vc vector
typedef vc<int> vi;
typedef vc<ll> vl;
typedef vc<string> vs;

int N;
string mark[10010];
int used[10010],nex[10010];
map<string,int> M;
vi ans;

void read(int cur){
	if(used[cur])return;
	ans.pb(cur);
	used[cur]=1;
	if(nex[cur]!=-1)read(nex[cur]);
}

int main(){
	while(cin>>N && N){
		rep(i,N)cin>>mark[i];
		fill(used,used+10010,0);
		fill(nex,nex+10010,-1);
		M.clear();
		ans.clear();
		
		rep(i,N){
			if(mark[i]=="-"){
				read(i);
			}else if(mark[i]=="v"){
				nex[i+1]=i;
			}else{
				string type;
				int number=0;
				int x=0;
				while(islower(mark[i][x])){
					type+=mark[i][x];
					x++;
				}
				while(x<mark[i].sz && isdigit(mark[i][x])){
					number=number*10+mark[i][x]-'0';
					x++;
				}
				if(M.find(type)!=M.end()){
					nex[i]=M[type];
				}
				if(number>1)M[type]=i;
				else M.erase(type);
				if(x<mark[i].sz)nex[i+1]=i;
				else if(number==1)read(i);
			}
		}
		
		rep(i,N)cout<<ans[i]+1<<endl;
	}
}
accuracy: 1
time_ms: 130
memory_kb: 3124
final_rank: 8