package main

import (
	"bufio"
	. "fmt"
	"index/suffixarray"
	"io"
	"os"
	"reflect"
	"unsafe"
)

// github.com/EndlessCheng/codeforces-go
func Sol427D(reader io.Reader, writer io.Writer) {
	min := func(a, b int) int {
		if a <= b {
			return a
		}
		return b
	}
	max := func(a, b int) int {
		if a >= b {
			return a
		}
		return b
	}

	in := bufio.NewReader(reader)
	out := bufio.NewWriter(writer)
	defer out.Flush()

	var s, t []byte
	Fscan(in, &s, &t)

	lenS1 := len(s)
	s = append(s, '$')
	s = append(s, t...)
	sa := *(*[]int)(unsafe.Pointer(reflect.ValueOf(suffixarray.New(s)).Elem().FieldByName("sa").UnsafeAddr()))
	sa = append([]int{len(s)}, sa...)

	n := len(s)
	rank := make([]int, n+1)
	for i := range rank {
		rank[sa[i]] = i
	}
	lcp := make([]int, n, n+1)
	h := 0
	for i := range lcp {
		j := sa[rank[i]-1]
		if h > 0 {
			h--
		}
		for ; j+h < n && i+h < n; h++ {
			if s[j+h] != s[i+h] {
				break
			}
		}
		lcp[rank[i]-1] = h
	}
	lcp = append(lcp, 0)

	const inf int = 1e9
	ans := inf
	for i := 2; i < n; i++ {
		if (sa[i] < lenS1) != (sa[i+1] < lenS1) && lcp[i-1] < lcp[i] && lcp[i+1] < lcp[i] {
			ans = min(ans, 1+max(lcp[i-1], lcp[i+1]))
		}
	}
	if ans == inf {
		ans = -1
	}
	Fprint(out, ans)
}

func main() {
	Sol427D(os.Stdin, os.Stdout)
}

package main

import (
	"bufio"
	. "fmt"
	"index/suffixarray"
	"io"
	"os"
	"reflect"
	"unsafe"
)

// github.com/EndlessCheng/codeforces-go
func CF427D(_r io.Reader, _w io.Writer) {
	in := bufio.NewReader(_r)
	out := bufio.NewWriter(_w)
	defer out.Flush()
	max := func(a, b int) int {
		if a > b {
			return a
		}
		return b
	}

	var s, t []byte
	Fscan(in, &s, &t)
	lenS1 := int32(len(s))
	s = append(append(s, '{'), t...)
	n := len(s)

	sa := *(*[]int32)(unsafe.Pointer(reflect.ValueOf(suffixarray.New(s)).Elem().FieldByName("sa").Field(0).UnsafeAddr()))
	rank := make([]int, n)
	for i := range rank {
		rank[sa[i]] = i
	}
	height := make([]int, n)
	h := 0
	for i, ri := range rank {
		if h > 0 {
			h--
		}
		if ri > 0 {
			for j := int(sa[ri-1]); i+h < n && j+h < n && s[i+h] == s[j+h]; h++ {
			}
		}
		height[ri] = h
	}

	ans := int(1e9)
	for i := 1; i+1 < n; i++ {
		if (sa[i-1] < lenS1) != (sa[i] < lenS1) && height[i-1] < height[i] && height[i] > height[i+1] {
			if l := 1 + max(height[i-1], height[i+1]); l < ans {
				ans = l
			}
		}
	}
	if ans == 1e9 {
		ans = -1
	}
	Fprint(out, ans)
}

func main() { CF427D(os.Stdin, os.Stdout) }

package main

import (
	"bufio"
	. "fmt"
	"index/suffixarray"
	"io"
	"os"
	"reflect"
	"unsafe"
)

// github.com/EndlessCheng/codeforces-go
func Sol427D(reader io.Reader, writer io.Writer) {
	calcLCP := func(s []byte, sa []int) (lcp []int) {
		n := len(s)
		rank := make([]int, n+1)
		for i := range rank {
			rank[sa[i]] = i
		}
		lcp = make([]int, n, n+1)
		h := 0
		for i := range lcp {
			j := sa[rank[i]-1]
			if h > 0 {
				h--
			}
			for ; j+h < n && i+h < n && s[j+h] == s[i+h]; h++ {
			}
			lcp[rank[i]-1] = h
		}
		return
	}
	min := func(a, b int) int {
		if a <= b {
			return a
		}
		return b
	}
	max := func(a, b int) int {
		if a >= b {
			return a
		}
		return b
	}

	in := bufio.NewReader(reader)
	out := bufio.NewWriter(writer)
	defer out.Flush()

	var s, t []byte
	Fscan(in, &s, &t)
	lenS1 := len(s)
	s = append(s, '$')
	s = append(s, t...)
	n := len(s)

	sa := *(*[]int)(unsafe.Pointer(reflect.ValueOf(suffixarray.New(s)).Elem().FieldByName("sa").UnsafeAddr()))
	sa = append([]int{len(s)}, sa...)
	lcp := calcLCP(s, sa)
	lcp = append(lcp, 0)

	const inf int = 1e9
	ans := inf
	for i := 2; i < n; i++ {
		if (sa[i] < lenS1) != (sa[i+1] < lenS1) && lcp[i-1] < lcp[i] && lcp[i+1] < lcp[i] {
			ans = min(ans, max(lcp[i-1], lcp[i+1])+1)
		}
	}
	if ans == inf {
		ans = -1
	}
	Fprint(out, ans)
}

func main() {
	Sol427D(os.Stdin, os.Stdout)
}

package main

import (
	"bufio"
	. "fmt"
	"index/suffixarray"
	"io"
	"os"
	"reflect"
	"unsafe"
)

// github.com/EndlessCheng/codeforces-go
func Sol427D(reader io.Reader, writer io.Writer) {
	min := func(a, b int) int {
		if a <= b {
			return a
		}
		return b
	}
	max := func(a, b int) int {
		if a >= b {
			return a
		}
		return b
	}

	in := bufio.NewReader(reader)
	out := bufio.NewWriter(writer)
	defer out.Flush()

	var s, t []byte
	Fscan(in, &s, &t)

	lenS1 := len(s)
	s = append(s, '$')
	s = append(s, t...)
	sa := *(*[]int)(unsafe.Pointer(reflect.ValueOf(suffixarray.New(s)).Elem().FieldByName("sa").UnsafeAddr()))
	sa = append([]int{len(s)}, sa...)

	n := len(s)
	rank := make([]int, n+1)
	for i := range rank {
		rank[sa[i]] = i
	}
	lcp := make([]int, n)
	h := 0
	for i := range lcp {
		j := sa[rank[i]-1]
		if h > 0 {
			h--
		}
		for ; j+h < n && i+h < n; h++ {
			if s[j+h] != s[i+h] {
				break
			}
		}
		lcp[rank[i]-1] = h
	}
	lcp = append(lcp, 0)

	const inf int = 1e9
	ans := inf
	for i := 2; i < n; i++ {
		if (sa[i] < lenS1) != (sa[i+1] < lenS1) && lcp[i-1] < lcp[i] && lcp[i+1] < lcp[i] {
			ans = min(ans, 1+max(lcp[i-1], lcp[i+1]))
		}
	}
	if ans == inf {
		ans = -1
	}
	Fprint(out, ans)
}

func main() {
	Sol427D(os.Stdin, os.Stdout)
}

package main

import (
	"bufio"
	"bytes"
	"errors"
	"flag"
	"fmt"
	"io"
	"log"
	"os"
	"strconv"
	"time"
	"unicode/utf8"
)

// ******************************** CODE STARTS ********************************

var (
)

func lcp(s1, s2 []byte) [][]int {
	n1 := len(s1)
	n2 := len(s2)
	L := make([][]int, n1)
	for i := 0; i < n1; i++ {
		L[i] = make([]int, n2)
	}

	for i1 := n1 - 1; i1 >= 0; i1-- {
		for i2 := n2 - 1; i2 >= 0; i2-- {
			if s1[i1] == s2[i2] {
				L[i1][i2] = 1
				if i1 + 1 < n1 && i2 + 1 < n2 {
					L[i1][i2] += L[i1 + 1][i2 + 1]
				}
			} else {
				L[i1][i2] = 0
			}
		}
	}

	return L
}

func unique(L [][]int) []int {
	res := make([]int, len(L))
	for j := 0; j < len(L); j++ {
		res[j] = -1
		value := 0
		for i := 0; i < len(L[j]); i++ {
			if j != i {
				value = maxInt(value, L[j][i])
			}
		}
		if j + value < len(L) {
			res[j] = value + 1
		}
	}
	return res
}

func solve() {
	s1 := []byte(readString())
	s2 := []byte(readString())

	L1 := unique(lcp(s1, s1))
//	logln(string(s1))
//	logln(L1)
	L2 := unique(lcp(s2, s2))
//	logln(string(s2))
//	logln(L2)

	lcp12 := lcp(s1, s2)

	ans := -1
	for j := 0; j < len(s1); j++ {
		for i := 0; i < len(s2); i++ {
			if L1[j] != -1 && L2[i] != -1 {
				l := maxInt(L1[j], L2[i])
				if l != -1 && l <= lcp12[j][i] {
					if ans == -1 || ans > l {
//						logln(j)
//						logln(i)
//						logln(l)
//						logln("lol")
						ans = l
					}
				}
			}
		}
	}

	printInt(ans)
	printLine()

}

// ********************************* CODE ENDS *********************************

// IO.

var (
	scanner *Scanner
	writer  *bufio.Writer
	logger  *log.Logger
)

