Problem: Berkomnadzor — Federal Service for Supervision of Communications, Information Technology and Mass Media — is a Berland federal executive body that protects ordinary residents of Berland from the threats of modern internet.

Berkomnadzor maintains a list of prohibited IPv4 subnets (blacklist) and a list of allowed IPv4 subnets (whitelist). All Internet Service Providers (ISPs) in Berland must configure the network equipment to block access to all IPv4 addresses matching the blacklist. Also ISPs must provide access (that is, do not block) to all IPv4 addresses matching the whitelist. If an IPv4 address does not match either of those lists, it's up to the ISP to decide whether to block it or not. An IPv4 address matches the blacklist (whitelist) if and only if it matches some subnet from the blacklist (whitelist). An IPv4 address can belong to a whitelist and to a blacklist at the same time, this situation leads to a contradiction (see no solution case in the output description).

An IPv4 address is a 32-bit unsigned integer written in the form a.b.c.d, where each of the values a,b,c,d is called an octet and is an integer from 0 to 255 written in decimal notation. For example, IPv4 address 192.168.0.1 can be converted to a 32-bit number using the following expression 192 ⋅ 2^{24} + 168 ⋅ 2^{16} + 0 ⋅ 2^8 + 1 ⋅ 2^0. First octet a encodes the most significant (leftmost) 8 bits, the octets b and c — the following blocks of 8 bits (in this order), and the octet d encodes the least significant (rightmost) 8 bits.

The IPv4 network in Berland is slightly different from the rest of the world. There are no reserved or internal addresses in Berland and use all 2^{32} possible values.

An IPv4 subnet is represented either as a.b.c.d or as a.b.c.d/x (where 0 ≤ x ≤ 32). A subnet a.b.c.d contains a single address a.b.c.d. A subnet a.b.c.d/x contains all IPv4 addresses with x leftmost (most significant) bits equal to x leftmost bits of the address a.b.c.d. It is required that 32 - x rightmost (least significant) bits of subnet a.b.c.d/x are zeroes.

Naturally it happens that all addresses matching subnet a.b.c.d/x form a continuous range. The range starts with address a.b.c.d (its rightmost 32 - x bits are zeroes). The range ends with address which x leftmost bits equal to x leftmost bits of address a.b.c.d, and its 32 - x rightmost bits are all ones. Subnet contains exactly 2^{32-x} addresses. Subnet a.b.c.d/32 contains exactly one address and can also be represented by just a.b.c.d.

For example subnet 192.168.0.0/24 contains range of 256 addresses. 192.168.0.0 is the first address of the range, and 192.168.0.255 is the last one.

Berkomnadzor's engineers have devised a plan to improve performance of Berland's global network. Instead of maintaining both whitelist and blacklist they want to build only a single optimised blacklist containing minimal number of subnets. The idea is to block all IPv4 addresses matching the optimised blacklist and allow all the rest addresses. Of course, IPv4 addresses from the old blacklist must remain blocked and all IPv4 addresses from the old whitelist must still be allowed. Those IPv4 addresses which matched neither the old blacklist nor the old whitelist may be either blocked or allowed regardless of their accessibility before. 

Please write a program which takes blacklist and whitelist as input and produces optimised blacklist. The optimised blacklist must contain the minimal possible number of subnets and satisfy all IPv4 addresses accessibility requirements mentioned above. 

IPv4 subnets in the source lists may intersect arbitrarily. Please output a single number -1 if some IPv4 address matches both source whitelist and blacklist.

Input

The first line of the input contains single integer n (1 ≤ n ≤ 2⋅10^5) — total number of IPv4 subnets in the input.

The following n lines contain IPv4 subnets. Each line starts with either '-' or '+' sign, which indicates if the subnet belongs to the blacklist or to the whitelist correspondingly. It is followed, without any spaces, by the IPv4 subnet in a.b.c.d or a.b.c.d/x format (0 ≤ x ≤ 32). The blacklist always contains at least one subnet.

All of the IPv4 subnets given in the input are valid. Integer numbers do not start with extra leading zeroes. The provided IPv4 subnets can intersect arbitrarily.

Output

Output -1, if there is an IPv4 address that matches both the whitelist and the blacklist. Otherwise output t — the length of the optimised blacklist, followed by t subnets, with each subnet on a new line. Subnets may be printed in arbitrary order. All addresses matching the source blacklist must match the optimised blacklist. All addresses matching the source whitelist must not match the optimised blacklist. You can print a subnet a.b.c.d/32 in any of two ways: as a.b.c.d/32 or as a.b.c.d.

