#include <bits/stdc++.h>
using namespace std;
const int maxn = 305;
struct edge {
  int v, rev, f;
};
int n;
vector<pair<int, int>> inp;
vector<int> ans;
int maxm, maxim;
map<pair<int, int>, vector<int>> M;
vector<vector<edge>> 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);
  }
}
int bfs() {
  vector<int> q;
  q.push_back(0);
  pred[0] = make_pair(0, 0);
  for (int i = 0; i < (q.size()); ++i) {
    int u = q[i];
    for (int j = 0; j < (adj[u].size()); ++j) {
      edge& e = adj[u][j];
      if (e.f == 0) continue;
      if (pred[e.v].first == -1) {
        pred[e.v] = make_pair(u, j);
        q.push_back(e.v);
      }
      if (e.v == 1) break;
    }
    if (pred[1].first != -1) break;
  }
  if (pred[1].first == -1) {
    for (int u : q) pred[u] = make_pair(-1, -1);
    return 0;
  }
  int cur = 1, prev = pred[cur].first, flow = adj[prev][pred[cur].second].f;
  while (cur != 0) {
    flow = min(flow, adj[prev][pred[cur].second].f);
    cur = prev;
    prev = pred[cur].first;
  }
  cur = 1;
  prev = pred[cur].first;
  while (cur != 0) {
    edge& e = adj[prev][pred[cur].second];
    e.f -= flow;
    adj[cur][e.rev].f += flow;
    cur = prev;
    prev = pred[cur].first;
  }
  for (int u : q) {
    pred[u] = make_pair(-1, -1);
  }
  return flow;
}
bool poss() {
  while (bfs())
    ;
  for (int i = 0; i < (adj[1].size()); ++i) {
    edge& e = adj[1][i];
    if (adj[e.v][e.rev].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 (auto& e : adj[i])
        if (e.v != 1 && e.f > 0) {
          for (int j = 0; j < (e.f); ++j) {
            M[rG[i]].push_back(M[rG[e.v]].back());
            M[rG[e.v]].pop_back();
          }
          if (M[rG[e.v]].empty()) M.erase(rG[e.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, e1;
  e0.v = j;
  e0.rev = adj[j].size();
  e0.f = k;
  e1.v = i;
  e1.rev = adj[i].size();
  e1.f = 0;
  adj[i].push_back(e0);
  adj[j].push_back(e1);
}
void del_edge(int i, int j) {
  adj[j].pop_back();
  adj[i].pop_back();
}
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));
}
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<edge>> adj_copy = adj;
  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;
    }
  cout << "-1\n";
}
int main() {
  ios::sync_with_stdio(0);
  int t = 1;
  while (t--) solve();
  return 0;
}