func main() {
	local := flag.Bool("local", false, "Equals true, if run is local.")
	flag.Parse()

	var (
		input  *os.File
		output *os.File
	)

	if *local {
		startTime := time.Now()
		defer func() {
			println(fmt.Sprintf("Time: %.5fs", time.Since(startTime).Seconds()))
		}()
		input, _ = os.Open("/home/outside/coding/workspace/go/io/input.txt")
		output, _ = os.Create("/home/outside/coding/workspace/go/io/output.txt")
		logger = log.New(output, "log: ", 0)
	} else {
		input = os.Stdin
		output = os.Stdout
		// input, _ = os.Open("")
		// output, _ = os.Create("")
	}
	defer input.Close()
	defer output.Close()

	scanner = NewScanner(input)
	scanner.Split(bufio.ScanWords)

	writer = bufio.NewWriter(output)
	defer writer.Flush()

	solve()
}

// Read.

func readString() string {
	scanner.Scan()
	ans := scanner.Text()
	return ans
}

func readLine() string {
	scanner.Split(bufio.ScanLines)
	defer scanner.Split(bufio.ScanWords)
	return readString()
}

func readInt() int {
	ans, _ := strconv.ParseInt(readString(), 10, 0)
	return int(ans)
}

func readInt64() int64 {
	ans, _ := strconv.ParseInt(readString(), 10, 64)
	return ans
}

func readFloat64() float64 {
	ans, _ := strconv.ParseFloat(readString(), 64)
	return ans
}

// Write.

func printString(value string) {
	writer.WriteString(value)
}

func printLine() {
	printString("\n")
}

func printInt(value int) {
	printString(strconv.FormatInt(int64(value), 10))
}

func printInt64(value int64) {
	printString(strconv.FormatInt(value, 10))
}

func printFLoat64(value float64) {
	printString(strconv.FormatFloat(value, 'f', 20, 64))
}

// Log.

func logln(value ...interface{}) {
	writer.Flush()
	logger.Println(value...)
}
func logf(format string, value ...interface{}) {
	writer.Flush()
	logger.Printf(format, value...)
}

// Tuple

type Tuple struct {
	a, b int
}

func (p Tuple) Equals(key Key) bool {
	return p.a == key.(Tuple).a
}

func (p Tuple) Less(key Key) bool {
	return p.a < key.(Tuple).a
}

type TupleSlice []Tuple

func (p TupleSlice) Len() int {
	return len(p)
}

func (p TupleSlice) Less(j, i int) bool {
	return p[j].a < p[i].a
}

func (p TupleSlice) Swap(j, i int) {
	p[j], p[i] = p[i], p[j]
}

// Min, max, abs.

func maxInt(a, b int) int {
	if a > b {
		return a
	} else {
		return b
	}
}

func minInt(a, b int) int {
	if a < b {
		return a
	} else {
		return b
	}
}

func absInt(a int) int {
	if a > 0 {
		return a
	} else {
		return -a
	}
}

func maxInt64(a, b int64) int64 {
	if a > b {
		return a
	} else {
		return b
	}
}

func minInt64(a, b int64) int64 {
	if a < b {
		return a
	} else {
		return b
	}
}

func absInt64(a int64) int64 {
	if a > 0 {
		return a
	} else {
		return -a
	}
}

func maxFloat64(a, b float64) float64 {
	if a > b {
		return a
	} else {
		return b
	}
}

func minFloat64(a, b float64) float64 {
	if a < b {
		return a
	} else {
		return b
	}
}

func absFloat64(a float64) float64 {
	if a > 0 {
		return a
	} else {
		return -a
	}
}

// Set Key interface implementations.

type Int int

func (p Int) Equals(key Key) bool {
	return int(p) == int(key.(Int))
}

func (p Int) Less(key Key) bool {
	return int(p) < int(key.(Int))
}

// Set.

type Key interface {
	Equals(key Key) bool
	Less(key Key) bool
}

type node struct {
	key   Key
	left  *node
	right *node
}

func newNode(key Key) *node {
	return &node{key, nil, nil}
}

type SplayTree struct {
	root *node
	tmp  *node
	len  int
}

func NewSplayTree() *SplayTree {
	return &SplayTree{nil, newNode(nil), 0}
}

func rotateLeft(x, p *node) {
	p.right = x.left
	x.left = p
}

func rotateRight(x, p *node) {
	p.left = x.right
	x.right = p
}

func (p *SplayTree) splay(x *node, key Key) *node {
	if x == nil {
		return nil
	}

	left := p.tmp
	right := p.tmp

	for {
		if key.Less(x.key) {
			y := x.left
			if y == nil {
				break
			}
			if key.Less(y.key) { // zig-zig
				rotateRight(y, x)
				x = y
				if x.left == nil {
					break
				}
			}
			// link right
			right.left = x
			right = x
			// move left
			x = x.left
		} else if x.key.Less(key) {
			y := x.right
			if y == nil {
				break
			}
			if y.key.Less(key) { // zig-zig
				rotateLeft(y, x)
				x = y
				if x.right == nil {
					break
				}
			}
			// link left
			left.right = x
			left = x
			// move right
			x = x.right
		} else {
			break
		}
	}

	left.right = x.left
	right.left = x.right
	x.left = p.tmp.right
	x.right = p.tmp.left

	return x
}

// left <= key < right
func (p *SplayTree) split(key Key) (left, right *node) {
	p.root = p.splay(p.root, key)
	if p.root.key.Equals(key) || p.root.key.Less(key) {
		right := p.root.right
		p.root.right = nil
		return p.root, right
	} else {
		left := p.root.left
		p.root.left = nil
		return left, p.root
	}
}

// keys from left tree must be less then keys from right tree
func (p *SplayTree) join(left, right *node) *node {
	if left == nil {
		return right
	} else if right == nil {
		return left
	}
	left = p.splay(left, right.key)
	left.right = right
	return left
}

type Set interface {
	Len() int
	Insert(key Key) error
	Find(key Key) bool
	Remove(key Key) error
}

func NewSet() Set {
	return Set(NewSplayTree())
}

func (p *SplayTree) Len() int {
	return p.len
}

func (p *SplayTree) Insert(key Key) error {
	if p.root == nil {
		p.root = newNode(key)
		p.len++
	} else {
		p.root = p.splay(p.root, key)
		if p.root.key.Equals(key) {
			return errors.New("Such key already exists")
		} else {
			left, right := p.split(key)
			p.root = newNode(key)
			p.root.left = left
			p.root.right = right
			p.len++
		}
	}
	return nil
}

func (p *SplayTree) Find(key Key) bool {
	if p.root == nil {
		return false
	}
	p.root = p.splay(p.root, key)
	return p.root.key.Equals(key)
}

func (p *SplayTree) Remove(key Key) error {
	p.root = p.splay(p.root, key)
	if p.root == nil || !p.root.key.Equals(key) {
		return errors.New("Such key doesn't exist")
	}
	p.root = p.join(p.split(key))
	return nil
}

// Copied scan.go
// Scanner provides a convenient interface for reading data such as
// a file of newline-delimited lines of text. Successive calls to
// the Scan method will step through the 'tokens' of a file, skipping
// the bytes between the tokens. The specification of a token is
// defined by a split function of type SplitFunc; the default split
// function breaks the input into lines with line termination stripped. Split
// functions are defined in this package for scanning a file into
// lines, bytes, UTF-8-encoded runes, and space-delimited words. The
// client may instead provide a custom split function.
//
// Scanning stops unrecoverably at EOF, the first I/O error, or a token too
// large to fit in the buffer. When a scan stops, the reader may have
// advanced arbitrarily far past the last token. Programs that need more
// control over error handling or large tokens, or must run sequential scans
// on a reader, should use bufio.Reader instead.
//
type Scanner struct {
        r            io.Reader // The reader provided by the client.
        split        SplitFunc // The function to split the tokens.
        maxTokenSize int       // Maximum size of a token; modified by tests.
        token        []byte    // Last token returned by split.
        buf          []byte    // Buffer used as argument to split.
        start        int       // First non-processed byte in buf.
        end          int       // End of data in buf.
        err          error     // Sticky error.
}

// SplitFunc is the signature of the split function used to tokenize the
// input. The arguments are an initial substring of the remaining unprocessed
// data and a flag, atEOF, that reports whether the Reader has no more data
// to give. The return values are the number of bytes to advance the input
// and the next token to return to the user, plus an error, if any. If the
// data does not yet hold a complete token, for instance if it has no newline
// while scanning lines, SplitFunc can return (0, nil, nil) to signal the
// Scanner to read more data into the slice and try again with a longer slice
// starting at the same point in the input.
//
// If the returned error is non-nil, scanning stops and the error
// is returned to the client.
//
// The function is never called with an empty data slice unless atEOF
// is true. If atEOF is true, however, data may be non-empty and,
// as always, holds unprocessed text.
type SplitFunc func(data []byte, atEOF bool) (advance int, token []byte, err error)

// Errors returned by Scanner.
var (
        ErrTooLong         = errors.New("bufio.Scanner: token too long")
        ErrNegativeAdvance = errors.New("bufio.Scanner: SplitFunc returns negative advance count")
        ErrAdvanceTooFar   = errors.New("bufio.Scanner: SplitFunc returns advance count beyond input")
)

const (
        // Maximum size used to buffer a token. The actual maximum token size
        // may be smaller as the buffer may need to include, for instance, a newline.
        MaxScanTokenSize = 1 << 30
)

// NewScanner returns a new Scanner to read from r.
// The split function defaults to ScanLines.
func NewScanner(r io.Reader) *Scanner {
        return &Scanner{
                r:            r,
                split:        ScanLines,
                maxTokenSize: MaxScanTokenSize,
                buf:          make([]byte, 4096), // Plausible starting size; needn't be large.
        }
}

