#include <bits/stdc++.h>
using namespace std;
const int maxn = 305;
const int INF = 1e9;
struct edge {
  int v, f;
};
int n;
vector<pair<int, int>> inp;
vector<int> ans;
int maxm, maxim;
map<pair<int, int>, vector<int>> M;
edge E[5 * maxn];
int ecnt;
int Q[5 * maxn], D[5 * maxn], ptr[5 * maxn];
vector<vector<int>> adj;
map<pair<int, int>, int> G;
vector<pair<int, int>> rG;
pair<int, int> pred[5 * maxn];
int maxi[maxn];
bool unk(pair<int, int> p) { return p.first == -1 || p.second == -1; }
int read_num() {
  string s;
  cin >> s;
  if (s == "?") return -1;
  return stoi(s);
}
void read_input() {
  cin >> n;
  inp.resize(n);
  ans.resize(n);
  for (int i = 0; i < (n); ++i) {
    int x = read_num();
    int y = read_num();
    inp[i] = make_pair(x, y);
    M[inp[i]].push_back(i);
  }
}
bool bfs() {
  memset(D, -1, sizeof D);
  int qh = 1, qt = 0;
  Q[0] = D[0] = 0;
  while (qt < qh) {
    int u = Q[qt++];
    for (int i = 0; i < (adj[u].size()); ++i) {
      edge& e = E[adj[u][i]];
      if (e.f && D[e.v] == -1) {
        D[e.v] = D[u] + 1;
        Q[qh++] = e.v;
      }
    }
  }
  return D[1] != -1;
}
int dfs(int u, int f) {
  if (!f) return 0;
  if (u == 1) return f;
  int res = 0;
  for (; ptr[u] < adj[u].size(); ++ptr[u]) {
    edge& e = E[adj[u][ptr[u]]];
    if (D[e.v] != D[u] + 1) continue;
    int p = dfs(e.v, min(e.f, f));
    if (p) {
      e.f -= p;
      E[adj[u][ptr[u]] ^ 1].f += p;
      f -= p;
      res += p;
      if (!f) break;
    }
  }
  return res;
}
bool poss() {
  while (bfs()) {
    memset(ptr, 0, sizeof ptr);
    while (dfs(0, INF))
      ;
  }
  for (int i = 0; i < (adj[1].size()); ++i) {
    int ei = adj[1][i];
    if (E[ei ^ 1].f != 0) return false;
  }
  return true;
}
void output() {
  for (auto it : M) {
    pair<int, int> p = it.first;
    vector<int>& v = it.second;
    if (p.first == 0)
      for (int i = 0; i < (v.size() / p.second); ++i) {
        for (int j = 0; j < (p.second - 1); ++j)
          ans[v[i * p.second + j]] = v[i * p.second + j + 1];
        ans[v[i * p.second + p.second - 1]] = v[i * p.second];
      }
    else {
      int x = M[make_pair(p.first - 1, p.second)][0];
      for (int i = 0; i < (v.size()); ++i) ans[v[i]] = x;
    }
  }
  for (int i = 0; i < (n); ++i) cout << ans[i] + 1 << " ";
  cout << "\n";
}
void answer(int x) {
  for (int i = 0; i < (rG.size()); ++i)
    if (i > 1 && !unk(rG[i])) {
      for (int ei : adj[i])
        if (E[ei].v != 1 && E[ei].f > 0) {
          for (int j = 0; j < (E[ei].f); ++j) {
            M[rG[i]].push_back(M[rG[E[ei].v]].back());
            M[rG[E[ei].v]].pop_back();
          }
          if (M[rG[E[ei].v]].empty()) M.erase(rG[E[ei].v]);
        }
    }
  for (int j = 1; j < maxn; ++j) {
    auto it = M.find(make_pair(j, -1));
    if (it == M.end()) continue;
    vector<int>& v = it->second;
    move(v.begin(), v.end(), back_inserter(M[make_pair(j, x)]));
    M.erase(it);
  }
  auto it = M.find(make_pair(0, -1));
  if (it != M.end()) {
    move(it->second.begin(), it->second.end(),
         back_inserter(M[make_pair(0, 1)]));
    M.erase(it);
  }
  it = M.find(make_pair(-1, -1));
  if (it != M.end()) {
    move(it->second.begin(), it->second.end(),
         back_inserter(M[make_pair(0, 1)]));
    M.erase(it);
  }
  for (int i = 0; i < (rG.size()); ++i) {
    pair<int, int> p = rG[i];
    it = M.find(p);
    if (it == M.end()) continue;
    if (!unk(p)) continue;
    move(it->second.begin(), it->second.end(),
         back_inserter(M[make_pair(1, p.second)]));
    M.erase(it);
  }
  output();
}
void corner_case() {
  vector<int>& v = M[make_pair(-1, -1)];
  for (int i = 0; i < (maxm + 1); ++i) {
    auto it = M.find(make_pair(i, -1));
    if (it == M.end()) {
      if (v.empty()) {
        cout << "-1\n";
        return;
      }
      M[make_pair(i, 1)].push_back(v.back());
      v.pop_back();
    } else {
      move(it->second.begin(), it->second.end(),
           back_inserter(M[make_pair(i, 1)]));
      M.erase(it);
    }
  }
  move(v.begin(), v.end(), back_inserter(M[make_pair(0, 1)]));
  M.erase(make_pair(-1, -1));
  output();
}
int add_node(int i, int j) {
  G[make_pair(i, j)] = rG.size();
  rG.push_back(make_pair(i, j));
  adj.push_back({});
  return G[make_pair(i, j)];
}
void add_edge(int i, int j, int k) {
  edge e0{j, k}, e1{i, 0};
  adj[i].push_back(ecnt);
  E[ecnt++] = e0;
  adj[j].push_back(ecnt);
  E[ecnt++] = e1;
}
void del_edge(int i, int j) {
  adj[j].pop_back();
  adj[i].pop_back();
  ecnt -= 2;
}
vector<pair<int, int>> predecessors(int i, int j) {
  return {make_pair(i, -1), make_pair(-1, j), make_pair(-1, -1)};
}
void del_node(int i, int j) {
  rG.pop_back();
  G.erase(make_pair(i, j));
  adj.pop_back();
}
void add_missing(int i, int j, int k) {
  int idx = add_node(i, j);
  for (pair<int, int> p : predecessors(i, j)) {
    auto it = M.find(p);
    if (it == M.end()) continue;
    add_edge(G[p], idx, k);
  }
  add_edge(idx, 1, k);
}
void solve() {
  memset(pred, -1, sizeof pred);
  memset(maxi, -1, sizeof maxi);
  maxm = maxim = -1;
  read_input();
  for (int i = 0; i < (n); ++i) {
    if (inp[i].second == -1)
      maxm = max(maxm, inp[i].first);
    else {
      maxi[inp[i].second] = max(maxi[inp[i].second], inp[i].first);
      maxi[inp[i].second] = max(maxi[inp[i].second], 0);
      maxim = max(maxim, maxi[inp[i].second]);
    }
  }
  int s = 0;
  for (int i = 0; i < (maxn); ++i)
    if (maxi[i] > 0) s += maxi[i];
  if (s > n) {
    cout << "-1\n";
    return;
  }
  if (maxim == -1) {
    corner_case();
    return;
  }
  adj.resize(2);
  rG.resize(2);
  for (auto& m : M) {
    pair<int, int> p = m.first;
    if (unk(p)) add_edge(0, add_node(p.first, p.second), m.second.size());
  }
  for (int i = 0; i < (maxn); ++i)
    for (int j = 0; j < (maxi[i] + 1); ++j) {
      if (j == 0) {
        int count = i;
        auto it = M.find(make_pair(0, i));
        if (it != M.end()) {
          count = it->second.size();
          count = (i - count % i) % i;
        }
        if (count > 0) add_missing(0, i, count);
      } else if (M.find(make_pair(j, i)) == M.end()) {
        add_missing(j, i, 1);
      }
    }
  if (maxm <= maxim + 1)
    if (poss()) {
      int idx = 1;
      for (int i = 0; i < (maxn); ++i)
        if (maxm <= maxi[i] + 1) {
          idx = i;
          break;
        }
      answer(idx);
      return;
    } else {
      cout << "-1\n";
      return;
    }
  vector<vector<int>> adj_copy = adj;
  edge Ec[5 * maxn];
  memcpy(Ec, E, sizeof E);
  int eccnt = ecnt;
  for (int i = 0; i < (maxn); ++i)
    if (maxi[i] != -1 && s - maxi[i] + maxm <= n) {
      for (int j = maxi[i] + 1; j <= maxm; ++j) add_missing(j, i, 1);
      if (poss()) {
        answer(i);
        return;
      }
      for (int j = maxm; j > maxi[i]; --j) del_node(j, i);
      adj = adj_copy;
      memcpy(E, Ec, sizeof E);
      ecnt = eccnt;
    }
  cout << "-1\n";
}
int main() {
  ios::sync_with_stdio(0);
  int t = 1;
  while (t--) solve();
  return 0;
}
