← Home
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()
}