#include <bits/stdc++.h>
using namespace std;
int IN() {
  int x = 0, f = 0, ch;
  for (; (ch = getchar()) < '0' || ch > '9';) f = (ch == '-');
  for (; ch >= '0' && ch <= '9'; (ch = getchar())) x = x * 10 + ch - '0';
  return f ? -x : x;
}
int N, X[605], Y[605];
int M, V[605], Max[605], cnt[605][605], ID[605][605];
int C, D, S, T, st[605], Dis[605], Q[605], G[605][605];
int Ans[605][605], F[605];
struct Lin {
  int v, f, next;
} E[200005];
void Link(int u, int v, int f) {
  E[++D] = (Lin){v, f, st[u]};
  st[u] = D;
  E[++D] = (Lin){u, 0, st[v]};
  st[v] = D;
  G[u][v] = D - 1;
}
bool BFS() {
  for (int i = 1, lim = C; i <= lim; i++) Dis[i] = -1;
  Dis[Q[1] = S] = 0;
  for (int l = 0, r = 1; l < r;) {
    int u = Q[++l];
    for (int i = st[u], v; i; i = E[i].next)
      if (E[i].f && Dis[v = E[i].v] == -1) Dis[Q[++r] = v] = Dis[u] + 1;
  }
  return Dis[T] != -1;
}
int DFS(int u, int Lim) {
  if (u == T) return Lim;
  int ret = 0;
  for (int i = st[u], v; i; i = E[i].next)
    if (E[i].f && Dis[v = E[i].v] == Dis[u] + 1) {
      int t = DFS(v, min(Lim - ret, E[i].f));
      if (t) {
        E[i].f -= t;
        E[i ^ 1].f += t;
        ret += t;
        if (ret == Lim) break;
      } else
        Dis[v] = -1;
    }
  return ret;
}
int MaxFlow() {
  int ret = 0;
  for (; BFS();) ret += DFS(S, (1 << 30));
  return ret;
}
void Init() {
  static char s[5], t[5];
  N = IN();
  for (int i = 1, lim = N; i <= lim; i++) {
    scanf("%s%s", s, t);
    if (s[0] != '?') {
      for (int j = 0; s[j]; j++) X[i] = X[i] * 10 + s[j] - '0';
    } else
      X[i] = -1;
    if (t[0] != '?') {
      for (int j = 0; t[j]; j++) Y[i] = Y[i] * 10 + t[j] - '0';
    } else
      Y[i] = -1;
  }
  int f1 = 0, f2 = 0;
  for (int i = 1, lim = N; i <= lim; i++) {
    if (X[i] != -1) f1 = 1;
    if (Y[i] != -1) f2 = 1;
  }
  if (!f1 && !f2) {
    for (int i = 1, lim = N; i <= lim; i++) X[i] = 0, Y[i] = 1;
  } else if (!f2) {
    for (int i = 1, lim = N; i <= lim; i++) Y[i] = 1;
  }
  for (int i = 1, lim = N; i <= lim; i++) {
    if (Y[i] != -1) {
      V[Y[i]] = 1;
      if (X[i] != -1) Max[Y[i]] = max(Max[Y[i]], X[i]);
    } else if (X[i] != -1)
      M = max(M, X[i]);
  }
  for (int i = 1, lim = N; i <= lim; i++)
    if (X[i] != -1 && Y[i] != -1) cnt[Y[i]][X[i]]++;
}
bool Work() {
  for (int cyc = 1, lim = N; cyc <= lim; cyc++)
    if (V[cyc]) {
      int tmp = Max[cyc];
      Max[cyc] = max(Max[cyc], M);
      int sum = 0;
      for (int i = 1, lim = N; i <= lim; i++)
        if (V[i]) sum += Max[i] + 1;
      if (sum > N) {
        Max[cyc] = tmp;
        continue;
      }
      C = N;
      for (int i = 1, lim = N; i <= lim; i++)
        if (V[i])
          for (int j = 0, lim = Max[i]; j <= lim; j++) ID[i][j] = ++C;
      S = ++C;
      T = ++C;
      for (int i = 1, lim = C; i <= lim; i++) st[i] = 0;
      D = 1;
      for (int i = 1, lim = C; i <= lim; i++)
        for (int j = 1, lim = C; j <= lim; j++) G[i][j] = 0;
      int tot = 0;
      for (int i = 1, lim = N; i <= lim; i++)
        if (V[i]) {
          int t = (i - cnt[i][0] % i) % i;
          if (cnt[i][0] == 0) t = i;
          Link(ID[i][0], T, t);
          tot += t;
          for (int j = 1, lim = Max[i]; j <= lim; j++)
            if (!cnt[i][j]) Link(ID[i][j], T, 1), tot++;
        }
      for (int i = 1, lim = N; i <= lim; i++) {
        if (X[i] != -1 && Y[i] != -1) continue;
        Link(S, i, 1);
        if (X[i] == -1 && Y[i] == -1) {
          for (int j = 1, lim = N; j <= lim; j++)
            if (V[j])
              for (int k = 0, lim = Max[j]; k <= lim; k++) Link(i, ID[j][k], 1);
        } else if (X[i] == -1) {
          for (int j = 0, lim = Max[Y[i]]; j <= lim; j++)
            Link(i, ID[Y[i]][j], 1);
        } else {
          for (int j = 1, lim = N; j <= lim; j++)
            if (V[j] && Max[j] >= X[i]) Link(i, ID[j][X[i]], 1);
        }
      }
      if (MaxFlow() < tot) {
        Max[cyc] = tmp;
        continue;
      }
      for (int i = 1, lim = N; i <= lim; i++) {
        if (X[i] != -1 && Y[i] != -1) continue;
        for (int j = 1, lim = N; j <= lim; j++)
          if (V[j])
            for (int k = 0, lim = Max[j]; k <= lim; k++)
              if (G[i][ID[j][k]] && E[G[i][ID[j][k]]].f == 0)
                Y[i] = j, X[i] = k;
      }
      return 1;
    }
  return 0;
}
void Out() {
  for (int i = 1, lim = N; i <= lim; i++) {
    if (X[i] != -1 && Y[i] != -1) continue;
    if (X[i] == -1 && Y[i] == -1)
      X[i] = 0, Y[i] = 1;
    else if (X[i] == -1)
      X[i] = 1;
    else {
      if (X[i] == 0)
        Y[i] = 1;
      else {
        for (int j = 1, lim = N; j <= lim; j++)
          if (V[j] && Max[j] >= X[i]) Y[i] = j;
      }
    }
  }
  for (int i = 1, lim = N; i <= lim; i++) Ans[Y[i]][X[i]] = i;
  for (int i = 1, lim = N; i <= lim; i++) {
    if (X[i] > 0)
      F[i] = Ans[Y[i]][X[i] - 1];
    else if (Y[i] == 1)
      F[i] = i;
  }
  for (int i = 2, lim = N; i <= lim; i++)
    if (V[i]) {
      static int H[605];
      *H = 0;
      for (int j = 1, lim = N; j <= lim; j++)
        if (Y[j] == i && X[j] == 0) H[++*H] = j;
      assert(*H % i == 0);
      for (int j = 1; j <= *H; j += i) {
        for (int k = j, lim = j + i - 2; k <= lim; k++) F[H[k]] = H[k + 1];
        F[H[j + i - 1]] = H[j];
      }
    }
  for (int i = 1, lim = N; i <= lim; i++) printf("%d ", F[i]);
  puts("");
}
int main(int argc, char* argv[]) {
  Init();
  if (!Work())
    puts("-1");
  else
    Out();
  return 0;
}