// Err returns the first non-EOF error that was encountered by the Scanner.
func (s *Scanner) Err() error {
        if s.err == io.EOF {
                return nil
        }
        return s.err
}

// Bytes returns the most recent token generated by a call to Scan.
// The underlying array may point to data that will be overwritten
// by a subsequent call to Scan. It does no allocation.
func (s *Scanner) Bytes() []byte {
        return s.token
}

// Text returns the most recent token generated by a call to Scan
// as a newly allocated string holding its bytes.
func (s *Scanner) Text() string {
        return string(s.token)
}

// Scan advances the Scanner to the next token, which will then be
// available through the Bytes or Text method. It returns false when the
// scan stops, either by reaching the end of the input or an error.
// After Scan returns false, the Err method will return any error that
// occurred during scanning, except that if it was io.EOF, Err
// will return nil.
func (s *Scanner) Scan() bool {
        // Loop until we have a token.
        for {
                // See if we can get a token with what we already have.
                if s.end > s.start {
                        advance, token, err := s.split(s.buf[s.start:s.end], s.err != nil)
                        if err != nil {
                                s.setErr(err)
                                return false
                        }
                        if !s.advance(advance) {
                                return false
                        }
                        s.token = token
                        if token != nil {
                                return true
                        }
                }
                // We cannot generate a token with what we are holding.
                // If we've already hit EOF or an I/O error, we are done.
                if s.err != nil {
                        // Shut it down.
                        s.start = 0
                        s.end = 0
                        return false
                }
                // Must read more data.
                // First, shift data to beginning of buffer if there's lots of empty space
                // or space is neded.
                if s.start > 0 && (s.end == len(s.buf) || s.start > len(s.buf)/2) {
                        copy(s.buf, s.buf[s.start:s.end])
                        s.end -= s.start
                        s.start = 0
                }
                // Is the buffer full? If so, resize.
                if s.end == len(s.buf) {
                        if len(s.buf) >= s.maxTokenSize {
                                s.setErr(ErrTooLong)
                                return false
                        }
                        newSize := len(s.buf) * 2
                        if newSize > s.maxTokenSize {
                                newSize = s.maxTokenSize
                        }
                        newBuf := make([]byte, newSize)
                        copy(newBuf, s.buf[s.start:s.end])
                        s.buf = newBuf
                        s.end -= s.start
                        s.start = 0
                        continue
                }
                // Finally we can read some input. Make sure we don't get stuck with
                // a misbehaving Reader. Officially we don't need to do this, but let's
                // be extra careful: Scanner is for safe, simple jobs.
                for loop := 0; ; {
                        n, err := s.r.Read(s.buf[s.end:len(s.buf)])
                        s.end += n
                        if err != nil {
                                s.setErr(err)
                                break
                        }
                        if n > 0 {
                                break
                        }
                        loop++
                        if loop > 100 {
                                s.setErr(io.ErrNoProgress)
                                break
                        }
                }
        }
}

// advance consumes n bytes of the buffer. It reports whether the advance was legal.
func (s *Scanner) advance(n int) bool {
        if n < 0 {
                s.setErr(ErrNegativeAdvance)
                return false
        }
        if n > s.end-s.start {
                s.setErr(ErrAdvanceTooFar)
                return false
        }
        s.start += n
        return true
}

// setErr records the first error encountered.
func (s *Scanner) setErr(err error) {
        if s.err == nil || s.err == io.EOF {
                s.err = err
        }
}

// Split sets the split function for the Scanner. If called, it must be
// called before Scan. The default split function is ScanLines.
func (s *Scanner) Split(split SplitFunc) {
        s.split = split
}

// Split functions

// ScanBytes is a split function for a Scanner that returns each byte as a token.
func ScanBytes(data []byte, atEOF bool) (advance int, token []byte, err error) {
        if atEOF && len(data) == 0 {
                return 0, nil, nil
        }
        return 1, data[0:1], nil
}

var errorRune = []byte(string(utf8.RuneError))

// ScanRunes is a split function for a Scanner that returns each
// UTF-8-encoded rune as a token. The sequence of runes returned is
// equivalent to that from a range loop over the input as a string, which
// means that erroneous UTF-8 encodings translate to U+FFFD = "\xef\xbf\xbd".
// Because of the Scan interface, this makes it impossible for the client to
// distinguish correctly encoded replacement runes from encoding errors.
func ScanRunes(data []byte, atEOF bool) (advance int, token []byte, err error) {
        if atEOF && len(data) == 0 {
                return 0, nil, nil
        }

        // Fast path 1: ASCII.
        if data[0] < utf8.RuneSelf {
                return 1, data[0:1], nil
        }

        // Fast path 2: Correct UTF-8 decode without error.
        _, width := utf8.DecodeRune(data)
        if width > 1 {
                // It's a valid encoding. Width cannot be one for a correctly encoded
                // non-ASCII rune.
                return width, data[0:width], nil
        }

        // We know it's an error: we have width==1 and implicitly r==utf8.RuneError.
        // Is the error because there wasn't a full rune to be decoded?
        // FullRune distinguishes correctly between erroneous and incomplete encodings.
        if !atEOF && !utf8.FullRune(data) {
                // Incomplete; get more bytes.
                return 0, nil, nil
        }

        // We have a real UTF-8 encoding error. Return a properly encoded error rune
        // but advance only one byte. This matches the behavior of a range loop over
        // an incorrectly encoded string.
        return 1, errorRune, nil
}

// dropCR drops a terminal \r from the data.
func dropCR(data []byte) []byte {
        if len(data) > 0 && data[len(data)-1] == '\r' {
                return data[0 : len(data)-1]
        }
        return data
}

// ScanLines is a split function for a Scanner that returns each line of
// text, stripped of any trailing end-of-line marker. The returned line may
// be empty. The end-of-line marker is one optional carriage return followed
// by one mandatory newline. In regular expression notation, it is `\r?\n`.
// The last non-empty line of input will be returned even if it has no
// newline.
func ScanLines(data []byte, atEOF bool) (advance int, token []byte, err error) {
        if atEOF && len(data) == 0 {
                return 0, nil, nil
        }
        if i := bytes.IndexByte(data, '\n'); i >= 0 {
                // We have a full newline-terminated line.
                return i + 1, dropCR(data[0:i]), nil
        }
        // If we're at EOF, we have a final, non-terminated line. Return it.
        if atEOF {
                return len(data), dropCR(data), nil
        }
        // Request more data.
        return 0, nil, nil
}

// isSpace reports whether the character is a Unicode white space character.
// We avoid dependency on the unicode package, but check validity of the implementation
// in the tests.
func isSpace(r rune) bool {
        if r <= '\u00FF' {
                // Obvious ASCII ones: \t through \r plus space. Plus two Latin-1 oddballs.
                switch r {
                case ' ', '\t', '\n', '\v', '\f', '\r':
                        return true
                case '\u0085', '\u00A0':
                        return true
                }
                return false
        }
        // High-valued ones.
        if '\u2000' <= r && r <= '\u200a' {
                return true
        }
        switch r {
        case '\u1680', '\u180e', '\u2028', '\u2029', '\u202f', '\u205f', '\u3000':
                return true
        }
        return false
}

// ScanWords is a split function for a Scanner that returns each
// space-separated word of text, with surrounding spaces deleted. It will
// never return an empty string. The definition of space is set by
// unicode.IsSpace.
func ScanWords(data []byte, atEOF bool) (advance int, token []byte, err error) {
        // Skip leading spaces.
        start := 0
        for width := 0; start < len(data); start += width {
                var r rune
                r, width = utf8.DecodeRune(data[start:])
                if !isSpace(r) {
                        break
                }
        }
        if atEOF && len(data) == 0 {
                return 0, nil, nil
        }
        // Scan until space, marking end of word.
        for width, i := 0, start; i < len(data); i += width {
                var r rune
                r, width = utf8.DecodeRune(data[i:])
                if isSpace(r) {
                        return i + width, data[start:i], nil
                }
        }
        // If we're at EOF, we have a final, non-empty, non-terminated word. Return it.
        if atEOF && len(data) > start {
                return len(data), data[start:], nil
        }
        // Request more data.
        return 0, nil, nil
}

package main

import (
	"bufio"
	"bytes"
	"errors"
	"flag"
	"fmt"
	"io"
	"log"
	"os"
	"strconv"
	"time"
	"unicode/utf8"
)

// ******************************** CODE STARTS ********************************

var (
)

func lcp(s1, s2 []byte) [][]int {
	n1 := len(s1)
	n2 := len(s2)
	L := make([][]int, n1)
	for i := 0; i < n1; i++ {
		L[i] = make([]int, n2)
	}

	for i1 := n1 - 1; i1 >= 0; i1-- {
		for i2 := n2 - 1; i2 >= 0; i2-- {
			if s1[i1] == s2[i2] {
				L[i1][i2] = 1
				if i1 + 1 < n1 && i2 + 1 < n2 {
					L[i1][i2] += L[i1 + 1][i2 + 1]
				}
			} else {
				L[i1][i2] = 0
			}
		}
	}

	return L
}

func unique(L [][]int) []int {
	res := make([]int, len(L))
	for j := 0; j < len(L); j++ {
		res[j] = -1
		value := -1
		for i := 0; i < len(L[j]); i++ {
			if j != i {
				value = maxInt(value, L[j][i])
			}
		}
		if value != -1 && j + value < len(L) {
			res[j] = value + 1
		}
	}
	return res
}

