```go
package main
import (
"bufio"
"fmt"
"os"
"sort"
"strconv"
"strings"
)
type rangePair struct {
start uint32
end uint32
}
type Subnet struct {
ip uint32
mask int
}
type node struct {
children [2]*node
force_req bool
force_forb bool
}
func newNode() *node {
return &node{}
}
func insert(root *node, base uint32, mask int, isReq bool) {
cur := root
val := base
for d := 0; d < mask; d++ {
bit := (val >> (31 - d)) & 1
if cur.children[bit] == nil {
cur.children[bit] = newNode()
}
cur = cur.children[bit]
}
if isReq {
cur.force_req = true
} else {
cur.force_forb = true
}
}
func build(n *node, val uint32, depth int) (bool, bool, int, []Subnet) {
if n == nil {
return false, false, 0, nil
}
lreq, lforb, lnum, lsubs := build(n.children[0], (val<<1)|uint32(0), depth+1)
rreq, rforb, rnum, rsubs := build(n.children[1], (val<<1)|uint32(1), depth+1)
hreq := n.force_req || lreq || rreq
hforb := n.force_forb || lforb || rforb
if !hreq {
return hreq, hforb, 0, nil
}
if !hforb {
b := val << (32 - depth)
m := depth
return hreq, hforb, 1, []Subnet{{b, m}}
}
num := lnum + rnum
var subs []Subnet
subs = append(subs, lsubs...)
subs = append(subs, rsubs...)
return hreq, hforb, num, subs
}
func decompose(s uint32, e uint32) []Subnet {
var res []Subnet
pos := uint64(s)
ee := uint64(e)
for pos <= ee {
maxb := 0
limit := ee - pos + 1
for b := 0; b <= 32; b++ {
sz := uint64(1) << uint64(b)
if sz > limit {
break
}
if pos%sz == 0 {
maxb = b
}
}
sz := uint64(1) << uint64(maxb)
base := uint32(pos)
masklen := 32 - maxb
res = append(res, Subnet{base, masklen})
pos += sz
}
return res
}
func mergeRanges(ranges []rangePair) []rangePair {
if len(ranges) == 0 {
return nil
}
sort.Slice(ranges, func(i, j int) bool { return ranges[i].start < ranges[j].start })
var merged []rangePair
merged = append(merged, ranges[0])
for i := 1; i < len(ranges); i++ {
last := &merged[len(merged)-1]
if last.end >= ranges[i].start {
if last.end < ranges[i].end {
last.end = ranges[i].end
}
} else {
merged = append(merged, ranges[i])
}
}
return merged
}
func hasOverlap(black, white []rangePair) bool {
i, j := 0, 0
for i < len(black) && j < len(white) {
if black[i].end < white[j].start {
i++
continue
}
if white[j].end < black[i].start {
j++
continue
}
return true
}
return false
}
func parseIP(ipstr string) uint32 {
parts := strings.Split(ipstr, ".")
a, _ := strconv.Atoi(parts[0])
b, _ := strconv.Atoi(parts[1])
c, _ := strconv.Atoi(parts[2])
d, _ := strconv.Atoi(parts[3])
return uint32(a<<24 | b<<16 | c<<8 | d)
}
func main() {
scanner := bufio.NewScanner(os.Stdin)
scanner.Scan()
n, _ := strconv.Atoi(scanner.Text())
var blacks []rangePair
var whites []rangePair
for i := 0; i < n; i++ {
scanner.Scan()
line := scanner.Text()
sign := line[0]
substr := line[1:]
var ipstr string
x := 32
if strings.Contains(substr, "/") {
parts := strings.Split(substr, "/")
ipstr = parts[0]
x, _ = strconv.Atoi(parts[1])
} else {
ipstr = substr
}
ip := parseIP(ipstr)
var start, end uint32
start = ip
if x == 0 {
start = 0
end = 4294967295
} else {
size := uint32(1) << (32 - x)
end = start + size - 1
}
if sign == '-' {
blacks = append(blacks, rangePair{start, end})
} else {
whites = append(whites, rangePair{start, end})
}
}
mblack := mergeRanges(blacks)
mwhite := mergeRanges(whites)
if hasOverlap(mblack, mwhite) {
fmt.Println(-1)
return
}
root := newNode()
for _, r := range mblack {
for _, sub := range decompose(r.start, r.end) {
insert(root, sub.ip, sub.mask, true)
}
}
for _, r := range mwhite {
for _, sub := range decompose(r.start, r.end) {
insert(root, sub.ip, sub.mask, false)
}
}
_, _, num, subs := build(root, 0, 0)
fmt.Println(num)
for _, sub := range subs {
a := sub.ip >> 24
b := (sub.ip >> 16) & 255
c := (sub.ip >> 8) & 255
d := sub.ip & 255
if sub.mask == 32 {
fmt.Printf("%d.%d.%d.%d\n", a, b, c, d)
} else {
fmt.Printf("%d.%d.%d.%d/%d\n", a, b, c, d, sub.mask)
}
}
}
```