If there is more than one solution, output any.

Examples

Input

1
-149.154.167.99


Output

1
0.0.0.0/0


Input

4
-149.154.167.99
+149.154.167.100/30
+149.154.167.128/25
-149.154.167.120/29


Output

2
149.154.167.99
149.154.167.120/29


Input

5
-127.0.0.4/31
+127.0.0.8
+127.0.0.0/30
-195.82.146.208/29
-127.0.0.6/31


Output

2
195.0.0.0/8
127.0.0.4/30


Input

2
+127.0.0.1/32
-127.0.0.1


Output

-1

Solution (in CPP):

Solution:
#include <bits/stdc++.h>
using namespace std;
template <class T>
inline T sqr(const T &x) {
  return x * x;
}
inline long long sqr(int x) { return sqr<long long>(x); }
template <class T>
T binpow(const T &a, long long n) {
  return n == 0 ? 1 : sqr(binpow(a, n / 2)) * (n % 2 ? a : 1);
}
long long binpow(long long a, long long n, long long modulo) {
  return n == 0 ? 1
                : sqr(binpow(a, n / 2, modulo)) % modulo * (n % 2 ? a : 1) %
                      modulo;
}
long long gcd(long long a, long long b, long long &x, long long &y) {
  if (a == 0) {
    x = 0;
    y = 1;
    return b;
  }
  long long x1, y1;
  long long d = gcd(b % a, a, x1, y1);
  x = y1 - (b / a) * x1;
  y = x1;
  return d;
}
inline long long phi(long long n) {
  long long result = n;
  for (long long i = 2; i * i <= n; ++i)
    if (n % i == 0) {
      while (n % i == 0) n /= i;
      result -= result / i;
    }
  if (n > 1) result -= result / n;
  return result;
}
inline vector<long long> inverseAll(long long m) {
  vector<long long> r(m);
  r[1] = 1;
  for (int i = 2; i < m; ++i) r[i] = (m - (m / i) * r[m % i] % m) % m;
  return r;
}
inline long long gcd(long long a, long long b) { return gcd(a, b, a, b); }
inline long long lcm(long long a, long long b) { return a / gcd(a, b) * b; }
inline long long llrand() {
  const long long lsbToFill = (sizeof(long long) << 3) - 1;
  const long long bitsFilledInIteration = __builtin_popcountll(RAND_MAX);
  long long number = 0;
  for (long long lsbFilled = 0; lsbFilled <= lsbToFill;
       lsbFilled += bitsFilledInIteration) {
    number ^= (((long long)rand()) << lsbFilled);
  }
  return number & numeric_limits<long long>::max();
}
inline long long llrand(long long begin, long long end) {
  return begin + llrand() % (end - begin);
}
struct Dinic {
  struct Edge {
    int u, v;
    long long cap, flow;
    Edge() {}
    Edge(int u, int v, long long cap) : u(u), v(v), cap(cap), flow(0) {}
  };
  int N;
  vector<Edge> E;
  vector<vector<int>> g;
  vector<int> d, pt;
  Dinic(int N) : N(N), E(0), g(N), d(N), pt(N) {}
  void AddEdge(int u, int v, long long cap) {
    if (u != v) {
      E.emplace_back(Edge(u, v, cap));
      g[u].emplace_back(E.size() - 1);
      E.emplace_back(Edge(v, u, 0));
      g[v].emplace_back(E.size() - 1);
    }
  }
  bool BFS(int S, int T) {
    queue<int> q({S});
    fill(d.begin(), d.end(), N + 1);
    d[S] = 0;
    while (!q.empty()) {
      int u = q.front();
      q.pop();
      if (u == T) break;
      for (int k : g[u]) {
        Edge &e = E[k];
        if (e.flow < e.cap && d[e.v] > d[e.u] + 1) {
          d[e.v] = d[e.u] + 1;
          q.emplace(e.v);
        }
      }
    }
    return d[T] != N + 1;
  }
  long long DFS(int u, int T, long long flow = -1) {
    if (u == T || flow == 0) return flow;
    for (int &i = pt[u]; i < g[u].size(); ++i) {
      Edge &e = E[g[u][i]];
      Edge &oe = E[g[u][i] ^ 1];
      if (d[e.v] == d[e.u] + 1) {
        long long amt = e.cap - e.flow;
        if (flow != -1 && amt > flow) amt = flow;
        if (long long pushed = DFS(e.v, T, amt)) {
          e.flow += pushed;
          oe.flow -= pushed;
          return pushed;
        }
      }
    }
    return 0;
  }
  long long MaxFlow(int S, int T) {
    long long total = 0;
    while (BFS(S, T)) {
      fill(pt.begin(), pt.end(), 0);
      while (long long flow = DFS(S, T)) total += flow;
    }
    return total;
  }
};
vector<long long> Dijkstra(const vector<list<pair<int, long long>>> &g, int s) {
  vector<long long> d(int((g).size()), numeric_limits<long long>::max() / 2LL);
  priority_queue<pair<long long, int>> q;
  d[s] = 0;
  q.emplace(-0, s);
  while (!q.empty()) {
    while (q.top().first > d[q.top().second]) {
      q.pop();
    }
    int v = q.top().second;
    q.pop();
    for (const auto &cw : g[v]) {
      if (d[v] + cw.second < d[cw.first]) {
        d[cw.first] = d[v] + cw.second;
        q.emplace(-d[cw.first], cw.first);
      }
    }
  }
  return d;
}
struct BinarySearchIterator
    : public std::iterator<std::forward_iterator_tag, bool> {
  long long value;
  typename iterator_traits<BinarySearchIterator>::difference_type operator-(
      const BinarySearchIterator &it) const {
    return value - it.value;
  }
  BinarySearchIterator &operator++() {
    ++value;
    return *this;
  }
  bool operator!=(const BinarySearchIterator &it) const {
    return value != it.value;
  }
  bool operator*() const { return true; }
};
template <int ALPHA>
class AhoCorasick {
 public:
  static const int ILLEGAL_INDEX;
  static const int ROOT;
  struct Node {
    bool leaf;
    int parent;
    int parentCharacter;
    int link;
    int next[ALPHA];
    int go[ALPHA];
    int outputFunction;
    Node(int parent = ILLEGAL_INDEX, int parentCharacter = ALPHA)
        : leaf(false),
          parent(parent),
          parentCharacter(parentCharacter),
          link(ILLEGAL_INDEX),
          outputFunction(ILLEGAL_INDEX) {
      fill_n(next, ALPHA, ILLEGAL_INDEX);
      fill_n(go, ALPHA, ILLEGAL_INDEX);
    }
  };
  vector<Node> tree = vector<Node>(1);
  AhoCorasick() {}
  AhoCorasick(int maxStatesNumber) { tree.reserve(maxStatesNumber); }
  template <class Iterator>
  void add(int length, const Iterator begin) {
    int vertex = ROOT;
    for (int i = 0; i < length; ++i) {
      if (ILLEGAL_INDEX == tree[vertex].next[begin[i]]) {
        tree[vertex].next[begin[i]] = int((tree).size());
        tree.push_back(Node(vertex, begin[i]));
      }
      vertex = tree[vertex].next[begin[i]];
    }
    tree[vertex].leaf = true;
  }
  int getLink(int vertex) {
    assert(0 <= vertex && vertex < tree.size());
    if (ILLEGAL_INDEX == tree[vertex].link) {
      if (ROOT == vertex || ROOT == tree[vertex].parent) {
        tree[vertex].link = ROOT;
      } else {
        tree[vertex].link =
            go(getLink(tree[vertex].parent), tree[vertex].parentCharacter);
      }
    }
    return tree[vertex].link;
  }
  int go(int vertex, int character) {
    assert(0 <= character && character < ALPHA);
    assert(0 <= vertex && vertex < tree.size());
    if (ILLEGAL_INDEX == tree[vertex].go[character]) {
      if (ILLEGAL_INDEX == tree[vertex].next[character]) {
        tree[vertex].go[character] =
            ROOT == vertex ? ROOT : go(getLink(vertex), character);
      } else {
        tree[vertex].go[character] = tree[vertex].next[character];
      }
    }
    return tree[vertex].go[character];
  }
  int getOutputFunction(int vertex) {
    assert(0 <= vertex && vertex < tree.size());
    if (ILLEGAL_INDEX == tree[vertex].outputFunction) {
      if (tree[vertex].leaf || ROOT == vertex) {
        tree[vertex].outputFunction = vertex;
      } else {
        tree[vertex].outputFunction = getOutputFunction(getLink(vertex));
      }
    }
    return tree[vertex].outputFunction;
  }
};
template <int ALPHA>
const int AhoCorasick<ALPHA>::ILLEGAL_INDEX = -1;
template <int ALPHA>
const int AhoCorasick<ALPHA>::ROOT = 0;
string address_to_string(int a, int b, int c, int d, int x) {
  string address;
  int numbers[] = {a, b, c, d};
  for (int i = 0; i < 4; ++i) {
    for (int j = 7; j >= 0; --j) {
      address.push_back('0' + ((numbers[i] >> j) & 1));
    }
  }
  assert(int((address).size()) == 32);
  address = address.substr(0, x);
  return address;
}
tuple<int, int, int, int, int> string_to_answer(const string &s) {
  int numbers[4] = {0, 0, 0, 0};
  int x = 0;
  for (int i = 0; i < 4; ++i) {
    for (int j = 7; j >= 0; --j) {
      if (x < int((s).size())) {
        numbers[i] |= ((s[x] - '0') << j);
        ++x;
      }
    }
  }
  return tie(numbers[0], numbers[1], numbers[2], numbers[3], x);
}
const int ALPHA = 2;
enum {
  UNDEFINED = -1,
  WHITE = 0,
  BLACK = 1,
};
vector<int> nextn[ALPHA];
vector<int> endn;
vector<int> values;
bool insert(const string &s, int value) {
  int v = 0;
  for (int i = 0; i < s.size(); ++i) {
    int c = s[i] - '0';
    if (-1 == nextn[c][v]) {
      nextn[c][v] = int((nextn[c]).size());
      endn.push_back(0);
      values.push_back(UNDEFINED);
      for (int cc = 0; cc < ALPHA; ++cc) {
        nextn[cc].push_back(-1);
      }
    }
    assert(nextn[c][v] != -1);
    v = nextn[c][v];
  }
  ++endn[v];
  if (-1 == values[v]) {
    values[v] = value;
  }
  return value == values[v];
}
bool propagate(int vertex, int value) {
  if (UNDEFINED != values[vertex]) {
    if (UNDEFINED != value && value != values[vertex]) {
      return false;
    }
    value = values[vertex];
  }
  bool success = true;
  set<int> possible_values = {value};
  possible_values.erase(UNDEFINED);
  for (int c = 0; c < ALPHA; ++c) {
    if (-1 != nextn[c][vertex]) {
      success &= propagate(nextn[c][vertex], value);
      possible_values.insert(values[nextn[c][vertex]]);
    }
  }
  if (int((possible_values).size()) == 1) {
    assert(!success || UNDEFINED == values[vertex] ||
           *possible_values.rbegin() == values[vertex]);
    values[vertex] = *possible_values.rbegin();
  }
  return success;
}
list<string> create_set(int vertex, string current = "") {
  if (BLACK == values[vertex]) {
    return {current};
  }
  list<string> result;
  for (int c = 0; c < ALPHA; ++c) {
    if (-1 != nextn[c][vertex]) {
      auto subset = create_set(nextn[c][vertex], current + char(c + '0'));
      result.insert(result.begin(), (subset).begin(), (subset).end());
    }
  }
  return result;
}
int main(int argc, const char *argv[]) {
  ios::sync_with_stdio(false);
  cin.tie(0);
  srand((unsigned int)time(NULL));
  int n;
  while (~scanf("%d", &n)) {
    bool success = true;
    for (int i = (0); i < (ALPHA); ++i) nextn[i].assign(1, -1);
    endn.assign(1, 0);
    values.assign(1, UNDEFINED);
    for (int i = (0); i < (n); ++i) {
      char type;
      int a, b, c, d, x;
      int count = scanf(" %c%d.%d.%d.%d/%d", &type, &a, &b, &c, &d, &x);
      if (count == 5) {
        x = 32;
      }
      assert(count == 5 || count == 6);
      string address = address_to_string(a, b, c, d, x);
      success &= insert(address, (type == '-') * BLACK + (type == '+') * WHITE);
    }
    if (success && propagate(0, UNDEFINED)) {
      const auto answer = create_set(0);
      printf("%d\n", int((answer).size()));
      for (const auto &current : answer) {
        int a, b, c, d, x;
        tie(a, b, c, d, x) = string_to_answer(current);
        printf("%d.%d.%d.%d/%d\n", a, b, c, d, x);
      }
    } else {
      printf("-1\n");
    }
  }
  return 0;
}