#include <bits/stdc++.h>
using namespace std;
long long gcd(long long a, long long b) { return b == 0 ? a : gcd(b, a % b); }
const int MAXN = 300;
int n;
char buff[10];
int pre[MAXN], cyc[MAXN];
vector<int> adj[MAXN];
int lmatch[MAXN], rmatch[MAXN];
bool done[MAXN];
bool augment(int at) {
  if (done[at])
    return false;
  else
    done[at] = true;
  for (int i = (0); i < (((int)(adj[at]).size())); ++i) {
    int to = adj[at][i];
    if (rmatch[to] == -1 || augment(rmatch[to])) {
      rmatch[to] = at, lmatch[at] = to;
      return true;
    }
  }
  return false;
}
int maxflow(int nl, int nr) {
  int ret = 0;
  for (int i = (0); i < (nl); ++i) lmatch[i] = -1;
  for (int i = (0); i < (nr); ++i) rmatch[i] = -1;
  for (int i = (0); i < (nl); ++i) {
    memset(done, false, sizeof(done));
    if (augment(i)) ++ret;
  }
  return ret;
}
bool ok(pair<int, int> want, pair<int, int> have) {
  if (have.first != -1 && have.first != want.first) return false;
  if (have.second != -1 && have.second != want.second) return false;
  return true;
}
void run() {
  scanf("%d", &n);
  for (int i = (0); i < (n); ++i) {
    scanf("%s", buff);
    if (strcmp(buff, "?") == 0)
      pre[i] = -1;
    else
      sscanf(buff, "%d", &pre[i]);
    scanf("%s", buff);
    if (strcmp(buff, "?") == 0)
      cyc[i] = -1;
    else
      sscanf(buff, "%d", &cyc[i]);
  }
  int idx = -1;
  for (int i = (0); i < (n); ++i)
    if (cyc[i] == -1 && pre[i] != -1 && pre[i] != 0 &&
        (idx == -1 || pre[i] > pre[idx]))
      idx = i;
  for (int idxcyc = (0); idxcyc <= (n); ++idxcyc) {
    if ((idx == -1) != (idxcyc == 0)) continue;
    map<pair<int, int>, int> need;
    if (idxcyc != 0) need[make_pair(0, idxcyc)] = idxcyc;
    for (int i = (0); i < (n); ++i) {
      if (cyc[i] != -1) need[make_pair(0, cyc[i])] = cyc[i];
      if (pre[i] == -1 || pre[i] == 0 || cyc[i] == -1 && i != idx) continue;
      int curcyc = i == idx ? idxcyc : cyc[i], curpre = pre[i];
      while (!need.count(make_pair(curpre, curcyc)))
        need[make_pair(curpre, curcyc)] = 1, --curpre;
    }
    vector<pair<int, int> > have;
    vector<int> haveidx;
    map<pair<int, int>, vector<int> > res;
    for (int i = (0); i < (n); ++i) {
      int curcyc = i == idx ? idxcyc : cyc[i], curpre = pre[i];
      if (curpre == -1) {
        have.push_back(make_pair(curpre, curcyc)), haveidx.push_back(i);
      } else if (curpre == 0) {
        if (curcyc != -1) {
          res[make_pair(curpre, curcyc)].push_back(i);
          need[make_pair(0, curcyc)] =
              (need[make_pair(0, curcyc)] - 1 + curcyc) % curcyc;
        } else {
          have.push_back(make_pair(curpre, curcyc)), haveidx.push_back(i);
        }
      } else {
        if (curcyc != -1) {
          res[make_pair(curpre, curcyc)].push_back(i);
          need[make_pair(curpre, curcyc)] = 0;
        } else {
          have.push_back(make_pair(curpre, curcyc)), haveidx.push_back(i);
        }
      }
    }
    vector<pair<int, int> > want;
    for (map<pair<int, int>, int>::iterator i = need.begin(); i != need.end();
         ++i)
      for (int j = (0); j < (i->second); ++j) want.push_back(i->first);
    if (((int)(want).size()) > ((int)(have).size())) continue;
    for (int i = (0); i < (((int)(want).size())); ++i) adj[i].clear();
    for (int i = (0); i < (((int)(want).size())); ++i)
      for (int j = (0); j < (((int)(have).size())); ++j)
        if (ok(want[i], have[j])) adj[i].push_back(j);
    if (maxflow(((int)(want).size()), ((int)(have).size())) !=
        ((int)(want).size()))
      continue;
    for (int i = (0); i < (((int)(have).size())); ++i) {
      if (rmatch[i] != -1) {
        res[want[rmatch[i]]].push_back(haveidx[i]);
        continue;
      }
      int curcyc = have[i].second, curpre = have[i].first;
      if ((curpre == -1 || curpre == 0) && curcyc == -1)
        res[make_pair(0, 1)].push_back(haveidx[i]);
      else if (curpre == -1)
        res[make_pair(1, curcyc)].push_back(haveidx[i]);
      else if (curcyc == -1 && idxcyc != 0)
        res[make_pair(curpre, idxcyc)].push_back(haveidx[i]);
      else
        assert(false);
    }
    vector<int> ret(n, -1);
    for (map<pair<int, int>, vector<int> >::iterator i = res.begin();
         i != res.end(); ++i) {
      int curcyc = i->first.second, curpre = i->first.first;
      vector<int> idxs = i->second;
      if (curpre == 0) {
        assert(((int)(idxs).size()) % curcyc == 0);
        for (int i = (0); i < (((int)(idxs).size())); ++i)
          ret[idxs[i]] = idxs[i - i % curcyc + (i + 1) % curcyc];
      } else {
        assert(res.count(make_pair(curpre - 1, curcyc)));
        for (int i = (0); i < (((int)(idxs).size())); ++i)
          ret[idxs[i]] = res[make_pair(curpre - 1, curcyc)][0];
      }
    }
    for (int i = (0); i < (n); ++i) {
      if (i != 0) printf(" ");
      printf("%d", ret[i] + 1);
    }
    puts("");
    return;
  }
  printf("-1\n");
}
int main() {
  run();
  return 0;
}
