package main

/*
スタック 汎用的
型Assertionを入れると相当スピードが落ちるので,
適材適所で使うこと.
*/

import (
	"bufio"
	"bytes"
	"fmt"
	"log"
	"os"
	"strconv"
	"strings"
)

// Item スタックの要素
type Item interface {
	String() string
}

// Stack スタック
type Stack struct {
	data []Item
	idx  int
}

// NewStack スタック作成
func NewStack(maxLength int) *Stack {
	return &Stack{make([]Item, maxLength+1), 0}
}

// IsFull 一杯
func (s *Stack) IsFull() bool {
	return s.idx >= len(s.data)
}

// IsEmpty 空
func (s *Stack) IsEmpty() bool {
	return s.idx == 0
}

// Push プッシュ
func (s *Stack) Push(e Item) {
	if s.IsFull() {
		panic("stack is full.")
	}
	s.idx++
	s.data[s.idx] = e
}

// Pop ポップ
func (s *Stack) Pop() Item {
	if s.IsEmpty() {
		panic("stack is empty.")
	}
	e := s.data[s.idx]
	s.idx--
	return e
}

// Top 一番上の要素
func (s *Stack) Top() Item {
	if s.IsEmpty() {
		panic("stack is empty.")
	}
	return s.data[s.idx]
}

func (s *Stack) String() string {
	var buf bytes.Buffer
	sep := ""
	for i := 1; i <= s.idx; i++ {
		buf.WriteString(fmt.Sprintf("%s%s", sep, s.data[i].String()))
		sep = " "
	}
	return buf.String()
}

// Int int型Stack
type Int int

func (i Int) String() string {
	fmt.Printf("%d", i)
	return fmt.Sprintf("%d", i)
}

// PopInt Pop
func (s *Stack) PopInt() Int {
	e := s.Pop()
	i, _ := e.(Int)
	return i
}

// TopInt 一番上の要素
func (s *Stack) TopInt() Int {
	e := s.Top()
	i, _ := e.(Int)
	return i
}

// MyItem 構造体Stack
type MyItem struct {
	Left int
	Sum  int
}

func (m MyItem) String() string {
	return fmt.Sprintf("(%d %d)", m.Left, m.Sum)
}

// PopMyItem Pop
func (s *Stack) PopMyItem() MyItem {
	e := s.Pop()
	i, _ := e.(MyItem)
	return i
}

// TopMyItem 一番上の要素
func (s *Stack) TopMyItem() MyItem {
	e := s.Top()
	i, _ := e.(MyItem)
	return i
}

func calcArea(symbols []string) int {
	stack := NewStack(len(symbols))
	sum := 0
	for i, r := range symbols {
		if r == `\` {
			stack.Push(Int(i))
		} else if r == `/` {
			// 水たまりエリアを加算
			if !stack.IsEmpty() {
				left := stack.PopInt()
				sum += i - int(left)
			}
		}
	}
	return sum
}

func collectMizuTamari(symbols []string) ints {
	stack1 := NewStack(len(symbols))
	stack2 := NewStack(len(symbols))
	for i, r := range symbols {
		if r == `\` {
			stack1.Push(Int(i))
		} else if r == `/` {
			// 水エリア
			if !stack1.IsEmpty() {
				left := int(stack1.PopInt())
				mizu := i - int(left)
				for !stack2.IsEmpty() && left < stack2.TopMyItem().Left {
					stackItem := stack2.PopMyItem()
					mizu += stackItem.Sum
				}
				stack2.Push(MyItem{left, mizu})
			}
		}
	}
	result := []int{}
	for !stack2.IsEmpty() {
		a := stack2.PopMyItem()
		result = append(result, a.Sum)
	}
	return reverse(result)
}

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	symbols := eGetChars(scanner)
	fmt.Println(calcArea(symbols))
	tamari := collectMizuTamari(symbols)
	if len(tamari) > 0 {
		fmt.Printf("%d %s\n", len(tamari), tamari)
	} else {
		fmt.Printf("%d\n", len(tamari))
	}
}
func eGetLine(r *bufio.Scanner) string {
	if r.Scan() {
		return r.Text()
	}
	err := r.Err()
	if err != nil {
		log.Fatal(err)
	}
	// EOF
	return ""
}
func eGetInt(r *bufio.Scanner) int {
	line := eGetLine(r)
	return eAtoi(line)
}
func eGetFields(r *bufio.Scanner) []string {
	line := eGetLine(r)
	return strings.Fields(line)
}
func eGetInts(r *bufio.Scanner) []int {
	fields := eGetFields(r)
	var ints []int
	for _, f := range fields {
		ints = append(ints, eAtoi(f))
	}
	return ints
}
func eGetChars(r *bufio.Scanner) []string {
	line := eGetLine(r)
	return strings.Split(line, "")
}
func eAtoi(s string) int {
	n, err := strconv.Atoi(s)
	if err != nil {
		log.Fatal(err)
	}
	return n
}

type ints []int

func (s ints) String() string {
	var buf bytes.Buffer
	sep := ""
	for _, v := range s {
		buf.WriteString(fmt.Sprintf("%s%d", sep, v))
		sep = " "
	}
	return buf.String()
}

func reverse(a ints) ints {
	r := make(ints, len(a))
	for i := 0; i < len(a); i++ {
		r[i] = a[len(a)-1-i]
	}
	return r
}



Measured memory_bytes: 2532