func solve() {
	s1 := []byte(readString())
	s2 := []byte(readString())

	L1 := unique(lcp(s1, s1))
//	logln(string(s1))
//	logln(L1)
	L2 := unique(lcp(s2, s2))
//	logln(string(s2))
//	logln(L2)

	lcp12 := lcp(s1, s2)

	ans := -1
	for j := 0; j < len(s1); j++ {
		for i := 0; i < len(s2); i++ {
			if L1[j] != -1 && L2[i] != -1 {
				l := maxInt(L1[j], L2[i])
				if l != -1 && l <= lcp12[j][i] {
					if ans == -1 || ans > l {
//						logln(j)
//						logln(i)
//						logln(l)
//						logln("lol")
						ans = l
					}
				}
			}
		}
	}

	printInt(ans)
	printLine()

}

// ********************************* CODE ENDS *********************************

// IO.

var (
	scanner *Scanner
	writer  *bufio.Writer
	logger  *log.Logger
)

func main() {
	local := flag.Bool("local", false, "Equals true, if run is local.")
	flag.Parse()

	var (
		input  *os.File
		output *os.File
	)

	if *local {
		startTime := time.Now()
		defer func() {
			println(fmt.Sprintf("Time: %.5fs", time.Since(startTime).Seconds()))
		}()
		input, _ = os.Open("/home/outside/coding/workspace/go/io/input.txt")
		output, _ = os.Create("/home/outside/coding/workspace/go/io/output.txt")
		logger = log.New(output, "log: ", 0)
	} else {
		input = os.Stdin
		output = os.Stdout
		// input, _ = os.Open("")
		// output, _ = os.Create("")
	}
	defer input.Close()
	defer output.Close()

	scanner = NewScanner(input)
	scanner.Split(bufio.ScanWords)

	writer = bufio.NewWriter(output)
	defer writer.Flush()

	solve()
}

// Read.

func readString() string {
	scanner.Scan()
	ans := scanner.Text()
	return ans
}

func readLine() string {
	scanner.Split(bufio.ScanLines)
	defer scanner.Split(bufio.ScanWords)
	return readString()
}

func readInt() int {
	ans, _ := strconv.ParseInt(readString(), 10, 0)
	return int(ans)
}

func readInt64() int64 {
	ans, _ := strconv.ParseInt(readString(), 10, 64)
	return ans
}

func readFloat64() float64 {
	ans, _ := strconv.ParseFloat(readString(), 64)
	return ans
}

// Write.

func printString(value string) {
	writer.WriteString(value)
}

func printLine() {
	printString("\n")
}

func printInt(value int) {
	printString(strconv.FormatInt(int64(value), 10))
}

func printInt64(value int64) {
	printString(strconv.FormatInt(value, 10))
}

func printFLoat64(value float64) {
	printString(strconv.FormatFloat(value, 'f', 20, 64))
}

// Log.

func logln(value ...interface{}) {
	writer.Flush()
	logger.Println(value...)
}
func logf(format string, value ...interface{}) {
	writer.Flush()
	logger.Printf(format, value...)
}

// Tuple

type Tuple struct {
	a, b int
}

func (p Tuple) Equals(key Key) bool {
	return p.a == key.(Tuple).a
}

func (p Tuple) Less(key Key) bool {
	return p.a < key.(Tuple).a
}

type TupleSlice []Tuple

func (p TupleSlice) Len() int {
	return len(p)
}

func (p TupleSlice) Less(j, i int) bool {
	return p[j].a < p[i].a
}

func (p TupleSlice) Swap(j, i int) {
	p[j], p[i] = p[i], p[j]
}

// Min, max, abs.

func maxInt(a, b int) int {
	if a > b {
		return a
	} else {
		return b
	}
}

func minInt(a, b int) int {
	if a < b {
		return a
	} else {
		return b
	}
}

func absInt(a int) int {
	if a > 0 {
		return a
	} else {
		return -a
	}
}

func maxInt64(a, b int64) int64 {
	if a > b {
		return a
	} else {
		return b
	}
}

func minInt64(a, b int64) int64 {
	if a < b {
		return a
	} else {
		return b
	}
}

func absInt64(a int64) int64 {
	if a > 0 {
		return a
	} else {
		return -a
	}
}

func maxFloat64(a, b float64) float64 {
	if a > b {
		return a
	} else {
		return b
	}
}

func minFloat64(a, b float64) float64 {
	if a < b {
		return a
	} else {
		return b
	}
}

func absFloat64(a float64) float64 {
	if a > 0 {
		return a
	} else {
		return -a
	}
}

// Set Key interface implementations.

type Int int

func (p Int) Equals(key Key) bool {
	return int(p) == int(key.(Int))
}

func (p Int) Less(key Key) bool {
	return int(p) < int(key.(Int))
}

// Set.

type Key interface {
	Equals(key Key) bool
	Less(key Key) bool
}

type node struct {
	key   Key
	left  *node
	right *node
}

func newNode(key Key) *node {
	return &node{key, nil, nil}
}

type SplayTree struct {
	root *node
	tmp  *node
	len  int
}

func NewSplayTree() *SplayTree {
	return &SplayTree{nil, newNode(nil), 0}
}

func rotateLeft(x, p *node) {
	p.right = x.left
	x.left = p
}

func rotateRight(x, p *node) {
	p.left = x.right
	x.right = p
}

func (p *SplayTree) splay(x *node, key Key) *node {
	if x == nil {
		return nil
	}

	left := p.tmp
	right := p.tmp

	for {
		if key.Less(x.key) {
			y := x.left
			if y == nil {
				break
			}
			if key.Less(y.key) { // zig-zig
				rotateRight(y, x)
				x = y
				if x.left == nil {
					break
				}
			}
			// link right
			right.left = x
			right = x
			// move left
			x = x.left
		} else if x.key.Less(key) {
			y := x.right
			if y == nil {
				break
			}
			if y.key.Less(key) { // zig-zig
				rotateLeft(y, x)
				x = y
				if x.right == nil {
					break
				}
			}
			// link left
			left.right = x
			left = x
			// move right
			x = x.right
		} else {
			break
		}
	}

	left.right = x.left
	right.left = x.right
	x.left = p.tmp.right
	x.right = p.tmp.left

	return x
}

// left <= key < right
func (p *SplayTree) split(key Key) (left, right *node) {
	p.root = p.splay(p.root, key)
	if p.root.key.Equals(key) || p.root.key.Less(key) {
		right := p.root.right
		p.root.right = nil
		return p.root, right
	} else {
		left := p.root.left
		p.root.left = nil
		return left, p.root
	}
}

// keys from left tree must be less then keys from right tree
func (p *SplayTree) join(left, right *node) *node {
	if left == nil {
		return right
	} else if right == nil {
		return left
	}
	left = p.splay(left, right.key)
	left.right = right
	return left
}

type Set interface {
	Len() int
	Insert(key Key) error
	Find(key Key) bool
	Remove(key Key) error
}

func NewSet() Set {
	return Set(NewSplayTree())
}

func (p *SplayTree) Len() int {
	return p.len
}

func (p *SplayTree) Insert(key Key) error {
	if p.root == nil {
		p.root = newNode(key)
		p.len++
	} else {
		p.root = p.splay(p.root, key)
		if p.root.key.Equals(key) {
			return errors.New("Such key already exists")
		} else {
			left, right := p.split(key)
			p.root = newNode(key)
			p.root.left = left
			p.root.right = right
			p.len++
		}
	}
	return nil
}

func (p *SplayTree) Find(key Key) bool {
	if p.root == nil {
		return false
	}
	p.root = p.splay(p.root, key)
	return p.root.key.Equals(key)
}

func (p *SplayTree) Remove(key Key) error {
	p.root = p.splay(p.root, key)
	if p.root == nil || !p.root.key.Equals(key) {
		return errors.New("Such key doesn't exist")
	}
	p.root = p.join(p.split(key))
	return nil
}

// Copied scan.go
// Scanner provides a convenient interface for reading data such as
// a file of newline-delimited lines of text. Successive calls to
// the Scan method will step through the 'tokens' of a file, skipping
// the bytes between the tokens. The specification of a token is
// defined by a split function of type SplitFunc; the default split
// function breaks the input into lines with line termination stripped. Split
// functions are defined in this package for scanning a file into
// lines, bytes, UTF-8-encoded runes, and space-delimited words. The
// client may instead provide a custom split function.
//
// Scanning stops unrecoverably at EOF, the first I/O error, or a token too
// large to fit in the buffer. When a scan stops, the reader may have
// advanced arbitrarily far past the last token. Programs that need more
// control over error handling or large tokens, or must run sequential scans
// on a reader, should use bufio.Reader instead.
//
type Scanner struct {
        r            io.Reader // The reader provided by the client.
        split        SplitFunc // The function to split the tokens.
        maxTokenSize int       // Maximum size of a token; modified by tests.
        token        []byte    // Last token returned by split.
        buf          []byte    // Buffer used as argument to split.
        start        int       // First non-processed byte in buf.
        end          int       // End of data in buf.
        err          error     // Sticky error.
}

// SplitFunc is the signature of the split function used to tokenize the
// input. The arguments are an initial substring of the remaining unprocessed
// data and a flag, atEOF, that reports whether the Reader has no more data
// to give. The return values are the number of bytes to advance the input
// and the next token to return to the user, plus an error, if any. If the
// data does not yet hold a complete token, for instance if it has no newline
// while scanning lines, SplitFunc can return (0, nil, nil) to signal the
// Scanner to read more data into the slice and try again with a longer slice
// starting at the same point in the input.
//
// If the returned error is non-nil, scanning stops and the error
// is returned to the client.
//
// The function is never called with an empty data slice unless atEOF
// is true. If atEOF is true, however, data may be non-empty and,
// as always, holds unprocessed text.
type SplitFunc func(data []byte, atEOF bool) (advance int, token []byte, err error)

