#include <bits/stdc++.h>
using namespace std;
inline char nc() {
  static char buf[100000], *p1 = buf, *p2 = buf;
  return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2)
             ? EOF
             : *p1++;
}
inline void read(int &x) {
  char c = nc(), b = 1;
  for (; !(c >= '0' && c <= '9'); c = nc())
    if (c == '-')
      b = -1;
    else if (c == '?')
      return void(x = -1);
  for (x = 0; c >= '0' && c <= '9'; x = x * 10 + c - '0', c = nc())
    ;
  x *= b;
}
namespace D {
const int N = 200005;
const int M = N << 2;
struct edge {
  int u, v, f, next;
} G[M << 1];
int head[N], inum = 1;
inline void add(int u, int v, int f, int p) {
  G[p].u = u;
  G[p].v = v;
  G[p].f = f;
  G[p].next = head[u];
  head[u] = p;
}
inline void link(int u, int v, int f) {
  add(u, v, f, ++inum), add(v, u, 0, ++inum);
}
int S, T;
int dis[N], Q[N], l, r;
inline bool bfs() {
  l = r = -1;
  for (int i = 1; i <= T; i++) dis[i] = -1;
  Q[++r] = S;
  dis[S] = 0;
  while (l < r) {
    int u = Q[++l];
    for (int p = head[u]; p; p = G[p].next)
      if (G[p].f && dis[G[p].v] == -1) {
        dis[G[p].v] = dis[u] + 1;
        Q[++r] = G[p].v;
        if (G[p].v == T) return 1;
      }
  }
  return 0;
}
int cur[N];
inline int dfs(int u, int flow) {
  if (u == T) return flow;
  int used = 0;
  for (int p = cur[u]; p; p = G[p].next) {
    cur[u] = p;
    if (dis[G[p].v] == dis[u] + 1 && G[p].f) {
      int d = dfs(G[p].v, min(flow - used, G[p].f));
      G[p].f -= d;
      G[p ^ 1].f += d;
      used += d;
      if (used == flow) break;
    }
  }
  if (!used) dis[u] = -1;
  return used;
}
inline int Dinic() {
  int ans = 0;
  while (bfs()) {
    memcpy(cur, head, sizeof(int) * (T + 5));
    ans += dfs(S, 1 << 30);
  }
  return ans;
}
}  // namespace D
const int N = 305;
int n, a[N], b[N];
int maxa;
int vst[N][N], maxl[N];
int cnt[N];
int x[N], y[N], tot;
int to[N];
int idx[N][N];
vector<int> cir[N];
inline void Print(int c) {
  using namespace D;
  for (int p = 2; p <= inum; p += 2)
    if (G[p].u != S && G[p].v != T && G[p].f == 0)
      a[G[p].u] = x[G[p].v - n], b[G[p].u] = y[G[p].v - n];
  for (int i = 1; i <= n; i++) {
    if (a[i] == -1 && b[i] == -1)
      a[i] = 0, b[i] = 1;
    else if (a[i] > 0 && b[i] == -1)
      b[i] = c;
    else if (a[i] == -1 && b[i] != -1)
      a[i] = 1;
    else if (a[i] == 0 && b[i] == -1)
      b[i] = 1;
    idx[a[i]][b[i]] = i;
    if (a[i] == 0) cir[b[i]].push_back(i);
  }
  for (int i = 1; i <= n; i++)
    for (int j = 0; j < cir[i].size(); j += i)
      for (int k = 0; k < i; k++) to[cir[i][j + k]] = cir[i][j + (k + 1) % i];
  for (int i = 1; i <= n; i++)
    if (a[i] != 0) to[i] = idx[a[i] - 1][b[i]];
  for (int i = 1; i <= n; i++) printf("%d ", to[i]);
  exit(0);
}
int must[N];
int main() {
  read(n);
  int k = 0;
  for (int i = 1; i <= n; i++) {
    read(a[i]), read(b[i]);
    if (a[i] > 0 && b[i] == -1)
      if (!k || a[k] < a[i]) k = i;
    if (a[i] > 0 && b[i] != -1)
      vst[b[i]][a[i]]++, maxl[b[i]] = max(maxl[b[i]], a[i]);
    if (a[i] == 0 && b[i] != -1) cnt[b[i]]++;
    if (b[i] != -1) must[b[i]]++;
  }
  for (int i = 1; i <= n; i++) {
    using namespace D;
    int tmp;
    if (k) {
      b[k] = i, vst[i][a[k]]++;
      must[i]++;
      tmp = maxl[i];
      maxl[i] = max(maxl[i], a[k]);
    }
    tot = 0;
    for (int i = 1; i <= n; i++)
      if (must[i] && (cnt[i] == 0 || cnt[i] % i != 0))
        ++tot, x[tot] = 0, y[tot] = i;
    for (int i = 1; i <= n; i++)
      for (int j = 1; j <= maxl[i]; j++)
        if (!vst[i][j]) ++tot, x[tot] = j, y[tot] = i;
    S = n + tot + 1;
    T = n + tot + 2;
    int flow = 0;
    for (int i = 1; i <= tot; i++)
      if (x[i] == 0)
        link(n + i, T, y[i] - cnt[y[i]] % y[i]),
            flow += y[i] - cnt[y[i]] % y[i];
      else
        link(n + i, T, 1), flow++;
    for (int i = 1; i <= n; i++)
      if (a[i] == -1 || b[i] == -1) {
        link(S, i, 1);
        for (int j = 1; j <= tot; j++)
          if ((a[i] == -1 || a[i] == x[j]) && (b[i] == -1 || b[i] == y[j]))
            link(i, n + j, 1);
      }
    if (Dinic() == flow) Print(i);
    memset(head, 0, sizeof(head));
    inum = 1;
    if (k) b[k] = -1, vst[i][a[k]]--, maxl[i] = tmp, must[i]--;
  }
  printf("-1\n");
  return 0;
}
