#include <bits/stdc++.h>
using namespace std;
inline int read() {
  char ch = getchar();
  int nega = 1;
  while (!isdigit(ch)) {
    if (ch == '?') return -1;
    if (ch == '-') nega = -1;
    ch = getchar();
  }
  int ans = 0;
  while (isdigit(ch)) {
    ans = ans * 10 + ch - 48;
    ch = getchar();
  }
  if (nega == -1) return -ans;
  return ans;
}
namespace Flow {
struct Edge {
  int v, cap, nxt;
};
Edge edge[305 * 305 * 305 / 20];
int first[305 * 305 * 3 + 5], cur[305 * 305 * 3 + 5], ss,
    dep[305 * 305 * 3 + 5];
inline void init() {
  memset(first, 0, sizeof(first));
  ss = 1;
}
inline void add(int u, int v, int w) {
  edge[++ss] = (Edge){v, w, first[u]};
  first[u] = ss;
  edge[++ss] = (Edge){u, 0, first[v]};
  first[v] = ss;
}
int q[305 * 10], qaq, r;
int s = 305 * 305 * 3 + 1, t = 305 * 305 * 3 + 2;
bool bfs() {
  memset(dep, 0, sizeof(dep));
  dep[s] = 1;
  qaq = 1, r = 1;
  q[1] = s;
  while (qaq <= r) {
    int u = q[qaq++];
    for (int i = first[u]; i != 0; i = edge[i].nxt) {
      if (!edge[i].cap) continue;
      int v = edge[i].v;
      if (!dep[v]) {
        dep[v] = dep[u] + 1;
        if (v == t) return 1;
        q[++r] = v;
      }
    }
  }
  return dep[t];
}
int dfs(int u, int flow) {
  if (u == t || !flow) return flow;
  int go = 0;
  for (int &i = cur[u]; i != 0; i = edge[i].nxt) {
    if (!edge[i].cap) continue;
    int v = edge[i].v;
    if (dep[u] + 1 != dep[v]) continue;
    int R = dfs(v, min(flow, edge[i].cap));
    if (R) {
      edge[i].cap -= R, edge[i ^ 1].cap += R;
      go += R, flow -= R;
    }
  }
  return go;
}
int dinic() {
  int ans = 0;
  while (bfs()) {
    memcpy(cur, first, sizeof(cur));
    ans += dfs(s, 0x3f3f3f3f);
  }
  return ans;
}
};  // namespace Flow
using namespace Flow;
int d[305], l[305];
vector<pair<int, int> > a;
vector<pair<int, int> > v[305];
vector<int> ze[305];
int maxn[305];
int n, cnt;
int id[305][305], vis[305][305];
int nd[305][305], Rev[305], ans[305];
pair<int, int> rev[305 * 305];
bool ok[305];
void solve() {
  for (int i = 1; i <= n; i++) v[i].clear();
  for (int i = 1; i <= n; i++) ze[i].clear();
  a.clear();
  cnt = 0;
  memset(maxn, 0, sizeof(maxn));
  memset(id, 0, sizeof(id));
  memset(vis, 0, sizeof(vis));
  memset(nd, 0, sizeof(nd));
  memset(Rev, 0, sizeof(Rev));
  memset(ans, 0, sizeof(ans));
  memset(rev, 0, sizeof(rev));
  for (int i = 1; i <= n; i++) {
    if (l[i] != -1) v[l[i]].emplace_back(d[i], l[i]);
    if (l[i] != -1 && d[i] != -1) {
      maxn[l[i]] = max(maxn[l[i]], d[i]), vis[d[i]][l[i]] = 1,
      nd[d[i]][l[i]] = i;
      if (d[i] == 0) ze[l[i]].push_back(i);
    } else
      a.emplace_back(d[i], l[i]), Rev[a.size()] = i;
  }
  init();
  for (int i = 1; i <= n; i++) {
    if (!v[i].size()) continue;
    int r = (i - ze[i].size() % i) % i;
    if (!ze[i].size()) r = i;
    for (int j = 1; j <= r; j++) {
      cnt++;
      add(s, cnt, 1);
      rev[cnt] = make_pair(0, i);
    }
    for (int j = 1; j <= maxn[i]; j++) {
      if (!vis[j][i])
        id[j][i] = ++cnt, add(s, id[j][i], 1), rev[cnt] = make_pair(j, i);
    }
  }
  if (cnt > n) return;
  for (int i = 0; i < (int)a.size(); i++) {
    auto [d, l] = a[i];
    for (int c = 1; c <= cnt; c++) {
      auto [j, k] = rev[c];
      if (d != -1 && d != j) continue;
      if (l != -1 && l != k) continue;
      add(c, cnt + i + 1, 1);
    }
    add(cnt + i + 1, t, 1);
  }
  int f = dinic();
  if (f != cnt) return;
  for (int i = 1; i <= cnt; i++) {
    auto [D, L] = rev[i];
    for (int j = first[i]; j != 0; j = edge[j].nxt) {
      int v = edge[j].v;
      if (v > i && edge[j].cap == 0) {
        int id = Rev[v - cnt];
        d[id] = D, l[id] = L;
        nd[D][L] = id;
        if (D == 0) ze[L].push_back(id);
      }
    }
  }
  for (int i = 1; i <= n; i++) {
    for (int j = 0; j < (int)ze[i].size(); j += i) {
      for (int k = 0; k < i - 1; k++) ans[ze[i][j + k]] = ze[i][j + k + 1];
      ans[ze[i][j + i - 1]] = ze[i][j];
    }
  }
  int maxid = 0;
  for (int i = 1; i <= n; i++) {
    if (maxn[maxid] < maxn[i]) maxid = i;
  }
  for (int i = 1; i <= n; i++) {
    if (d[i] == 0 && l[i] == -1) ans[i] = i;
  }
  for (int i = 1; i <= n; i++) {
    if (ans[i]) continue;
    if (d[i] == -1) d[i] = 1;
    if (l[i] == -1) l[i] = maxid;
    if (d[i] != -1 && l[i] != -1) {
      assert(d[i] != 0);
      ans[i] = nd[d[i] - 1][l[i]];
    }
  }
  for (int i = 1; i <= n; i++)
    if (!ans[i]) ans[i] = i;
  for (int i = 1; i <= n; i++) printf("%d ", ans[i]);
  exit(0);
}
signed main() {
  cin >> n;
  for (int i = 1; i <= n; i++) {
    d[i] = read(), l[i] = read();
  }
  int maxid = 0;
  for (int i = 1; i <= n; i++) {
    if (l[i] == -1 && d[i] > d[maxid]) maxid = i;
  }
  if (!maxid) {
    solve();
    cout << "-1\n";
    return 0;
  }
  for (int i = 1; i <= n; i++) {
    l[maxid] = i;
    solve();
  }
  cout << "-1\n";
  return 0;
}