// Errors returned by Scanner.
var (
        ErrTooLong         = errors.New("bufio.Scanner: token too long")
        ErrNegativeAdvance = errors.New("bufio.Scanner: SplitFunc returns negative advance count")
        ErrAdvanceTooFar   = errors.New("bufio.Scanner: SplitFunc returns advance count beyond input")
)

const (
        // Maximum size used to buffer a token. The actual maximum token size
        // may be smaller as the buffer may need to include, for instance, a newline.
        MaxScanTokenSize = 1 << 30
)

// NewScanner returns a new Scanner to read from r.
// The split function defaults to ScanLines.
func NewScanner(r io.Reader) *Scanner {
        return &Scanner{
                r:            r,
                split:        ScanLines,
                maxTokenSize: MaxScanTokenSize,
                buf:          make([]byte, 4096), // Plausible starting size; needn't be large.
        }
}

// Err returns the first non-EOF error that was encountered by the Scanner.
func (s *Scanner) Err() error {
        if s.err == io.EOF {
                return nil
        }
        return s.err
}

// Bytes returns the most recent token generated by a call to Scan.
// The underlying array may point to data that will be overwritten
// by a subsequent call to Scan. It does no allocation.
func (s *Scanner) Bytes() []byte {
        return s.token
}

// Text returns the most recent token generated by a call to Scan
// as a newly allocated string holding its bytes.
func (s *Scanner) Text() string {
        return string(s.token)
}

// Scan advances the Scanner to the next token, which will then be
// available through the Bytes or Text method. It returns false when the
// scan stops, either by reaching the end of the input or an error.
// After Scan returns false, the Err method will return any error that
// occurred during scanning, except that if it was io.EOF, Err
// will return nil.
func (s *Scanner) Scan() bool {
        // Loop until we have a token.
        for {
                // See if we can get a token with what we already have.
                if s.end > s.start {
                        advance, token, err := s.split(s.buf[s.start:s.end], s.err != nil)
                        if err != nil {
                                s.setErr(err)
                                return false
                        }
                        if !s.advance(advance) {
                                return false
                        }
                        s.token = token
                        if token != nil {
                                return true
                        }
                }
                // We cannot generate a token with what we are holding.
                // If we've already hit EOF or an I/O error, we are done.
                if s.err != nil {
                        // Shut it down.
                        s.start = 0
                        s.end = 0
                        return false
                }
                // Must read more data.
                // First, shift data to beginning of buffer if there's lots of empty space
                // or space is neded.
                if s.start > 0 && (s.end == len(s.buf) || s.start > len(s.buf)/2) {
                        copy(s.buf, s.buf[s.start:s.end])
                        s.end -= s.start
                        s.start = 0
                }
                // Is the buffer full? If so, resize.
                if s.end == len(s.buf) {
                        if len(s.buf) >= s.maxTokenSize {
                                s.setErr(ErrTooLong)
                                return false
                        }
                        newSize := len(s.buf) * 2
                        if newSize > s.maxTokenSize {
                                newSize = s.maxTokenSize
                        }
                        newBuf := make([]byte, newSize)
                        copy(newBuf, s.buf[s.start:s.end])
                        s.buf = newBuf
                        s.end -= s.start
                        s.start = 0
                        continue
                }
                // Finally we can read some input. Make sure we don't get stuck with
                // a misbehaving Reader. Officially we don't need to do this, but let's
                // be extra careful: Scanner is for safe, simple jobs.
                for loop := 0; ; {
                        n, err := s.r.Read(s.buf[s.end:len(s.buf)])
                        s.end += n
                        if err != nil {
                                s.setErr(err)
                                break
                        }
                        if n > 0 {
                                break
                        }
                        loop++
                        if loop > 100 {
                                s.setErr(io.ErrNoProgress)
                                break
                        }
                }
        }
}

// advance consumes n bytes of the buffer. It reports whether the advance was legal.
func (s *Scanner) advance(n int) bool {
        if n < 0 {
                s.setErr(ErrNegativeAdvance)
                return false
        }
        if n > s.end-s.start {
                s.setErr(ErrAdvanceTooFar)
                return false
        }
        s.start += n
        return true
}

// setErr records the first error encountered.
func (s *Scanner) setErr(err error) {
        if s.err == nil || s.err == io.EOF {
                s.err = err
        }
}

// Split sets the split function for the Scanner. If called, it must be
// called before Scan. The default split function is ScanLines.
func (s *Scanner) Split(split SplitFunc) {
        s.split = split
}

// Split functions

// ScanBytes is a split function for a Scanner that returns each byte as a token.
func ScanBytes(data []byte, atEOF bool) (advance int, token []byte, err error) {
        if atEOF && len(data) == 0 {
                return 0, nil, nil
        }
        return 1, data[0:1], nil
}

var errorRune = []byte(string(utf8.RuneError))

// ScanRunes is a split function for a Scanner that returns each
// UTF-8-encoded rune as a token. The sequence of runes returned is
// equivalent to that from a range loop over the input as a string, which
// means that erroneous UTF-8 encodings translate to U+FFFD = "\xef\xbf\xbd".
// Because of the Scan interface, this makes it impossible for the client to
// distinguish correctly encoded replacement runes from encoding errors.
func ScanRunes(data []byte, atEOF bool) (advance int, token []byte, err error) {
        if atEOF && len(data) == 0 {
                return 0, nil, nil
        }

        // Fast path 1: ASCII.
        if data[0] < utf8.RuneSelf {
                return 1, data[0:1], nil
        }

        // Fast path 2: Correct UTF-8 decode without error.
        _, width := utf8.DecodeRune(data)
        if width > 1 {
                // It's a valid encoding. Width cannot be one for a correctly encoded
                // non-ASCII rune.
                return width, data[0:width], nil
        }

        // We know it's an error: we have width==1 and implicitly r==utf8.RuneError.
        // Is the error because there wasn't a full rune to be decoded?
        // FullRune distinguishes correctly between erroneous and incomplete encodings.
        if !atEOF && !utf8.FullRune(data) {
                // Incomplete; get more bytes.
                return 0, nil, nil
        }

        // We have a real UTF-8 encoding error. Return a properly encoded error rune
        // but advance only one byte. This matches the behavior of a range loop over
        // an incorrectly encoded string.
        return 1, errorRune, nil
}

// dropCR drops a terminal \r from the data.
func dropCR(data []byte) []byte {
        if len(data) > 0 && data[len(data)-1] == '\r' {
                return data[0 : len(data)-1]
        }
        return data
}

// ScanLines is a split function for a Scanner that returns each line of
// text, stripped of any trailing end-of-line marker. The returned line may
// be empty. The end-of-line marker is one optional carriage return followed
// by one mandatory newline. In regular expression notation, it is `\r?\n`.
// The last non-empty line of input will be returned even if it has no
// newline.
func ScanLines(data []byte, atEOF bool) (advance int, token []byte, err error) {
        if atEOF && len(data) == 0 {
                return 0, nil, nil
        }
        if i := bytes.IndexByte(data, '\n'); i >= 0 {
                // We have a full newline-terminated line.
                return i + 1, dropCR(data[0:i]), nil
        }
        // If we're at EOF, we have a final, non-terminated line. Return it.
        if atEOF {
                return len(data), dropCR(data), nil
        }
        // Request more data.
        return 0, nil, nil
}

// isSpace reports whether the character is a Unicode white space character.
// We avoid dependency on the unicode package, but check validity of the implementation
// in the tests.
func isSpace(r rune) bool {
        if r <= '\u00FF' {
                // Obvious ASCII ones: \t through \r plus space. Plus two Latin-1 oddballs.
                switch r {
                case ' ', '\t', '\n', '\v', '\f', '\r':
                        return true
                case '\u0085', '\u00A0':
                        return true
                }
                return false
        }
        // High-valued ones.
        if '\u2000' <= r && r <= '\u200a' {
                return true
        }
        switch r {
        case '\u1680', '\u180e', '\u2028', '\u2029', '\u202f', '\u205f', '\u3000':
                return true
        }
        return false
}

// ScanWords is a split function for a Scanner that returns each
// space-separated word of text, with surrounding spaces deleted. It will
// never return an empty string. The definition of space is set by
// unicode.IsSpace.
func ScanWords(data []byte, atEOF bool) (advance int, token []byte, err error) {
        // Skip leading spaces.
        start := 0
        for width := 0; start < len(data); start += width {
                var r rune
                r, width = utf8.DecodeRune(data[start:])
                if !isSpace(r) {
                        break
                }
        }
        if atEOF && len(data) == 0 {
                return 0, nil, nil
        }
        // Scan until space, marking end of word.
        for width, i := 0, start; i < len(data); i += width {
                var r rune
                r, width = utf8.DecodeRune(data[i:])
                if isSpace(r) {
                        return i + width, data[start:i], nil
                }
        }
        // If we're at EOF, we have a final, non-empty, non-terminated word. Return it.
        if atEOF && len(data) > start {
                return len(data), data[start:], nil
        }
        // Request more data.
        return 0, nil, nil
}

package main

import (
	"bufio"
	"bytes"
	"errors"
	"flag"
	"fmt"
	"io"
	"log"
	"os"
	"strconv"
	"time"
	"unicode/utf8"
)

// ******************************** CODE STARTS ********************************

var (
)

func initialize(n int, multiplier uint16) []uint16 {
	power := make([]uint16, n)
	power[0] = 1
	for i := 1; i < n; i++ {
		power[i] = power[i - 1] * multiplier
	}
	return power
}

