← Home
package main

import (
	"bufio"
	"fmt"
	"os"
)

const INF = 1000000000

type SegTree struct {
	maxVal []int
	lazy   []int
}

func NewSegTree(n int) *SegTree {
	return &SegTree{
		maxVal: make([]int, 4*(n+1)),
		lazy:   make([]int, 4*(n+1)),
	}
}

func (st *SegTree) build(node, l, r int, initial []int) {
	st.lazy[node] = 0
	if l == r {
		st.maxVal[node] = initial[l]
		return
	}
	mid := l + (r-l)/2
	st.build(2*node, l, mid, initial)
	st.build(2*node+1, mid+1, r, initial)
	if st.maxVal[2*node] > st.maxVal[2*node+1] {
		st.maxVal[node] = st.maxVal[2*node]
	} else {
		st.maxVal[node] = st.maxVal[2*node+1]
	}
}

func (st *SegTree) AddPrefix(node, l, r, qr, val int) {
	if r <= qr {
		st.maxVal[node] += val
		st.lazy[node] += val
		return
	}
	if st.lazy[node] != 0 {
		lz := st.lazy[node]
		st.maxVal[2*node] += lz
		st.lazy[2*node] += lz
		st.maxVal[2*node+1] += lz
		st.lazy[2*node+1] += lz
		st.lazy[node] = 0
	}
	mid := l + (r-l)/2
	if qr <= mid {
		st.AddPrefix(2*node, l, mid, qr, val)
	} else {
		st.maxVal[2*node] += val
		st.lazy[2*node] += val
		st.AddPrefix(2*node+1, mid+1, r, qr, val)
	}
	if st.maxVal[2*node] > st.maxVal[2*node+1] {
		st.maxVal[node] = st.maxVal[2*node]
	} else {
		st.maxVal[node] = st.maxVal[2*node+1]
	}
}

func (st *SegTree) QueryPrefixMax(node, l, r, qr int) int {
	if r <= qr {
		return st.maxVal[node]
	}
	if st.lazy[node] != 0 {
		lz := st.lazy[node]
		st.maxVal[2*node] += lz
		st.lazy[2*node] += lz
		st.maxVal[2*node+1] += lz
		st.lazy[2*node+1] += lz
		st.lazy[node] = 0
	}
	mid := l + (r-l)/2
	if qr <= mid {
		return st.QueryPrefixMax(2*node, l, mid, qr)
	} else {
		leftMax := st.maxVal[2*node]
		rightMax := st.QueryPrefixMax(2*node+1, mid+1, r, qr)
		if leftMax > rightMax {
			return leftMax
		}
		return rightMax
	}
}

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	scanner.Buffer(make([]byte, 20000), 20000)
	if !scanner.Scan() {
		return
	}
	s := scanner.Text()
	if !scanner.Scan() {
		return
	}
	t := scanner.Text()

	n := len(s)
	m := len(t)

	match := make([]int, n+1)
	stack := make([]int, 0, n)
	for i := 1; i <= n; i++ {
		if s[i-1] == '.' {
			if len(stack) > 0 {
				match[i] = stack[len(stack)-1]
				stack = stack[:len(stack)-1]
			}
		} else {
			stack = append(stack, i)
		}
	}

	suff := make([]int, n+2)
	for i := 1; i <= n; i++ {
		if match[i] > 0 {
			suff[match[i]]++
		}
	}
	for i := n; i >= 1; i-- {
		suff[i] += suff[i+1]
	}

	dp := make([]int, n+1)
	for i := 1; i <= n; i++ {
		dp[i] = -INF
	}
	dp[0] = 0

	st := NewSegTree(n)

	for j := 1; j <= m; j++ {
		st.build(1, 0, n, dp)
		new_dp := make([]int, n+1)
		for i := 0; i <= n; i++ {
			new_dp[i] = -INF
		}

		for i := 1; i <= n; i++ {
			if s[i-1] == '.' && match[i] > 0 {
				l := match[i]
				st.AddPrefix(1, 0, n, l-1, 1)
			}
			if s[i-1] == t[j-1] {
				new_dp[i] = st.QueryPrefixMax(1, 0, n, i-1)
			}
		}
		dp = new_dp
	}

	maxPairs := -1
	for i := 1; i <= n; i++ {
		if s[i-1] == t[m-1] {
			if dp[i] >= 0 {
				pairs := dp[i] + suff[i+1]
				if pairs > maxPairs {
					maxPairs = pairs
				}
			}
		}
	}

	ans := n - (m + 2*maxPairs)
	fmt.Println(ans)
}