#include <bits/stdc++.h>
using namespace std;
const int MAXN = 500005;
const int MAXM = 500005;
const int inf = 1e9;
int n, m, cnt = -1, S, T, in[MAXN], out[MAXN], cur[MAXN], d[MAXN];
vector<int> Eid[MAXN];
struct Edge {
  int c, v;
} E[MAXM];
void init() {
  cnt = -1;
  for (int i = 0; i <= T; i++) Eid[i].clear();
}
void AddEdge(int x, int y, int c) {
  E[++cnt].v = y, E[cnt].c = c;
  Eid[x].push_back(cnt);
  E[++cnt].v = x, E[cnt].c = 0;
  Eid[y].push_back(cnt);
}
bool BFS() {
  static int Q[MAXN];
  int x, i, ql, qr;
  for (i = 0; i <= T; i++) d[i] = -1;
  Q[ql = qr = 0] = S;
  d[S] = 0;
  while (ql <= qr) {
    x = Q[ql++];
    for (i = 0; i < Eid[x].size(); i++) {
      const Edge &e = E[Eid[x][i]];
      if (e.c && d[e.v] == -1) {
        Q[++qr] = e.v;
        d[e.v] = d[x] + 1;
        if (e.v == T) return 1;
      }
    }
  }
  return 0;
}
int Aug(int x, int a) {
  if (x == T) return a;
  int aug = 0, delta;
  for (int &i = cur[x]; i < Eid[x].size(); i++) {
    Edge &e = E[Eid[x][i]];
    if (e.c && d[e.v] == d[x] + 1) {
      delta = Aug(e.v, min(a, e.c));
      if (delta) {
        e.c -= delta;
        E[Eid[x][i] ^ 1].c += delta;
        aug += delta;
        if (!(a -= delta)) break;
      }
    }
  }
  if (!aug) d[x] = -1;
  return aug;
}
int MaxFlow() {
  int flow = 0;
  while (BFS()) {
    for (int i = 0; i <= T; i++) cur[i] = 0;
    flow += Aug(S, inf);
  }
  return flow;
}
struct info {
  int cyc, prec;
  info() {}
  info(int a, int b) {
    cyc = b;
    prec = a;
  }
} Q[MAXN];
int maxlen[MAXN], need[MAXN], ans[MAXN];
int prec_[MAXN], cyc_[MAXN], prec[MAXN], cyc[MAXN];
char s1[MAXN], s2[MAXN];
bool bo[305][305], used[MAXN];
bool check(int x) {
  for (int i = 1; i <= n; i++) {
    bool flow = 0;
    for (int j = 0; j < Eid[i].size(); j++) {
      int en = E[Eid[i][j]].v, w = E[Eid[i][j]].c;
      if (en != S && w == 0) {
        flow = 1;
        prec[i] = Q[en].prec;
        cyc[i] = Q[en].cyc;
      }
    }
    if (!flow) {
      if (prec[i] == 0 && cyc[i] == -1) cyc[i] = 1;
    }
  }
  for (int i = 1; i <= n; i++) {
    if (prec[i] == -1 && cyc[i] == -1) {
      prec[i] = 0;
      cyc[i] = 1;
    }
    if (prec[i] != -1 && cyc[i] == -1) cyc[i] = x;
    if (prec[i] == -1 && cyc[i] != -1) prec[i] = 1;
  }
  return 1;
}
void print() {
  for (int i = 1; i <= n; i++) {
    if (used[i]) continue;
    if (prec[i] == 0) {
      if (cyc[i] == 1) {
        ans[i] = i;
        continue;
      }
      int cnt = 1, pre = i;
      for (int j = i + 1; j <= n; j++) {
        if (cyc[j] == cyc[i] && prec[j] == 0 && !used[j]) {
          ans[pre] = j;
          pre = j;
          used[j] = 1;
          cnt++;
        }
        if (cnt == cyc[i]) break;
      }
      ans[pre] = i;
    } else {
      for (int j = 1; j <= n; j++)
        if (prec[j] == prec[i] - 1 && cyc[j] == cyc[i]) ans[i] = j;
    }
  }
  for (int i = 1; i <= n; i++) printf("%d ", ans[i]);
}
void solve(int x) {
  for (int i = 0; i <= n; i++)
    for (int j = 0; j <= n; j++) bo[i][j] = 0;
  for (int i = 0; i <= n; i++) maxlen[i] = 0;
  for (int i = 1; i <= n; i++) {
    if (prec[i] != -1 && cyc[i] != -1) {
      maxlen[cyc[i]] = max(maxlen[cyc[i]], prec[i]);
      bo[cyc[i]][prec[i]] = 1;
    }
  }
  for (int i = 1; i <= n; i++) {
    need[i] = 0;
    int cnt = 0;
    bool exist = 0;
    for (int j = 1; j <= n; j++) {
      if (cyc[j] == i) exist = 1;
      if (prec[j] == 0 && cyc[j] == i) cnt++;
    }
    if (!exist) continue;
    while ((cnt + need[i]) % i || (cnt == 0 && need[i] == 0)) need[i]++;
  }
  int t = n, maxflow = 0;
  for (int i = 1; i <= n; i++) {
    if (need[i]) t++, maxflow += need[i];
    for (int j = 1; j <= maxlen[i]; j++)
      if (!bo[i][j]) t++, maxflow++;
  }
  T = t + 1;
  t = n;
  for (int i = 1; i <= n; i++) {
    if (need[i]) {
      t++;
      Q[t] = info(0, i);
      AddEdge(t, T, need[i]);
      for (int j = 1; j <= n; j++) {
        if (prec[j] == 0 && cyc[j] == -1) AddEdge(j, t, 1);
        if (prec[j] == -1 && cyc[j] == i) AddEdge(j, t, 1);
        if (prec[j] == -1 && cyc[j] == -1) AddEdge(j, t, 1);
      }
    }
    for (int j = 1; j <= maxlen[i]; j++) {
      if (!bo[i][j]) {
        t++;
        Q[t] = info(j, i);
        AddEdge(t, T, 1);
        for (int k = 1; k <= n; k++) {
          if (prec[k] == -1 && cyc[k] == i) AddEdge(k, t, 1);
          if (prec[k] == -1 && cyc[k] == -1) AddEdge(k, t, 1);
          if (prec[k] == j && cyc[k] == -1) AddEdge(k, t, 1);
        }
      }
    }
  }
  for (int i = 1; i <= n; i++) {
    if (prec[i] == -1 || cyc[i] == -1) AddEdge(S, i, 1);
  }
  if (MaxFlow() == maxflow) {
    if (check(x)) {
      print();
      exit(0);
    }
  }
  init();
}
int main() {
  scanf("%d", &n);
  for (int i = 1; i <= n; i++) {
    scanf("%s%s", s1, s2);
    if (s1[0] == '?')
      prec_[i] = -1;
    else
      prec_[i] = atoi(s1);
    if (s2[0] == '?')
      cyc_[i] = -1;
    else
      cyc_[i] = atoi(s2);
  }
  for (int i = 1; i <= n; i++) {
    int pos = 0, X = 0;
    for (int j = 1; j <= n; j++) {
      prec[j] = prec_[j];
      cyc[j] = cyc_[j];
      if (prec_[j] != -1 && cyc_[j] == -1) {
        if (prec_[j] > X) {
          X = prec_[j];
          pos = j;
        }
      }
    }
    if (pos) cyc[pos] = i;
    solve(i);
  }
  return puts("-1");
}
