package main
import (
"bufio"
"fmt"
"os"
"strconv"
)
type Node struct {
child [2]int32
flags uint8
}
const (
WhiteEnd = 1 << 0
BlackEnd = 1 << 1
HasWhite = 1 << 2
HasBlack = 1 << 3
)
var nodes []Node
var conflict bool
var ans []string
func parseIP(s string) (uint32, int) {
var ip uint32
var length int = 32
var current uint32
var isLen bool
for i := 0; i < len(s); i++ {
if s[i] == '.' {
ip = (ip << 8) | current
current = 0
} else if s[i] == '/' {
ip = (ip << 8) | current
current = 0
isLen = true
} else {
current = current*10 + uint32(s[i]-'0')
}
}
if isLen {
length = int(current)
} else {
ip = (ip << 8) | current
}
return ip, length
}
func insert(ip uint32, length int, isWhite bool) {
curr := int32(0)
for i := 0; i < length; i++ {
bit := (ip >> (31 - i)) & 1
if nodes[curr].child[bit] == 0 {
nodes = append(nodes, Node{})
nodes[curr].child[bit] = int32(len(nodes) - 1)
}
curr = nodes[curr].child[bit]
}
if isWhite {
nodes[curr].flags |= WhiteEnd
} else {
nodes[curr].flags |= BlackEnd
}
}
func dfs1(u int32) {
left := nodes[u].child[0]
right := nodes[u].child[1]
if left != 0 {
dfs1(left)
}
if right != 0 {
dfs1(right)
}
flags := nodes[u].flags
hasWhite := (flags & WhiteEnd) != 0
hasBlack := (flags & BlackEnd) != 0
if left != 0 {
if (nodes[left].flags & HasWhite) != 0 {
hasWhite = true
}
if (nodes[left].flags & HasBlack) != 0 {
hasBlack = true
}
}
if right != 0 {
if (nodes[right].flags & HasWhite) != 0 {
hasWhite = true
}
if (nodes[right].flags & HasBlack) != 0 {
hasBlack = true
}
}
if hasWhite {
nodes[u].flags |= HasWhite
}
if hasBlack {
nodes[u].flags |= HasBlack
}
if ((flags&WhiteEnd) != 0 && hasBlack) || ((flags&BlackEnd) != 0 && hasWhite) {
conflict = true
}
}
func formatIP(ip uint32, length int) string {
return strconv.Itoa(int((ip>>24)&255)) + "." +
strconv.Itoa(int((ip>>16)&255)) + "." +
strconv.Itoa(int((ip>>8)&255)) + "." +
strconv.Itoa(int(ip&255)) + "/" +
strconv.Itoa(length)
}
func dfs2(u int32, ip uint32, length int) {
hasWhite := (nodes[u].flags & HasWhite) != 0
hasBlack := (nodes[u].flags & HasBlack) != 0
if hasBlack && !hasWhite {
ans = append(ans, formatIP(ip, length))
return
}
if hasBlack && hasWhite {
left := nodes[u].child[0]
right := nodes[u].child[1]
if left != 0 {
dfs2(left, ip, length+1)
}
if right != 0 {
dfs2(right, ip|(1<<(31-length)), length+1)
}
}
}
func main() {
scanner := bufio.NewScanner(os.Stdin)
scanner.Buffer(make([]byte, 1024*1024), 10*1024*1024)
scanner.Split(bufio.ScanWords)
if !scanner.Scan() {
return
}
n, _ := strconv.Atoi(scanner.Text())
nodes = make([]Node, 1, 6500000)
for i := 0; i < n; i++ {
scanner.Scan()
s := scanner.Text()
isWhite := s[0] == '+'
ip, length := parseIP(s[1:])
insert(ip, length, isWhite)
}
dfs1(0)
if conflict {
fmt.Println("-1")
return
}
dfs2(0, 0, 0)
out := bufio.NewWriter(os.Stdout)
out.WriteString(strconv.Itoa(len(ans)) + "\n")
for _, s := range ans {
out.WriteString(s + "\n")
}
out.Flush()
}