func hash(s []byte, power []uint16) []uint16 {
	n := len(s)
	h := make([]uint16, n)
	for i := 0; i < n; i++ {
		h[i] = (uint16(s[i]) + 1) * power[i]
		if i > 0 {
			h[i] += h[i - 1]
		}
	}
	return h
}

func getMap(h, power []uint16) map[uint16]int {
	M := make(map[uint16]int)
	for j := 0; j < len(h); j++ {
		for i := j; i < len(h); i++ {
			value := h[i]
			if j > 0 {
				value -= h[j - 1]
			}
			value *= power[len(power) - 1 - j]
			if M[value] != 0 {
				M[value] = -1
			} else {
				M[value] = i - j + 1
			}
		}
	}
	return M
}

func solve() {
	s1 := []byte(readString())
	s2 := []byte(readString())
	N := maxInt(len(s1), len(s2))
	power := initialize(N + 10, 29)
	h1 := hash(s1, power)
	h2 := hash(s2, power)
	M1 := getMap(h1, power)
	M2 := getMap(h2, power)
	ans := -1
	for k, v := range M1 {
		if v > 0 && M2[k] > 0 {
			if ans == -1 || ans > v {
				ans = v
			}
		}
	}
	printInt(ans)
	printLine()

}

// ********************************* CODE ENDS *********************************

// IO.

var (
	scanner *Scanner
	writer  *bufio.Writer
	logger  *log.Logger
)

func main() {
	local := flag.Bool("local", false, "Equals true, if run is local.")
	flag.Parse()

	var (
		input  *os.File
		output *os.File
	)

	if *local {
		startTime := time.Now()
		defer func() {
			println(fmt.Sprintf("Time: %.5fs", time.Since(startTime).Seconds()))
		}()
		input, _ = os.Open("/home/outside/coding/workspace/go/io/input.txt")
		output, _ = os.Create("/home/outside/coding/workspace/go/io/output.txt")
		logger = log.New(output, "log: ", 0)
	} else {
		input = os.Stdin
		output = os.Stdout
		// input, _ = os.Open("")
		// output, _ = os.Create("")
	}
	defer input.Close()
	defer output.Close()

	scanner = NewScanner(input)
	scanner.Split(bufio.ScanWords)

	writer = bufio.NewWriter(output)
	defer writer.Flush()

	solve()
}

// Read.

func readString() string {
	scanner.Scan()
	ans := scanner.Text()
	return ans
}

func readLine() string {
	scanner.Split(bufio.ScanLines)
	defer scanner.Split(bufio.ScanWords)
	return readString()
}

func readInt() int {
	ans, _ := strconv.ParseInt(readString(), 10, 0)
	return int(ans)
}

func readInt64() int64 {
	ans, _ := strconv.ParseInt(readString(), 10, 64)
	return ans
}

func readFloat64() float64 {
	ans, _ := strconv.ParseFloat(readString(), 64)
	return ans
}

// Write.

func printString(value string) {
	writer.WriteString(value)
}

func printLine() {
	printString("\n")
}

func printInt(value int) {
	printString(strconv.FormatInt(int64(value), 10))
}

func printInt64(value int64) {
	printString(strconv.FormatInt(value, 10))
}

func printFLoat64(value float64) {
	printString(strconv.FormatFloat(value, 'f', 20, 64))
}

// Log.

func logln(value ...interface{}) {
	writer.Flush()
	logger.Println(value...)
}
func logf(format string, value ...interface{}) {
	writer.Flush()
	logger.Printf(format, value...)
}

// Tuple

type Tuple struct {
	a, b int
}

func (p Tuple) Equals(key Key) bool {
	return p.a == key.(Tuple).a
}

func (p Tuple) Less(key Key) bool {
	return p.a < key.(Tuple).a
}

type TupleSlice []Tuple

func (p TupleSlice) Len() int {
	return len(p)
}

func (p TupleSlice) Less(j, i int) bool {
	return p[j].a < p[i].a
}

func (p TupleSlice) Swap(j, i int) {
	p[j], p[i] = p[i], p[j]
}

// Min, max, abs.

func maxInt(a, b int) int {
	if a > b {
		return a
	} else {
		return b
	}
}

func minInt(a, b int) int {
	if a < b {
		return a
	} else {
		return b
	}
}

func absInt(a int) int {
	if a > 0 {
		return a
	} else {
		return -a
	}
}

func maxInt64(a, b int64) int64 {
	if a > b {
		return a
	} else {
		return b
	}
}

func minInt64(a, b int64) int64 {
	if a < b {
		return a
	} else {
		return b
	}
}

func absInt64(a int64) int64 {
	if a > 0 {
		return a
	} else {
		return -a
	}
}

func maxFloat64(a, b float64) float64 {
	if a > b {
		return a
	} else {
		return b
	}
}

func minFloat64(a, b float64) float64 {
	if a < b {
		return a
	} else {
		return b
	}
}

func absFloat64(a float64) float64 {
	if a > 0 {
		return a
	} else {
		return -a
	}
}

// Set Key interface implementations.

type Int int

func (p Int) Equals(key Key) bool {
	return int(p) == int(key.(Int))
}

func (p Int) Less(key Key) bool {
	return int(p) < int(key.(Int))
}

// Set.

type Key interface {
	Equals(key Key) bool
	Less(key Key) bool
}

type node struct {
	key   Key
	left  *node
	right *node
}

func newNode(key Key) *node {
	return &node{key, nil, nil}
}

type SplayTree struct {
	root *node
	tmp  *node
	len  int
}

func NewSplayTree() *SplayTree {
	return &SplayTree{nil, newNode(nil), 0}
}

func rotateLeft(x, p *node) {
	p.right = x.left
	x.left = p
}

func rotateRight(x, p *node) {
	p.left = x.right
	x.right = p
}

func (p *SplayTree) splay(x *node, key Key) *node {
	if x == nil {
		return nil
	}

	left := p.tmp
	right := p.tmp

	for {
		if key.Less(x.key) {
			y := x.left
			if y == nil {
				break
			}
			if key.Less(y.key) { // zig-zig
				rotateRight(y, x)
				x = y
				if x.left == nil {
					break
				}
			}
			// link right
			right.left = x
			right = x
			// move left
			x = x.left
		} else if x.key.Less(key) {
			y := x.right
			if y == nil {
				break
			}
			if y.key.Less(key) { // zig-zig
				rotateLeft(y, x)
				x = y
				if x.right == nil {
					break
				}
			}
			// link left
			left.right = x
			left = x
			// move right
			x = x.right
		} else {
			break
		}
	}

	left.right = x.left
	right.left = x.right
	x.left = p.tmp.right
	x.right = p.tmp.left

	return x
}

// left <= key < right
func (p *SplayTree) split(key Key) (left, right *node) {
	p.root = p.splay(p.root, key)
	if p.root.key.Equals(key) || p.root.key.Less(key) {
		right := p.root.right
		p.root.right = nil
		return p.root, right
	} else {
		left := p.root.left
		p.root.left = nil
		return left, p.root
	}
}

// keys from left tree must be less then keys from right tree
func (p *SplayTree) join(left, right *node) *node {
	if left == nil {
		return right
	} else if right == nil {
		return left
	}
	left = p.splay(left, right.key)
	left.right = right
	return left
}

type Set interface {
	Len() int
	Insert(key Key) error
	Find(key Key) bool
	Remove(key Key) error
}

func NewSet() Set {
	return Set(NewSplayTree())
}

func (p *SplayTree) Len() int {
	return p.len
}

func (p *SplayTree) Insert(key Key) error {
	if p.root == nil {
		p.root = newNode(key)
		p.len++
	} else {
		p.root = p.splay(p.root, key)
		if p.root.key.Equals(key) {
			return errors.New("Such key already exists")
		} else {
			left, right := p.split(key)
			p.root = newNode(key)
			p.root.left = left
			p.root.right = right
			p.len++
		}
	}
	return nil
}

func (p *SplayTree) Find(key Key) bool {
	if p.root == nil {
		return false
	}
	p.root = p.splay(p.root, key)
	return p.root.key.Equals(key)
}

func (p *SplayTree) Remove(key Key) error {
	p.root = p.splay(p.root, key)
	if p.root == nil || !p.root.key.Equals(key) {
		return errors.New("Such key doesn't exist")
	}
	p.root = p.join(p.split(key))
	return nil
}

// Copied scan.go
// Scanner provides a convenient interface for reading data such as
// a file of newline-delimited lines of text. Successive calls to
// the Scan method will step through the 'tokens' of a file, skipping
// the bytes between the tokens. The specification of a token is
// defined by a split function of type SplitFunc; the default split
// function breaks the input into lines with line termination stripped. Split
// functions are defined in this package for scanning a file into
// lines, bytes, UTF-8-encoded runes, and space-delimited words. The
// client may instead provide a custom split function.
//
// Scanning stops unrecoverably at EOF, the first I/O error, or a token too
// large to fit in the buffer. When a scan stops, the reader may have
// advanced arbitrarily far past the last token. Programs that need more
// control over error handling or large tokens, or must run sequential scans
// on a reader, should use bufio.Reader instead.
//
type Scanner struct {
        r            io.Reader // The reader provided by the client.
        split        SplitFunc // The function to split the tokens.
        maxTokenSize int       // Maximum size of a token; modified by tests.
        token        []byte    // Last token returned by split.
        buf          []byte    // Buffer used as argument to split.
        start        int       // First non-processed byte in buf.
        end          int       // End of data in buf.
        err          error     // Sticky error.
}

