#include <bits/stdc++.h>
using namespace std;
bool FindMatch(int i, const vector<vector<int> > &w, vector<int> &mr,
               vector<int> &mc, vector<int> &seen) {
  for (int j = 0; j < w[i].size(); j++) {
    if (w[i][j] && !seen[j]) {
      seen[j] = true;
      if (mc[j] < 0 || FindMatch(mc[j], w, mr, mc, seen)) {
        mr[i] = j;
        mc[j] = i;
        return true;
      }
    }
  }
  return false;
}
int BipartiteMatching(const vector<vector<int> > &w, vector<int> &mr,
                      vector<int> &mc) {
  mr = vector<int>(w.size(), -1);
  mc = vector<int>(w[0].size(), -1);
  int ct = 0;
  for (int i = 0; i < w.size(); i++) {
    vector<int> seen(w[0].size());
    if (FindMatch(i, w, mr, mc, seen)) ct++;
  }
  return ct;
}
int n;
int level[305];
int cyc[305];
int mxl[305];
int need[305];
int mx;
bool match(int x, int y) {
  if (x == -1 || y == -1) return true;
  return x == y;
}
vector<int> ans;
bool solveWhereMaxIs(int x) {
  vector<int> nodeCyc;
  vector<int> nodeLev;
  for (int i = 1; i <= n; i++) {
    if (i != x && mxl[i] < 0) continue;
    for (int j = 0; j < (max(1, need[i]) + i - 1) / i; j++) {
      for (int k = 0; k < i; k++) {
        nodeCyc.push_back(i);
        nodeLev.push_back(0);
      }
    }
    int lev = mxl[i];
    if (i == x) lev = max(lev, mx);
    for (int j = 1; j <= lev; j++) {
      nodeCyc.push_back(i);
      nodeLev.push_back(j);
    }
  }
  int len = nodeCyc.size();
  if (len > n) return false;
  vector<vector<int> > g(n, vector<int>(n, 0));
  for (int i = 0; i < n; i++)
    for (int j = 0; j < len; j++)
      if (match(cyc[i], nodeCyc[j]) && match(level[i], nodeLev[j]))
        g[i][j] = true;
  vector<int> L, R;
  int matches = BipartiteMatching(g, L, R);
  if (matches < len) return false;
  for (int i = 0; i < n; i++)
    if (L[i] == -1 && cyc[i] > 0 && level[i] == 0)
      for (int j = 0; j < len; j++)
        if (match(cyc[i], nodeCyc[j]) && match(level[i], nodeLev[j])) {
          if (cyc[R[j]] == -1 || level[R[j]] == -1) {
            L[R[j]] = -1;
            R[j] = i;
            L[i] = j;
            break;
          }
        }
  ans = vector<int>(n, -1);
  int cnt = 0;
  int any[305][305];
  memset(any, -1, sizeof(any));
  for (int i = 1; i <= n; i++) {
    if (i != x && mxl[i] < 0) continue;
    for (int j = 0; j < (max(1, need[i]) + i - 1) / i; j++) {
      any[i][0] = R[cnt];
      ans[R[cnt]] = R[cnt + i - 1];
      cnt++;
      for (int k = 1; k < i; k++) {
        ans[R[cnt]] = R[cnt - 1];
        cnt++;
      }
    }
    int lev = mxl[i];
    if (i == x) lev = max(lev, mx);
    for (int j = 1; j <= lev; j++) {
      ans[R[cnt]] = R[cnt - 1];
      any[i][j] = R[cnt];
      cnt++;
    }
  }
  for (int i = 0; i < n; i++)
    if (L[i] == -1) {
      if (cyc[i] == -1 && level[i] == -1)
        ans[i] = any[x][0];
      else if (cyc[i] == -1 && level[i] == 0)
        ans[i] = i;
      else if (cyc[i] == -1)
        ans[i] = any[x][level[i] - 1];
      else if (level[i] == -1)
        ans[i] = any[cyc[i]][0];
      else
        ans[i] = any[cyc[i]][level[i] - 1];
    }
  return true;
}
bool solve() {
  memset(mxl, -1, sizeof(mxl));
  mx = 0;
  bool ok = false;
  for (int i = 0; i < n; i++) {
    if (cyc[i] > 0) {
      mxl[cyc[i]] = max(0, max(level[i], mxl[cyc[i]]));
      if (level[i] == 0) need[cyc[i]]++;
    }
    mx = max(mx, level[i]);
  }
  for (int i = 1; i <= n; i++) {
    if (mxl[i] < 0) continue;
    ok = true;
    if (solveWhereMaxIs(i)) return true;
  }
  if (!ok) return solveWhereMaxIs(1);
  return false;
}
char s[10];
int getNum() {
  scanf("%s", s);
  int len = strlen(s);
  if (s[0] == '?') return -1;
  int num = 0;
  for (int i = 0; i < len; i++) {
    num *= 10;
    num += s[i] - '0';
  }
  return num;
}
int main() {
  scanf("%d", &n);
  for (int i = 0; i < n; i++) {
    level[i] = getNum();
    cyc[i] = getNum();
  }
  if (solve())
    for (int i = 0; i < n; i++) printf("%d ", ans[i] + 1);
  else
    printf("-1\n");
}