// SplitFunc is the signature of the split function used to tokenize the
// input. The arguments are an initial substring of the remaining unprocessed
// data and a flag, atEOF, that reports whether the Reader has no more data
// to give. The return values are the number of bytes to advance the input
// and the next token to return to the user, plus an error, if any. If the
// data does not yet hold a complete token, for instance if it has no newline
// while scanning lines, SplitFunc can return (0, nil, nil) to signal the
// Scanner to read more data into the slice and try again with a longer slice
// starting at the same point in the input.
//
// If the returned error is non-nil, scanning stops and the error
// is returned to the client.
//
// The function is never called with an empty data slice unless atEOF
// is true. If atEOF is true, however, data may be non-empty and,
// as always, holds unprocessed text.
type SplitFunc func(data []byte, atEOF bool) (advance int, token []byte, err error)

// Errors returned by Scanner.
var (
        ErrTooLong         = errors.New("bufio.Scanner: token too long")
        ErrNegativeAdvance = errors.New("bufio.Scanner: SplitFunc returns negative advance count")
        ErrAdvanceTooFar   = errors.New("bufio.Scanner: SplitFunc returns advance count beyond input")
)

const (
        // Maximum size used to buffer a token. The actual maximum token size
        // may be smaller as the buffer may need to include, for instance, a newline.
        MaxScanTokenSize = 1 << 30
)

// NewScanner returns a new Scanner to read from r.
// The split function defaults to ScanLines.
func NewScanner(r io.Reader) *Scanner {
        return &Scanner{
                r:            r,
                split:        ScanLines,
                maxTokenSize: MaxScanTokenSize,
                buf:          make([]byte, 4096), // Plausible starting size; needn't be large.
        }
}

// Err returns the first non-EOF error that was encountered by the Scanner.
func (s *Scanner) Err() error {
        if s.err == io.EOF {
                return nil
        }
        return s.err
}

// Bytes returns the most recent token generated by a call to Scan.
// The underlying array may point to data that will be overwritten
// by a subsequent call to Scan. It does no allocation.
func (s *Scanner) Bytes() []byte {
        return s.token
}

// Text returns the most recent token generated by a call to Scan
// as a newly allocated string holding its bytes.
func (s *Scanner) Text() string {
        return string(s.token)
}

// Scan advances the Scanner to the next token, which will then be
// available through the Bytes or Text method. It returns false when the
// scan stops, either by reaching the end of the input or an error.
// After Scan returns false, the Err method will return any error that
// occurred during scanning, except that if it was io.EOF, Err
// will return nil.
func (s *Scanner) Scan() bool {
        // Loop until we have a token.
        for {
                // See if we can get a token with what we already have.
                if s.end > s.start {
                        advance, token, err := s.split(s.buf[s.start:s.end], s.err != nil)
                        if err != nil {
                                s.setErr(err)
                                return false
                        }
                        if !s.advance(advance) {
                                return false
                        }
                        s.token = token
                        if token != nil {
                                return true
                        }
                }
                // We cannot generate a token with what we are holding.
                // If we've already hit EOF or an I/O error, we are done.
                if s.err != nil {
                        // Shut it down.
                        s.start = 0
                        s.end = 0
                        return false
                }
                // Must read more data.
                // First, shift data to beginning of buffer if there's lots of empty space
                // or space is neded.
                if s.start > 0 && (s.end == len(s.buf) || s.start > len(s.buf)/2) {
                        copy(s.buf, s.buf[s.start:s.end])
                        s.end -= s.start
                        s.start = 0
                }
                // Is the buffer full? If so, resize.
                if s.end == len(s.buf) {
                        if len(s.buf) >= s.maxTokenSize {
                                s.setErr(ErrTooLong)
                                return false
                        }
                        newSize := len(s.buf) * 2
                        if newSize > s.maxTokenSize {
                                newSize = s.maxTokenSize
                        }
                        newBuf := make([]byte, newSize)
                        copy(newBuf, s.buf[s.start:s.end])
                        s.buf = newBuf
                        s.end -= s.start
                        s.start = 0
                        continue
                }
                // Finally we can read some input. Make sure we don't get stuck with
                // a misbehaving Reader. Officially we don't need to do this, but let's
                // be extra careful: Scanner is for safe, simple jobs.
                for loop := 0; ; {
                        n, err := s.r.Read(s.buf[s.end:len(s.buf)])
                        s.end += n
                        if err != nil {
                                s.setErr(err)
                                break
                        }
                        if n > 0 {
                                break
                        }
                        loop++
                        if loop > 100 {
                                s.setErr(io.ErrNoProgress)
                                break
                        }
                }
        }
}

// advance consumes n bytes of the buffer. It reports whether the advance was legal.
func (s *Scanner) advance(n int) bool {
        if n < 0 {
                s.setErr(ErrNegativeAdvance)
                return false
        }
        if n > s.end-s.start {
                s.setErr(ErrAdvanceTooFar)
                return false
        }
        s.start += n
        return true
}

// setErr records the first error encountered.
func (s *Scanner) setErr(err error) {
        if s.err == nil || s.err == io.EOF {
                s.err = err
        }
}

// Split sets the split function for the Scanner. If called, it must be
// called before Scan. The default split function is ScanLines.
func (s *Scanner) Split(split SplitFunc) {
        s.split = split
}

// Split functions

// ScanBytes is a split function for a Scanner that returns each byte as a token.
func ScanBytes(data []byte, atEOF bool) (advance int, token []byte, err error) {
        if atEOF && len(data) == 0 {
                return 0, nil, nil
        }
        return 1, data[0:1], nil
}

var errorRune = []byte(string(utf8.RuneError))

// ScanRunes is a split function for a Scanner that returns each
// UTF-8-encoded rune as a token. The sequence of runes returned is
// equivalent to that from a range loop over the input as a string, which
// means that erroneous UTF-8 encodings translate to U+FFFD = "\xef\xbf\xbd".
// Because of the Scan interface, this makes it impossible for the client to
// distinguish correctly encoded replacement runes from encoding errors.
func ScanRunes(data []byte, atEOF bool) (advance int, token []byte, err error) {
        if atEOF && len(data) == 0 {
                return 0, nil, nil
        }

        // Fast path 1: ASCII.
        if data[0] < utf8.RuneSelf {
                return 1, data[0:1], nil
        }

        // Fast path 2: Correct UTF-8 decode without error.
        _, width := utf8.DecodeRune(data)
        if width > 1 {
                // It's a valid encoding. Width cannot be one for a correctly encoded
                // non-ASCII rune.
                return width, data[0:width], nil
        }

        // We know it's an error: we have width==1 and implicitly r==utf8.RuneError.
        // Is the error because there wasn't a full rune to be decoded?
        // FullRune distinguishes correctly between erroneous and incomplete encodings.
        if !atEOF && !utf8.FullRune(data) {
                // Incomplete; get more bytes.
                return 0, nil, nil
        }

        // We have a real UTF-8 encoding error. Return a properly encoded error rune
        // but advance only one byte. This matches the behavior of a range loop over
        // an incorrectly encoded string.
        return 1, errorRune, nil
}

// dropCR drops a terminal \r from the data.
func dropCR(data []byte) []byte {
        if len(data) > 0 && data[len(data)-1] == '\r' {
                return data[0 : len(data)-1]
        }
        return data
}

// ScanLines is a split function for a Scanner that returns each line of
// text, stripped of any trailing end-of-line marker. The returned line may
// be empty. The end-of-line marker is one optional carriage return followed
// by one mandatory newline. In regular expression notation, it is `\r?\n`.
// The last non-empty line of input will be returned even if it has no
// newline.
func ScanLines(data []byte, atEOF bool) (advance int, token []byte, err error) {
        if atEOF && len(data) == 0 {
                return 0, nil, nil
        }
        if i := bytes.IndexByte(data, '\n'); i >= 0 {
                // We have a full newline-terminated line.
                return i + 1, dropCR(data[0:i]), nil
        }
        // If we're at EOF, we have a final, non-terminated line. Return it.
        if atEOF {
                return len(data), dropCR(data), nil
        }
        // Request more data.
        return 0, nil, nil
}

// isSpace reports whether the character is a Unicode white space character.
// We avoid dependency on the unicode package, but check validity of the implementation
// in the tests.
func isSpace(r rune) bool {
        if r <= '\u00FF' {
                // Obvious ASCII ones: \t through \r plus space. Plus two Latin-1 oddballs.
                switch r {
                case ' ', '\t', '\n', '\v', '\f', '\r':
                        return true
                case '\u0085', '\u00A0':
                        return true
                }
                return false
        }
        // High-valued ones.
        if '\u2000' <= r && r <= '\u200a' {
                return true
        }
        switch r {
        case '\u1680', '\u180e', '\u2028', '\u2029', '\u202f', '\u205f', '\u3000':
                return true
        }
        return false
}

// ScanWords is a split function for a Scanner that returns each
// space-separated word of text, with surrounding spaces deleted. It will
// never return an empty string. The definition of space is set by
// unicode.IsSpace.
func ScanWords(data []byte, atEOF bool) (advance int, token []byte, err error) {
        // Skip leading spaces.
        start := 0
        for width := 0; start < len(data); start += width {
                var r rune
                r, width = utf8.DecodeRune(data[start:])
                if !isSpace(r) {
                        break
                }
        }
        if atEOF && len(data) == 0 {
                return 0, nil, nil
        }
        // Scan until space, marking end of word.
        for width, i := 0, start; i < len(data); i += width {
                var r rune
                r, width = utf8.DecodeRune(data[i:])
                if isSpace(r) {
                        return i + width, data[start:i], nil
                }
        }
        // If we're at EOF, we have a final, non-empty, non-terminated word. Return it.
        if atEOF && len(data) > start {
                return len(data), data[start:], nil
        }
        // Request more data.
        return 0, nil, nil
}

package main

import (
	"bufio"
	"errors"
	"flag"
	"fmt"
	"log"
	"os"
	"strconv"
	"time"
)

// ******************************** CODE STARTS ********************************

var (
	mas [100010]int64
)

func solve() {
	n := readInt()
	for i := 0; i < n; i++ {
		mas[i] = readInt64()
	}

	best := mas[1]*mas[1] + 1
	for i := 1; i < n; i++ {
		if best > mas[i]*mas[i]+1 {
			best = mas[i]*mas[i] + 1
		}
	}

	for i := 1; i < n; i++ {
		mas[i] += mas[i-1]
	}

	for j := 1; j < n; j++ {
		for i := j - 1; i > -1; i-- {
			s := int64(j-i) * int64(j-i)
			if s > best || s > 5000000 {
				break
			}
			if absInt64(mas[i]-mas[j]) < 10000 {
				if best > absInt64(mas[i]-mas[j])*absInt64(mas[i]-mas[j])+s {
					best = absInt64(mas[i]-mas[j])*absInt64(mas[i]-mas[j]) + s
				}
			}
		}
	}
	printInt64(best)
	printLine()
}

// ********************************* CODE ENDS *********************************

// IO.

var (
	scanner *bufio.Scanner
	writer  *bufio.Writer
	logger  *log.Logger
)

func main() {
	local := flag.Bool("local", false, "Equals true, if run is local.")
	flag.Parse()

	var (
		input  *os.File
		output *os.File
	)

	if *local {
		startTime := time.Now()
		defer func() {
			println(fmt.Sprintf("Time: %.5fs", time.Since(startTime).Seconds()))
		}()
		input, _ = os.Open("/home/outside/coding/workspace/go/io/input.txt")
		output, _ = os.Create("/home/outside/coding/workspace/go/io/output.txt")
		logger = log.New(output, "log: ", 0)
	} else {
		input = os.Stdin
		output = os.Stdout
		// input, _ = os.Open("")
		// output, _ = os.Create("")
	}
	defer input.Close()
	defer output.Close()

	scanner = bufio.NewScanner(input)
	scanner.Split(bufio.ScanWords)

	writer = bufio.NewWriter(output)
	defer writer.Flush()

	solve()
}

// Read.

func readString() string {
	scanner.Scan()
	ans := scanner.Text()
	return ans
}

func readLine() string {
	scanner.Split(bufio.ScanLines)
	defer scanner.Split(bufio.ScanWords)
	return readString()
}

func readInt() int {
	ans, _ := strconv.ParseInt(readString(), 10, 0)
	return int(ans)
}

func readInt64() int64 {
	ans, _ := strconv.ParseInt(readString(), 10, 64)
	return ans
}

func readFloat64() float64 {
	ans, _ := strconv.ParseFloat(readString(), 64)
	return ans
}

// Write.

func printString(value string) {
	writer.WriteString(value)
}

func printLine() {
	printString("\n")
}

func printInt(value int) {
	printString(strconv.FormatInt(int64(value), 10))
}

func printInt64(value int64) {
	printString(strconv.FormatInt(value, 10))
}

func printFLoat64(value float64) {
	printString(strconv.FormatFloat(value, 'f', 20, 64))
}

// Log.

func logln(value ...interface{}) {
	writer.Flush()
	logger.Println(value...)
}
func logf(format string, value ...interface{}) {
	writer.Flush()
	logger.Printf(format, value...)
}

// Min, max, abs.

func maxInt(a, b int) int {
	if a > b {
		return a
	} else {
		return b
	}
}

func minInt(a, b int) int {
	if a < b {
		return a
	} else {
		return b
	}
}

func absInt(a int) int {
	if a > 0 {
		return a
	} else {
		return -a
	}
}

func maxInt64(a, b int64) int64 {
	if a > b {
		return a
	} else {
		return b
	}
}

func minInt64(a, b int64) int64 {
	if a < b {
		return a
	} else {
		return b
	}
}

func absInt64(a int64) int64 {
	if a > 0 {
		return a
	} else {
		return -a
	}
}

func maxFloat64(a, b float64) float64 {
	if a > b {
		return a
	} else {
		return b
	}
}

func minFloat64(a, b float64) float64 {
	if a < b {
		return a
	} else {
		return b
	}
}

func absFloat64(a float64) float64 {
	if a > 0 {
		return a
	} else {
		return -a
	}
}

// Set Key interface implementations.

type Int int

func (p Int) Equals(key Key) bool {
	return int(p) == int(key.(Int))
}

func (p Int) Less(key Key) bool {
	return int(p) < int(key.(Int))
}

// Set.

type Key interface {
	Equals(key Key) bool
	Less(key Key) bool
}

type node struct {
	key   Key
	left  *node
	right *node
}

func newNode(key Key) *node {
	return &node{key, nil, nil}
}

type SplayTree struct {
	root *node
	tmp  *node
	len  int
}

func NewSplayTree() *SplayTree {
	return &SplayTree{nil, newNode(nil), 0}
}

func rotateLeft(x, p *node) {
	p.right = x.left
	x.left = p
}

func rotateRight(x, p *node) {
	p.left = x.right
	x.right = p
}

func (p *SplayTree) splay(x *node, key Key) *node {
	if x == nil {
		return nil
	}

	left := p.tmp
	right := p.tmp

	for {
		if key.Less(x.key) {
			y := x.left
			if y == nil {
				break
			}
			if key.Less(y.key) { // zig-zig
				rotateRight(y, x)
				x = y
				if x.left == nil {
					break
				}
			}
			// link right
			right.left = x
			right = x
			// move left
			x = x.left
		} else if x.key.Less(key) {
			y := x.right
			if y == nil {
				break
			}
			if y.key.Less(key) { // zig-zig
				rotateLeft(y, x)
				x = y
				if x.right == nil {
					break
				}
			}
			// link left
			left.right = x
			left = x
			// move right
			x = x.right
		} else {
			break
		}
	}

	left.right = x.left
	right.left = x.right
	x.left = p.tmp.right
	x.right = p.tmp.left

	return x
}

// left <= key < right
func (p *SplayTree) split(key Key) (left, right *node) {
	p.root = p.splay(p.root, key)
	if p.root.key.Equals(key) || p.root.key.Less(key) {
		right := p.root.right
		p.root.right = nil
		return p.root, right
	} else {
		left := p.root.left
		p.root.left = nil
		return left, p.root
	}
}

// keys from left tree must be less then keys from right tree
func (p *SplayTree) join(left, right *node) *node {
	if left == nil {
		return right
	} else if right == nil {
		return left
	}
	left = p.splay(left, right.key)
	left.right = right
	return left
}

type Set interface {
	Len() int
	Insert(key Key) error
	Find(key Key) bool
	Remove(key Key) error
}

func NewSet() Set {
	return Set(NewSplayTree())
}

func (p *SplayTree) Len() int {
	return p.len
}

func (p *SplayTree) Insert(key Key) error {
	if p.root == nil {
		p.root = newNode(key)
		p.len++
	} else {
		p.root = p.splay(p.root, key)
		if p.root.key.Equals(key) {
			return errors.New("Such key already exists")
		} else {
			left, right := p.split(key)
			p.root = newNode(key)
			p.root.left = left
			p.root.right = right
			p.len++
		}
	}
	return nil
}

func (p *SplayTree) Find(key Key) bool {
	if p.root == nil {
		return false
	}
	p.root = p.splay(p.root, key)
	return p.root.key.Equals(key)
}

func (p *SplayTree) Remove(key Key) error {
	p.root = p.splay(p.root, key)
	if p.root == nil || !p.root.key.Equals(key) {
		return errors.New("Such key doesn't exist")
	}
	p.root = p.join(p.split(key))
	return nil
}

package main

import (
	"bufio"
	. "fmt"
	"index/suffixarray"
	"io"
	"os"
	"reflect"
	"unsafe"
)

// github.com/EndlessCheng/codeforces-go
func Sol427D(reader io.Reader, writer io.Writer) {
	min := func(a, b int) int {
		if a <= b {
			return a
		}
		return b
	}
	max := func(a, b int) int {
		if a >= b {
			return a
		}
		return b
	}

	in := bufio.NewReader(reader)
	out := bufio.NewWriter(writer)
	defer out.Flush()

	var s, t []byte
	Fscan(in, &s, &t)

	lenS1 := len(s)
	s = append(s, '$')
	s = append(s, t...)
	sa := *(*[]int)(unsafe.Pointer(reflect.ValueOf(suffixarray.New(s)).Elem().FieldByName("sa").UnsafeAddr()))
	sa = append([]int{len(s)}, sa...)

	n := len(s)
	rank := make([]int, n+1)
	for i := range rank {
		rank[sa[i]] = i
	}
	lcp := make([]int, n)
	h := 0
	for i := range lcp {
		j := sa[rank[i]-1]
		if h > 0 {
			h--
		}
		for ; j+h < n && i+h < n; h++ {
			if s[j+h] != s[i+h] {
				break
			}
		}
		lcp[rank[i]-1] = h
	}

	const inf int = 1e9
	ans := inf
	for i := 2; i+1 < n; i++ {
		if (sa[i] < lenS1) != (sa[i+1] < lenS1) && lcp[i-1] < lcp[i] && lcp[i+1] < lcp[i] {
			ans = min(ans, 1+max(lcp[i-1], lcp[i+1]))
		}
	}
	if ans == inf {
		ans = -1
	}
	Fprint(out, ans)
}

func main() {
	Sol427D(os.Stdin, os.Stdout)
}