Sergei B., the young coach of Pokemons, has found the big house which consists of n flats ordered in a row from left to right. It is possible to enter each flat from the street. It is possible to go out from each flat. Also, each flat is connected with the flat to the left and the flat to the right. Flat number 1 is only connected with the flat number 2 and the flat number n is only connected with the flat number n - 1.

There is exactly one Pokemon of some type in each of these flats. Sergei B. asked residents of the house to let him enter their flats in order to catch Pokemons. After consulting the residents of the house decided to let Sergei B. enter one flat from the street, visit several flats and then go out from some flat. But they won't let him visit the same flat more than once. 

Sergei B. was very pleased, and now he wants to visit as few flats as possible in order to collect Pokemons of all types that appear in this house. Your task is to help him and determine this minimum number of flats he has to visit. 


-----Input-----

The first line contains the integer n (1 ≤ n ≤ 100 000) — the number of flats in the house.

The second line contains the row s with the length n, it consists of uppercase and lowercase letters of English alphabet, the i-th letter equals the type of Pokemon, which is in the flat number i. 


-----Output-----

Print the minimum number of flats which Sergei B. should visit in order to catch Pokemons of all types which there are in the house. 


-----Examples-----
Input
3
AaA

Output
2

Input
7
bcAAcbc

Output
3

Input
6
aaBCCe

Output
5



-----Note-----

In the first test Sergei B. can begin, for example, from the flat number 1 and end in the flat number 2.

In the second test Sergei B. can begin, for example, from the flat number 4 and end in the flat number 6. 

In the third test Sergei B. must begin from the flat number 2 and end in the flat number 6.

Difficulty: MEDIUM
Tags: String algorithms

Sorting

Amortized analysis
Skill types: Sorting

Amortized analysis
Expected Time Complexity: O(N)

Starter code:

Solutions:
n = int(input())
s = input()
k = k1 = n
q = set()
c = 0
w = 0
t = False
for i in range(n):
	if s[i] not in q:
		q.add(s[i])
		w = i
		k1 = k = w - c + 1
while True:
	if s[c] in s[c + 1:w + 1]:
		if w - c < k1:
			k1 = w - c
			if k1 < k:
				k = k1
		c += 1
	else:
		for i in range(c + 1, n):
			if s[i] == s[c]:
				w = i
				t = True
				break
		if t == False:
			print(k)
			break
		t = False


import sys
line = input()
n = int(line)
line2 = input()
line2 = list(line2)
letters = {}
i = 0
while i < n:
	if line2[i] not in letters:
		letters[line2[i]] = 1
	i = i + 1
noPoke = len(letters.keys())
for letter in letters:
	letters[letter] = 0
min = 0
i = 0
while min < noPoke and i < n:
	if line2[i] in letters:
		if letters[line2[i]] == 0:
			min = min + 1
	letters[line2[i]] = letters[line2[i]] + 1
	i = i + 1
k = 0
rez = i
while letters[line2[k]] > 1:
	letters[line2[k]] = letters[line2[k]] - 1
	k = k + 1
rez = rez - k
valid = 0
while i < n and valid == 0 and (rez > noPoke):
	letters[line2[i]] = letters[line2[i]] + 1
	while letters[line2[k]] > 1:
		letters[line2[k]] = letters[line2[k]] - 1
		k = k + 1
	rez2 = i - k + 1
	if rez2 < rez:
		rez = rez2
		if noPoke == rez:
			valid = 1
	i = i + 1
print(str(rez))


n = int(input())
s = input()
l = [0] * n
for t in set(s):
	j = -1
	for i in range(n):
		if s[i] == t:
			j = i
		if j == -1:
			l[i] = n
		else:
			l[i] = max(l[i], i - j + 1)
print(min(l))


n = int(input())
a = input()
b = dict()
c = dict()
for i in a:
	b[i] = b.get(i, 0) + 1
r = 0
ans = n
for i in range(n):
	while len(c) < len(b) and r < n:
		c[a[r]] = c.get(a[r], 0) + 1
		r += 1
	if r == n and len(c) < len(b):
		break
	c[a[i]] = c.get(a[i], 0) - 1
	ans = min(ans, r - i)
	if c[a[i]] < 1:
		del c[a[i]]
print(ans)


n = int(input())
s = input()
check = {}
size_check = set((x for x in s))
ans = 10 ** 5
left = 0
for right in range(n):
	if s[right] in check:
		check[s[right]] += 1
	else:
		check[s[right]] = 1
	while left < right and s[left] in check and (check[s[left]] > 1):
		check[s[left]] -= 1
		left += 1
	if len(check) == len(size_check):
		if right - left + 1 < ans:
			ans = right - left + 1
print(ans)


from typing import Dict, Any
flat_num = int(input())
flats = input()
types = set(flats)
shortest_interval = float('inf')
closest_left = 0
curr_caught = {}
for (right, f) in enumerate(flats):
	if f not in curr_caught:
		curr_caught[f] = 0
	curr_caught[f] += 1
	while closest_left + 1 <= right and curr_caught.get(flats[closest_left], 0) > 1:
		curr_caught[flats[closest_left]] -= 1
		closest_left += 1
	if len(curr_caught) == len(types):
		shortest_interval = min(shortest_interval, right - closest_left + 1)
print(shortest_interval)


n = int(input())
s = list(input())
types = len(set(s))

def check(l):
	mp = dict()
	for i in range(l):
		if s[i] not in mp:
			mp[s[i]] = 1
		else:
			mp[s[i]] += 1
	if len(mp) == types:
		return True
	for i in range(l, n):
		mp[s[i - l]] -= 1
		if mp[s[i - l]] is 0:
			mp.pop(s[i - l])
		if s[i] not in mp:
			mp[s[i]] = 1
		else:
			mp[s[i]] += 1
		if len(mp) == types:
			return True
	return False
(l, r) = (1, n)
while l < r:
	mid = (l + r) // 2
	if check(mid):
		r = mid
	else:
		l = mid + 1
print(r)


n = int(input())
s = input()
letters = set()
for i in range(len(s)):
	letters.add(s[i])
magic = 1000000000
length = [0] * len(s)
for c in letters:
	last = -1
	for i in range(len(s)):
		if s[i] == c:
			last = i
		if last == -1:
			length[i] = magic
		else:
			length[i] = max(length[i], i - last + 1)
ans = magic
for i in range(len(s)):
	if length[i] < ans:
		ans = length[i]
print(ans)


n = int(input())
s = input()
c = set(s)
d = {i: 0 for i in c}
maks = 999999
l = 0
for i in range(n):
	d[s[i]] += 1
	if c != set():
		if s[i] in c:
			c.remove(s[i])
	if c == set():
		while True:
			d[s[l]] -= 1
			if d[s[l]] == 0:
				c.add(s[l])
				l += 1
				break
			l += 1
		maks = min(maks, i - l + 2)
print(maks)


from collections import Counter
c = Counter()
ans = n = int(input())
s = input()
k = len(set(s))
i = j = t = 0
while j < n:
	while len(c) < k and j < n:
		c[s[j]] += 1
		j += 1
	while len(c) == k:
		if j - i < ans:
			ans = j - i
		c[s[i]] -= 1
		if c[s[i]] == 0:
			del c[s[i]]
		i += 1
print(ans)


n = int(input())
st = input()
i2 = 0
uniques = 0
has = dict()
mi = 1000000
for ch in st:
	if ch not in has:
		has[ch] = 0
for i in range(n):
	while uniques < len(has) and i2 < n:
		has[st[i2]] += 1
		if has[st[i2]] == 1:
			uniques += 1
		i2 += 1
	if uniques < len(has):
		break
	mi = min(mi, i2 - i)
	if has[st[i]] == 1:
		uniques -= 1
	has[st[i]] -= 1
print(mi)


from sys import stdin

def main():
	n = int(stdin.readline())
	ville = stdin.readline()
	minimum = n
	maisons = {}
	nbType = 0
	for maison in ville:
		if maison != '\n' and maison not in maisons:
			maisons[maison] = 0
			nbType += 1
	nbZeros = nbType - 1
	inf = 0
	sup = 0
	maisons[ville[0]] += 1
	while n > sup:
		if nbZeros == 0:
			minimum = min(minimum, sup - inf + 1)
			maisons[ville[inf]] -= 1
			if maisons[ville[inf]] == 0:
				nbZeros += 1
			inf += 1
		else:
			sup += 1
			if n > sup:
				maisons[ville[sup]] += 1
				if maisons[ville[sup]] == 1:
					nbZeros -= 1
	print(minimum)
main()


def main():
	input()
	s = input()
	d = dict.fromkeys(s, 0)
	(le, res) = (len(d), [])
	(iti, itj) = (iter(enumerate(s)) for _ in '12')
	try:
		while True:
			while le:
				(i, c) = next(iti)
				if d[c]:
					d[c] += 1
				else:
					d[c] = 1
					le -= 1
			while True:
				(j, c) = next(itj)
				if d[c] > 1:
					d[c] -= 1
				else:
					(d[c], le) = (0, 1)
					res.append(i - j)
					break
	except StopIteration:
		print(min(res) + 1)
main()


def calculate_ans(flats):
	(needed, shortest) = (len(set(flats)), len(flats))
	counter = dict()
	(ind1, ind2) = (0, 0)
	while ind1 < len(flats):
		if len(counter.keys()) == needed:
			shortest = min(shortest, ind2 - ind1)
			counter[flats[ind1]] -= 1
			if counter[flats[ind1]] == 0:
				del counter[flats[ind1]]
			ind1 += 1
		else:
			if ind2 == len(flats):
				break
			if flats[ind2] in counter:
				counter[flats[ind2]] += 1
			else:
				counter[flats[ind2]] = 1
			ind2 += 1
	return shortest
_ = input()
print(calculate_ans(input()))


n = int(input())
s = input()
S = len(set(s))
a = n
j = t = 0
d = {}
for i in range(n):
	if s[i] not in d:
		d[s[i]] = 0
		t += 1
	d[s[i]] += 1
	if t == S:
		while d[s[j]] > 1:
			d[s[j]] -= 1
			j += 1
		a = min(a, i - j + 1)
print(a)


a = int(input())
from collections import defaultdict
al = defaultdict(int)
z = input()
count = 0
for i in range(len(z)):
	if al[z[i]] == 0:
		count += 1
		al[z[i]] = 1
dk = defaultdict(int)
l = 0
r = 0
ans = []
dount = 0
flag = 0
while l <= r and r <= len(z) - 1:
	if dk[z[r]] == 0:
		dount += 1
		dk[z[r]] += 1
	elif flag == 0:
		dk[z[r]] += 1
	if dount == count:
		dk[z[l]] -= 1
		ans.append(r - l + 1)
		l += 1
		flag = 1
		if dk[z[l - 1]] == 0:
			dount = dount - 1
			r += 1
			flag = 0
		continue
	else:
		r += 1
print(min(ans))


import os, sys
from io import BytesIO, IOBase
from collections import Counter
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
from math import ceil
mod = 10 ** 9 + 7
for _ in range(1):
	n = int(input())
	p = list(input())
	pokemons = len(set(p))
	ans = float('inf')
	c = Counter()
	start = 0
	end = 0
	while end < n:
		while end < n and len(c) < pokemons:
			c[p[end]] += 1
			end += 1
		while len(c) == pokemons:
			ans = min(ans, end - start)
			c[p[start]] -= 1
			if c[p[start]] == 0:
				del c[p[start]]
			start += 1
	print(ans)


n = int(input())
s = input()
tCap = []
shortest = n
l = 0
for r in range(n):
	if s[r] not in tCap:
		tCap += s[r]
		shortest = r - l + 1
	else:
		while s[l] in s[l + 1:r + 1]:
			l += 1
		if r - l + 1 < shortest:
			shortest = r - l + 1
print(shortest)


from collections import defaultdict
n = int(input())
s = input()
need = len(set(s))
types = set()
cnt = defaultdict(int)
ret = float('inf')
left = 0
for right in range(n):
	types.add(s[right])
	cnt[s[right]] += 1
	while len(types) == need:
		ret = min(ret, right - left + 1)
		cnt[s[left]] -= 1
		if cnt[s[left]] == 0:
			types.remove(s[left])
		left += 1
print(ret)


n = int(input())
s = input()
all_types = set()
count = {}
for c in s:
	all_types.add(c)
	count[c] = 0
n_all_types = len(all_types)

def solve():
	ret = n
	first = 0
	last = 0
	n_types = 0
	while first <= last:
		while n_types < n_all_types:
			if last == n:
				return ret
			if count[s[last]] == 0:
				n_types += 1
			count[s[last]] += 1
			last += 1
		ret = min(ret, last - first)
		if count[s[first]] == 1:
			n_types -= 1
		count[s[first]] -= 1
		first += 1
	return ret
print(solve())


n = int(input())
a = list(input())
p = len(set(a))
(l, i, j) = (0, 0, 0)
b = []
c = {}
while i < n or j < n:
	if l == p:
		b.append(j - i)
		c[a[i]] -= 1
		if c[a[i]] == 0:
			l = l - 1
		i = i + 1
	elif j < n:
		while l != p and j < n:
			if a[j] in c:
				if c[a[j]] == 0:
					l = l + 1
					c[a[j]] = c[a[j]] + 1
				else:
					c[a[j]] += 1
			else:
				l += 1
				c[a[j]] = 1
			j += 1
	else:
		i += 1
print(min(b))


import sys
n = int(sys.stdin.readline())
line = sys.stdin.readline()
st = set()
dt = dict()
for x in line:
	st.add(x)
st.remove('\n')
ans = n
head = 0
for i in range(n):
	x = line[i]
	if x not in dt:
		dt[x] = 1
	else:
		dt[x] += 1
	while head <= i:
		x = line[head]
		if x in dt and dt[x] > 1:
			dt[x] -= 1
			head += 1
		else:
			break
	if len(dt) == len(st):
		ans = min(ans, i - head + 1)
print(ans)


def solve(s, k):
	d = {}
	for i in s:
		d[i] = 1
	c = len(d)
	d = {}
	for i in range(k):
		if s[i] in d:
			d[s[i]] += 1
		else:
			d[s[i]] = 1
	if len(d) == c:
		return True
	dif = 0
	for i in range(k, n):
		if s[i] in d:
			if d[s[i]] == 0:
				dif -= 1
			d[s[i]] += 1
			d[s[i - k]] -= 1
			if d[s[i - k]] == 0:
				dif += 1
		else:
			d[s[i]] = 1
			d[s[i - k]] -= 1
			if d[s[i - k]] == 0:
				dif += 1
		if len(d) - dif == c:
			return True
	return False
n = int(input())
s = str(input())
low = 1
high = n
ans = 0
while low <= high:
	mid = (low + high) // 2
	k = mid
	if solve(s, k):
		ans = mid
		high = mid - 1
	else:
		low = mid + 1
print(ans)


import os
import sys
from math import *
from collections import *
from fractions import *
from bisect import *
from io import BytesIO, IOBase

def vsInput():
	sys.stdin = open('input.txt', 'r')
	sys.stdout = open('output.txt', 'w')
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')

def value():
	return tuple(map(int, input().split()))

def array():
	return [int(i) for i in input().split()]

def Int():
	return int(input())

def Str():
	return input()

def arrayS():
	return [i for i in input().split()]
n = Int()
s = input()
left = 0
i = 0
count = defaultdict(int)
chars = len(set(s))
i = 0
cur = 0
ans = inf
while i < n:
	count[s[i]] += 1
	if count[s[i]] == 1:
		cur += 1
	if cur == chars:
		while count[s[left]] > 1:
			count[s[left]] -= 1
			left += 1
		ans = min(i - left + 1, ans)
	i += 1
print(ans)


n = int(input())
pokemons = input()
last = {}
start_of_all = 0
for i in range(n):
	ty = pokemons[i]
	if ty not in last:
		start_of_all = i
	last[ty] = 0
minlen = 100001
for i in range(n):
	ty = pokemons[i]
	last[ty] = i
	length = i + 1 - min(last.values())
	if i >= start_of_all and length < minlen:
		minlen = length
print(minlen)


n = int(input())
temp = input()
st = [c for c in temp]
temp = set(st)
nT = len(temp)
s = {}
for i in temp:
	s[i] = 0
currT = set()
i = 0
j = 0
minL = 10 ** 10
for i in range(len(st)):
	currT.add(st[i])
	s[st[i]] += 1
	while j < i and s[st[j]] > 1:
		s[st[j]] -= 1
		j += 1
	if len(currT) == nT:
		minL = min(minL, i - j + 1)
print(minL)


from collections import defaultdict
import bisect
n = int(input())
s = input()
x = set(s)
if len(x) == 1:
	print(1)
else:
	ind = defaultdict(list)
	for i in range(n):
		ind[s[i]].append(i)
	i = 0
	j = 0
	while x:
		x.discard(s[j])
		j = j + 1
	j = j - 1
	ans = n
	while j < n:
		f = 0
		t = ''
		for ch in ind:
			l = bisect.bisect_left(ind[ch], i)
			r = bisect.bisect_right(ind[ch], j)
			if r - l == 0:
				f = 1
				t = ch
				break
		if f:
			while s[j] != t:
				j = j + 1
				if j == n:
					break
			if j == n:
				break
			else:
				ans = min(ans, j - i + 1)
				i = i + 1
		else:
			ans = min(ans, j - i + 1)
			i = i + 1
	print(ans)


n = int(input())
s = input()
p = {}
c = set(s)
L = 0
k = n
for R in range(n):
	p[s[R]] = p.get(s[R], 0) + 1
	if p[s[R]] == 1:
		c.discard(s[R])
	while L <= R and p[s[L]] > 1:
		p[s[L]] -= 1
		L += 1
	if len(c) == 0:
		k = min(k, R - L + 1)
print(k)


n = int(input())
s = input()
t = set()
for i in range(n):
	t.add(ord(s[i]))
l = len(t)
o = dict()
p = 0
i = 0
while p < l:
	r = o.get(ord(s[i]), 0)
	if r == 0:
		o[ord(s[i])] = 1
		p += 1
	else:
		o[ord(s[i])] += 1
	i += 1
left = 0
minn = i - left
while True:
	if o[ord(s[left])] > 1:
		o[ord(s[left])] -= 1
		left += 1
		minn = min(minn, i - left)
	else:
		if i >= n:
			break
		o[ord(s[i])] += 1
		i += 1
print(minn)


from sys import maxsize, stdout, stdin, stderr
mod = int(1000000000.0 + 7)
import sys

def I():
	return int(stdin.readline())

def lint():
	return [int(x) for x in stdin.readline().split()]

def S():
	return input().strip()

def grid(r, c):
	return [lint() for i in range(r)]
from collections import defaultdict, Counter
import math
import heapq
from heapq import heappop, heappush
import bisect
from itertools import groupby

def gcd(a, b):
	while b:
		a %= b
		tmp = a
		a = b
		b = tmp
	return a

def lcm(a, b):
	return a // gcd(a, b) * b

def check_prime(n):
	for i in range(2, int(n ** (1 / 2)) + 1):
		if not n % i:
			return False
	return True

def Bs(a, x):
	i = 0
	j = 0
	left = 1
	right = x
	flag = False
	while left < right:
		mi = (left + right) // 2
		if a[mi] <= x:
			left = mi + 1
			i += 1
		else:
			right = mi
			j += 1
	if left > 0 and a[left - 1] == x:
		return (i - 1, j)
	else:
		return (-1, -1)

def nCr(n, r):
	return fact(n) // (fact(r) * fact(n - r))

def fact(n):
	res = 1
	for i in range(2, n + 1):
		res = res * i
	return res

def primefactors(n):
	num = 0
	while n % 2 == 0:
		num += 1
		n = n / 2
	for i in range(3, int(math.sqrt(n)) + 1, 2):
		while n % i == 0:
			num += 1
			n = n // i
	if n > 2:
		num += 1
	return num

def ask(a):
	print('? {}'.format(a), flush=True)
	n = I()
	return n

def dfs(i, p):
	(a, tmp) = (0, 0)
	for j in d[i]:
		if j != p:
			a += 1
			tmp += dfs(j, i)
	if a == 0:
		return 0
	return tmp / a + 1

def primeFactors(n):
	l = []
	while n % 2 == 0:
		l.append(2)
		n = n // 2
	if n > 2:
		l.append(n)
	return l
k = 1
for _ in range(k):
	n = I()
	s = S()
	d = Counter(s)
	(l, r) = (0, n - 1)
	m = {}
	tmp = len(set(s))
	(j, ans) = (0, mod)
	for i in range(n):
		if s[i] in m:
			m[s[i]] += 1
		else:
			m[s[i]] = 1
		while j < i and s[j] in m and (m[s[j]] > 1):
			m[s[j]] -= 1
			j += 1
		if len(m) == tmp:
			ans = min(ans, i - j + 1)
	print(ans)


(n, s) = (int(input()), input())
(p, q, r) = (len(set(s)), {}, 10 ** 6)
for i in range(n):
	q[s[i]] = i
	if len(q) == p:
		r = min(r, max(q.values()) - min(q.values()))
print(r + 1)


(n, s) = (int(input()), input())
dis = len(set(s))
mp = {}
(l, r, m, cnt) = (0, 0, 99999999, 0)
for c in s:
	if c not in mp:
		mp[c] = 0
		cnt += 1
	mp[c] += 1
	if cnt == dis:
		while mp[s[l]] > 1:
			mp[s[l]] -= 1
			l += 1
		m = min(m, r - l + 1)
	r += 1
print(m)


def isAllOccurences(left, right):
	global letters
	global disLetters
	for i in disLetters:
		if letters[right][ord(i)] - (0 if left == 0 else letters[left - 1][ord(i)]) == 0:
			return False
	return True

def binSolve(leftStart, rightStart):
	left = leftStart
	right = rightStart
	mid = (left + right) // 2
	lastAllOccurences = mid
	while left <= right:
		mid = (left + right) // 2
		if isAllOccurences(leftStart, mid):
			right = mid - 1
			lastAllOccurences = mid
		else:
			left = mid + 1
	return lastAllOccurences
n = int(input())
s = input()
letters = []
for _ in range(n):
	letters.append([0] * 256)
letters[0][ord(s[0])] = 1
disLetters = [s[0]]
for (i, x) in enumerate(s[1:]):
	for j in range(ord('a'), ord('z') + 1):
		letters[i + 1][j] = letters[i][j]
	for j in range(ord('A'), ord('Z') + 1):
		letters[i + 1][j] = letters[i][j]
	if letters[i + 1][ord(x)] == 0:
		disLetters.append(x)
	letters[i + 1][ord(x)] += 1
globalMin = 1000000
for left in range(n):
	right = binSolve(left, len(s) - 1)
	if isAllOccurences(left, right):
		if abs(right - left + 1) < globalMin:
			globalMin = abs(right - left + 1)
print(globalMin)


n = int(input())
s = input()
k = len(set(s))
c = 0
i = 0
cnt = {}
for i in s:
	cnt[i] = 0
j = 0
i = 0
mini = n
while j < n:
	cnt[s[j]] += 1
	if cnt[s[j]] == 1:
		c += 1
	if c == k:
		while i < j and cnt[s[i]] > 1:
			cnt[s[i]] -= 1
			i += 1
		mini = min(mini, j - i + 1)
	j += 1
print(mini)


def createdict():
	x = {}
	for i in range(26):
		x[chr(ord('a') + i)] = i
	for i in range(26, 52):
		x[chr(ord('A') + i - 26)] = i
	return x
n = int(input().strip())
s = input().strip()
l = [[] for i in range(52)]
ts = set()
cs = set()
d = createdict()
for i in range(n):
	if s[i] not in ts:
		ts.add(s[i])
	l[d[s[i]]].append(i)
for end in range(n):
	if s[end] not in cs:
		cs.add(s[end])
	if ts & cs == ts:
		break
ans = end + 1
flag = 0
for start in range(1, n):
	c = s[start - 1]
	while l[d[c]]:
		if l[d[c]][0] < start:
			del l[d[c]][0]
			if len(l[d[c]]) == 0:
				flag = 1
		elif start <= l[d[c]][0] <= end:
			break
		else:
			end = l[d[c]][0]
			break
	if flag:
		break
	ans = min(ans, end - start + 1)
print(ans)


n = int(input())
poke = list(input())
(st, cur) = (0, 0)
dct = {}
k = len(set(poke))
while len(dct) < k:
	dct[poke[cur]] = dct.get(poke[cur], 0) + 1
	cur += 1
ans = cur
while dct[poke[st]] > 1:
	dct[poke[st]] -= 1
	st += 1
	ans = min(ans, cur - st)
for i in range(cur, n):
	dct[poke[i]] += 1
	while dct[poke[st]] > 1:
		dct[poke[st]] -= 1
		st += 1
	ans = min(ans, i - st + 1)
print(ans)


import sys
import math
prime = [True for _ in range(1000001)]

def solve():
	(n, e, h, a, b, c) = map(int, input().split())
	ans = 1000000000.0
	for i in range(1, 1000001):
		su = 0
		ntmp = n
		tmp1 = e
		tmp2 = h
		tmp1 -= i
		tmp2 -= i
		if tmp1 < 0 or tmp2 < 0 or i > ntmp:
			break
		ntmp -= i
		su += c * i
		if ntmp == 0:
			ans = min(ans, su)
			continue
		if a <= b:
			if tmp1 // 2 >= ntmp:
				su += int(a * ntmp)
				ntmp -= ntmp
			else:
				su += int(a * (tmp1 // 2))
				ntmp -= tmp1 // 2
				if ntmp <= tmp2 // 3:
					su += int(b * ntmp)
					ntmp -= ntmp
				else:
					su += int(b * (tmp2 // 3))
					ntmp -= tmp2 // 3
		elif tmp2 // 3 >= ntmp:
			su += int(b * ntmp)
			ntmp -= ntmp
		else:
			su += int(b * (tmp2 // 3))
			ntmp -= tmp2 // 3
			if ntmp <= tmp1 // 2:
				su += int(a * ntmp)
				ntmp -= ntmp
			else:
				su += int(a * (tmp1 // 2))
				ntmp -= tmp1 // 2
		if ntmp == 0:
			ans = min(ans, su)
	if ans == 1000000000.0:
		print('-1')
	else:
		print(ans)

def main():
	n = int(input())
	s = input()
	m = {}
	have = {}
	cc = 0
	for c in s:
		if c not in m:
			m[c] = 1
		else:
			m[c] += 1
	ct = len(m)
	l = 0
	ans = 1000000000.0
	for i in range(0, n):
		if s[i] not in have:
			have[s[i]] = 0
			cc += 1
		have[s[i]] += 1
		while l <= i and have[s[l]] > 1:
			have[s[l]] -= 1
			l += 1
		if cc == ct:
			ans = min(ans, i - l + 1)
	print(ans)
main()


import sys

def findIndex(element, list_element):
	try:
		index_element = list_element.index(element)
		return index_element
	except ValueError:
		return None

def customPrint(string):
	return

def sliceNose(string, tokens):
	while len(currentList) > 1 and currentList[0] == currentList[1]:
		customPrint('Flavius sliceNose 2: ' + str(currentList))
		currentList = currentList[1:]
		customPrint('Flavius  sliceNose 2: ' + str(currentList))
line = input()
n = int(line)
line2 = input()
line2 = list(line2)
letters = {}
i = 0
while i < n:
	if line2[i] not in letters:
		letters[line2[i]] = 1
	i = i + 1
noPoke = len(letters.keys())
customPrint(letters)
customPrint('numar pokemoni: ' + str(noPoke))
for letter in letters:
	letters[letter] = 0
min = 0
i = 0
while min < noPoke and i < n:
	if line2[i] in letters:
		if letters[line2[i]] == 0:
			min = min + 1
	letters[line2[i]] = letters[line2[i]] + 1
	i = i + 1
k = 0
rez = i
customPrint('numar caractere parcurse: ' + str(i))
customPrint('Rade Din fata')
while letters[line2[k]] > 1:
	letters[line2[k]] = letters[line2[k]] - 1
	customPrint('letters[line2[k]] : ' + str(line2[k]) + ' k: ' + str(k))
	k = k + 1
customPrint(letters)
rez = rez - k
customPrint('numar caractere parcurse: ' + str(i))
customPrint('numar caractere cu mai multe intrari: ' + str(k))
customPrint('Rezultat: ' + str(rez))
customPrint('Rade Din fata end')
customPrint('Mergi in continuare si rade din fata')
customPrint('i este: ' + str(i))
while i < n:
	customPrint('i este: ' + str(i))
	customPrint('[line2[i]] este: ' + line2[i])
	customPrint('letters[line2[i]] este: ' + str(letters[line2[i]]))
	letters[line2[i]] = letters[line2[i]] + 1
	customPrint('k este: ' + str(k))
	while letters[line2[k]] > 1:
		letters[line2[k]] = letters[line2[k]] - 1
		customPrint('ffff  letters[line2[k]] : ' + str(line2[k]) + ' k: ' + str(k))
		k = k + 1
	rez2 = i - k + 1
	customPrint('rez2 este: ' + str(rez2))
	if rez2 < rez:
		rez = rez2
	i = i + 1
customPrint('end i este ' + str(i))
customPrint('end min val: ' + str(rez))
customPrint(letters)
print(str(rez))


n = int(input())
s = input()
D = dict()
A = set()
for i in range(n):
	if s[i] not in A:
		A.add(s[i])
l = 100001
for i in A:
	D[i] = 0
g = 0
c = '0'
for i in range(n):
	D[s[i]] += 1
	q = 0
	if c == '0':
		for k in A:
			if D[k] == 0:
				break
		else:
			q = 1
	if q == 1 or s[i] == c:
		for k in range(g, i + 1):
			D[s[k]] -= 1
			if D[s[k]] == 0:
				D[s[k]] += 1
				l = min(l, i - k + 1)
				g = max(k, 0)
				c = s[k]
				break
print(l)


import math
q = 1
for _ in range(q):
	n = int(input())
	s = list(input())
	l = [0] * n
	true = list(set(s))
	for i in true:
		cur = -1
		for j in range(n):
			if s[j] == i:
				cur = j
			if cur != -1:
				l[j] = max(l[j], j - cur + 1)
			else:
				l[j] = 10 ** 9
	print(min(l))


from sys import stdin, stdout
from math import gcd, ceil, sqrt
ii1 = lambda : int(stdin.readline().strip())
is1 = lambda : stdin.readline().strip()
iia = lambda : list(map(int, stdin.readline().strip().split()))
isa = lambda : stdin.readline().strip().split()
mod = 1000000007
n = ii1()
s = is1()
num = set(list(s))
arr = [0] * len(num)
count = 0
d = {}
for i in num:
	d[i] = count
	count += 1
temp = set()
res = float('inf')
for i in range(n):
	arr[d[s[i]]] = i
	temp.add(s[i])
	if len(temp) == len(num):
		small = min(arr)
		res = min(res, i - min(arr) + 1)
		temp.remove(s[small])
print(res)


from collections import Counter
n = int(input())
string = input()
chars = set(string)
cnt = Counter()
left = right = 0
while len(cnt) != len(chars):
	cnt[string[right]] += 1
	right += 1
ans = right
right -= 1
while right < n:
	while cnt[string[left]] != 1:
		cnt[string[left]] -= 1
		left += 1
	ans = min(ans, right - left + 1)
	right += 1
	if right < n:
		cnt[string[right]] += 1
print(ans)


n = int(input())
s = input()
exi = [0 for i in range(52)]

def fill(x):
	if x.islower():
		exi[ord(x) - 97] = 1
		return ord(x) - 97
	else:
		exi[ord(x) - 65 + 26] = 1
		return ord(x) - 65 + 26
arr = []
for c in s:
	arr.append(fill(c))
now = [0 for i in range(52)]

def check():
	for i in range(52):
		if exi[i]:
			if exi[i] > now[i]:
				return 0
	return 1
first = 0
now[arr[first]] += 1
if check():
	print(1)
	return
min = n
for i in range(1, n):
	now[arr[i]] += 1
	for j in range(first, i):
		if now[arr[j]] > 1:
			first += 1
			now[arr[j]] -= 1
		else:
			break
	if check():
		leng = i - first + 1
		if min > leng:
			min = leng
print(min)


N = int(input())
A = list(map(ord, list(input())))
S = [0] * 150
for i in range(N):
	S[A[i]] += 1
Pokemon = len(S) - S.count(0)
L = 0
R = N
while R - L > 1:
	M = (R + L) // 2
	l = 0
	r = 0
	S = [0] * 150
	count = 0
	is_ok = False
	while r < l + M:
		if S[A[r]] == 0:
			count += 1
		S[A[r]] += 1
		r += 1
	if count == Pokemon:
		is_ok = True
	while r < N and (not is_ok):
		if S[A[l]] == 1:
			count -= 1
		S[A[l]] -= 1
		if S[A[r]] == 0:
			count += 1
		S[A[r]] += 1
		l += 1
		r += 1
		if count == Pokemon:
			is_ok = True
	if is_ok:
		R = M
	else:
		L = M
print(R)


def idx(x):
	if x > 'Z':
		return ord(x) - ord('a') + 26
	else:
		return ord(x) - ord('A')

def check():
	tmp = 0
	for i in range(52):
		if buf[i]:
			tmp |= 1 << i
	return tmp & syb == syb
n = int(input())
s = input()
syb = 0
c = [[] for i in range(n + 1)]
for i in range(1, n + 1):
	c[i] = [0] * 52
	c[i][idx(s[i - 1])] += 1
	syb |= 1 << idx(s[i - 1])
ans = 1061109567
l = 1
r = 1
buf = c[1]
while r <= n:
	if check():
		while buf[idx(s[l - 1])] > 1:
			buf[idx(s[l - 1])] -= 1
			l += 1
		ans = min(ans, r - l + 1)
	r += 1
	if r <= n:
		buf[idx(s[r - 1])] += 1
print(ans)


def pro():
	n = int(input())
	s = input()
	l = 0
	r = 0
	p = len(set(s))
	m = 100001
	y = len(s)
	k = set(s[0])
	d = dict()
	d[s[0]] = d.get(s[0], 0) + 1
	while r < y:
		if len(k) < p:
			r += 1
			if r < y:
				k.add(s[r])
				d[s[r]] = d.get(s[r], 0) + 1
		else:
			m = min(m, r - l + 1)
			if d[s[l]] == 1:
				d[s[l]] = 0
				k.remove(s[l])
			else:
				d[s[l]] -= 1
			l += 1
	print(m)
pro()


n = int(input())
s = input()
p = set()
for c in s:
	p.add(c)
pc = len(p)
d = dict()
l = 0
r = 0
d[s[r]] = 1
while len(d) < pc:
	r += 1
	if s[r] in d:
		d[s[r]] += 1
	else:
		d[s[r]] = 1
m = r - l
while l + 1 < n:
	d[s[l]] -= 1
	if d[s[l]] == 0:
		del d[s[l]]
	l += 1
	while r + 1 < n and len(d) < pc:
		r += 1
		if s[r] in d:
			d[s[r]] += 1
		else:
			d[s[r]] = 1
	if len(d) < pc:
		break
	m = min(m, r - l)
print(m + 1)


strNum = int(input())
strToSearch = ''
if strNum > 0:
	strToSearch = input()
charSet = set(strToSearch)
charTotalNum = len(charSet)
charCount = 0
charDict = {}
rightBoundary = 0
leftBoundary = 0
ret = strNum
for rightIdx in range(strNum):
	if strToSearch[rightIdx] not in charDict:
		charCount += 1
		charDict[strToSearch[rightIdx]] = 1
	else:
		charDict[strToSearch[rightIdx]] += 1
	if charCount == charTotalNum:
		for leftIdx in range(leftBoundary, rightIdx + 1):
			if charDict[strToSearch[leftIdx]] > 1:
				charDict[strToSearch[leftIdx]] -= 1
			else:
				rightBoundary = rightIdx
				leftBoundary = leftIdx
				ret = min(ret, rightIdx - leftIdx + 1)
				break
print(str(ret))


from sys import stdin
input = lambda : stdin.readline().strip()
from math import ceil, sqrt, factorial, gcd
from collections import deque
n = int(input())
l = list(input())
d = {i: 0 for i in set(l)}
po = len(set(l))
s = set()
a = 0
b = 0
mi = n
for i in range(n):
	s.add(l[i])
	d[l[i]] += 1
	b += 1
	while d[l[a]] > 1:
		d[l[a]] -= 1
		a += 1
	if len(s) == po:
		mi = min(mi, b - a)
print(mi)


from collections import defaultdict
n = int(input())
s = input()
Ans = 1
first = 0
end = 0
Dict = defaultdict(int)
Dict[s[0]] = 1
for index in range(1, n):
	i = s[index]
	if Dict[i] == 0:
		Ans = index - first + 1
		Dict[i] += 1
	else:
		Dict[i] += 1
		while first < index and Dict[s[first]] > 1:
			Dict[s[first]] -= 1
			first += 1
		Ans = min(index - first + 1, Ans)
print(Ans)


n = int(input())
stri = input()
dict = {}
lenght = len(set(stri))
count = 0
j = 0
result = 999999999
for i in range(n):
	if stri[i] not in dict:
		dict[stri[i]] = 0
		count += 1
	dict[stri[i]] += 1
	if count == lenght:
		while dict[stri[j]] > 1:
			dict[stri[j]] -= 1
			j += 1
		result = min(result, i - j + 1)
print(result)


n = int(input())
s = input()
collected = {}
for pokemon in s:
	collected[pokemon] = 0
first = 0
last = 0
collectedCount = 0
while collectedCount < len(collected):
	if collected[s[last]] == 0:
		collectedCount += 1
	collected[s[last]] += 1
	last += 1
min = last
while first < n:
	if collectedCount == len(collected) and last - first < min:
		min = last - first
	collected[s[first]] -= 1
	if collected[s[first]] == 0:
		collectedCount -= 1
	first += 1
	while last < n and collectedCount < len(collected):
		if collected[s[last]] == 0:
			collectedCount += 1
		collected[s[last]] += 1
		last += 1
print(min)


n = int(input())
s = input()
t = set(s)
tt = len(t)
vis = dict()
for a in t:
	vis[a] = 0
(l, r) = (0, -1)
now = 0
ans = n + 100
while l != n:
	while r + 1 != n and now != tt:
		r += 1
		if vis[s[r]] == 0:
			now += 1
		vis[s[r]] += 1
	if now == tt:
		ans = min(ans, r - l + 1)
	vis[s[l]] -= 1
	if vis[s[l]] == 0:
		now -= 1
	l += 1
print(ans)


from collections import defaultdict
di = defaultdict(int)
n = int(input())
s = input()
cn = len(set(s))
co = 0

def ad(a):
	global co, di
	if di[s[a]] == 0:
		co += 1
	di[s[a]] += 1
	return

def re(a):
	global co, di
	di[s[a]] -= 1
	if di[s[a]] == 0:
		co -= 1
	return
ad(0)
po = 0
ma = n
for i in range(n):
	while co < cn:
		if po == n - 1:
			break
		po += 1
		ad(po)
	if co == cn:
		ma = min(ma, po - i + 1)
	re(i)
print(ma)


def count_different_poks(seq, k):
	if len(seq) < k:
		return
	d = dict()
	max_caught = 0
	for i in range(len(seq)):
		d.setdefault(seq[i], 0)
		d[seq[i]] += 1
		if i >= k:
			d[seq[i - k]] -= 1
			if d[seq[i - k]] == 0:
				del d[seq[i - k]]
		max_caught = max(max_caught, len(d))
	return max_caught

def pokemon():
	length = int(input())
	seq = input()
	(low, top) = (0, length)
	all_poks = count_different_poks(seq, length)
	min_flats = length
	while low < top:
		mid = (low + top) // 2
		if count_different_poks(seq, mid) == all_poks:
			min_flats = min(min_flats, mid)
			top = mid
		else:
			low = mid + 1
	assert low == top
	return min_flats
print(pokemon())


n = int(input())
s = input()
abc = 'qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM'
d = {x: 0 for x in abc}
i = 0
j = 0
ans = 100000000
ctd = len(set([i for i in s]))
for _ in s:
	d[s[j]] += 1
	if d[s[j]] == 1:
		ctd -= 1
	while d[s[i]] > 1:
		d[s[i]] -= 1
		i += 1
	j += 1
	if not ctd:
		ans = min(ans, j - i)
print(ans)


n = int(input())
st = input()
l = len(st)
u = list(set(st))
INT_MAX = 1000000000
e = [0 for _ in range(l)]
last = -1
for c in u:
	last = -1
	for (i, s) in enumerate(st):
		if s != c:
			e[i] = INT_MAX
		else:
			last = i
			break
	count = last
	while count < l:
		if st[count] == c:
			last = count
		e[count] = max(e[count], count - last + 1)
		count += 1
print(min(e))


n = int(input())
s = input()
alles = {}
(l, r, c, ans, le) = (0, 0, 0, float('+inf'), len(set(s)))
for i in s:
	if i not in alles:
		alles[i] = 0
		c += 1
	alles[i] += 1
	if c == le:
		while alles[s[l]] > 1:
			alles[s[l]] -= 1
			l += 1
		ans = min(ans, r - l + 1)
	r += 1
print(ans)


from collections import *
(n, s, ans, p1, mem) = (int(input()), input(), float('inf'), 0, defaultdict(int))
(dis, cur) = (len(set(s)), 0)
for i in range(n):
	if mem[s[i]] == 0:
		cur += 1
	mem[s[i]] += 1
	if cur == dis:
		ans = min(ans, i - p1 + 1)
		for j in range(p1, i):
			if mem[s[j]] and cur == dis:
				mem[s[j]] -= 1
				ans = min(ans, i - j + 1)
				if mem[s[j]] == 0:
					cur -= 1
			else:
				break
			p1 += 1
print(ans)


debug = lambda *args: None

def can(s, size, n, u):
	d = {}
	i = 0
	k = size
	for c in s:
		debug(c, k, d)
		if k > 0:
			k -= 1
			d[c] = d.setdefault(c, 0) + 1
		else:
			if s[i - size] in d:
				d[s[i - size]] -= 1
				if d[s[i - size]] == 0:
					del d[s[i - size]]
			d[c] = d.setdefault(c, 0) + 1
		if len(d) == u:
			return True
		i += 1
	debug('cant')
	return False
n = int(input())
s = input()
u = len(set(s))
(lo, hi) = (u, n)
debug(u, n)
while lo < hi:
	mid = lo + int((hi - lo) / 2)
	debug('mid', mid)
	if can(s, mid, n, u):
		hi = mid
	else:
		lo = mid + 1
print(lo)


import os
import sys
from io import BytesIO, IOBase
import heapq as h
from types import GeneratorType
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		import os
		self.os = os
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = self.os.read(self._fd, max(self.os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = self.os.read(self._fd, max(self.os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			self.os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
import time
start_time = time.time()
import collections as col
import math
from functools import reduce

def getInts():
	return [int(s) for s in input().split()]

def getInt():
	return int(input())

def getStrs():
	return [s for s in input().split()]

def getStr():
	return input()

def listStr():
	return list(input())

def solve():
	N = getInt()
	S = getStr()
	targ = len(set(S))
	letter_set = set()
	letter_count = col.defaultdict(int)
	ind = 0
	j = 0
	best = 10 ** 9
	while ind < N:
		letter_set.add(S[j])
		letter_count[S[j]] += 1
		while j + 1 < N and len(letter_set) < targ:
			j += 1
			letter_set.add(S[j])
			letter_count[S[j]] += 1
		while ind < N and letter_count[S[ind]] > 1:
			letter_count[S[ind]] -= 1
			ind += 1
		if len(letter_set) < targ:
			break
		best = min(best, j - ind + 1)
		letter_count[S[ind]] -= 1
		if letter_count[S[ind]] == 0:
			letter_set.remove(S[ind])
		ind += 1
		if j == N - 1:
			break
		j += 1
	return best
print(solve())


n = int(input())
flats = input()
types = set(flats)
counter = {}
menor = n
j = 0
for i in range(n):
	if counter.get(flats[i], 0) == 0:
		counter[flats[i]] = 1
	else:
		counter[flats[i]] += 1
	if len(counter) < len(types):
		continue
	while counter[flats[j]] > 1:
		counter[flats[j]] -= 1
		j += 1
	menor = min(menor, i - j + 1)
	if menor == len(types):
		break
print(menor)


n = int(input())
s = str(input())
m = {}
for i in s:
	m[i] = 0
d = len(m.keys()) - 1
l = 0
m[s[0]] = 1
answer = n
for i in range(1, len(s)):
	if m[s[i]] == 0:
		m[s[i]] = 1
		d -= 1
	else:
		m[s[i]] += 1
	if d == 0:
		answer = min(answer, i - l + 1)
		for j in range(l, i + 1):
			if m[s[j]] == 1:
				l = j
				answer = min(answer, i - l + 1)
				break
			m[s[j]] -= 1
		else:
			l = i
print(answer)


import sys
import bisect
from math import ceil, floor
RI = lambda : [int(x) for x in sys.stdin.readline().split()]
ri = lambda : sys.stdin.readline().strip()
mod = 10 ** 9 + 7
n = int(ri())
st = ri()
l = 1
r = n
tot = len(set(st))

def solve(k):
	dic = {}
	for i in range(0, k):
		if st[i] not in dic:
			dic[st[i]] = 1
		else:
			dic[st[i]] += 1
	if len(dic) == tot:
		return True
	for i in range(k, len(st)):
		dic[st[i - k]] -= 1
		if dic[st[i - k]] == 0:
			dic.pop(st[i - k])
		if st[i] not in dic:
			dic[st[i]] = 1
		else:
			dic[st[i]] += 1
		if len(dic) == tot:
			return True
	return False
ans = n
while l <= r:
	mid = (l + r) // 2
	if solve(mid):
		r = mid - 1
		ans = min(mid, ans)
	else:
		l = mid + 1
print(ans)


n = int(input())
l = [0] * n
v = []
p = input()
for i in p:
	if i in v:
		continue
	v.append(i)
for i in v:
	last = -1
	for j in range(n):
		if p[j] == i:
			last = j
		if last != -1:
			l[j] = max(l[j], j - last + 1)
		else:
			l[j] = 10 ** 9
print(min(l))


def main():
	n = int(input())
	s = input()
	u_set = set()
	for i in s:
		u_set.add(i)
	u_cnt = len(u_set)
	d = {}
	j = 0
	ans = 10 ** 9
	for i in range(n):
		while len(d.keys()) < u_cnt and j < n:
			d[s[j]] = d.get(s[j], 0) + 1
			j += 1
		if len(d.keys()) == u_cnt:
			if j - i < ans:
				ans = j - i
		elif j == n:
			break
		d[s[i]] -= 1
		if d[s[i]] == 0:
			del d[s[i]]
	print(ans)
main()


n = int(input())
s = input()
u = set(s)
dp = [0] * n
for i in u:
	lastI = -1
	for j in range(n):
		if s[j] == i:
			lastI = j
		if lastI == -1:
			dp[j] = n
		else:
			dp[j] = max(dp[j], j - lastI + 1)
print(min(dp))


def indice(char):
	n = ord(char)
	if n < 91:
		return n - 65
	return n - 71
(n, s) = (int(input()), input())
k = len(set(s))
(i, j) = (0, 0)
actual = 0
minimo = n
lista = [0] * 52
while True:
	if actual == k:
		if j - i < minimo:
			minimo = j - i
		m = indice(s[i])
		if lista[m] == 1:
			actual -= 1
		lista[m] -= 1
		i += 1
	elif j < n:
		j += 1
		m = indice(s[j - 1])
		if lista[m] == 0:
			actual += 1
		lista[m] += 1
	else:
		break
print(minimo)


n = int(input())
s = input()
q = len(set(s))
d = {}
count = 0
best = 999999999
j = 0
for i in range(n):
	if s[i] not in d:
		d[s[i]] = 0
		count += 1
	d[s[i]] += 1
	if count == q:
		while d[s[j]] > 1:
			d[s[j]] -= 1
			j += 1
		best = min(best, i - j + 1)
print(best)


n = int(input())
flats = input()
ans = n
count = {}
for c in flats:
	count[c] = 0
all_char = len(count)
j = 0
exist = 0
for i in range(n):
	while j < n and exist < all_char:
		if count[flats[j]] == 0:
			exist += 1
		count[flats[j]] += 1
		j += 1
	if exist == all_char:
		ans = min(ans, j - i)
	else:
		break
	count[flats[i]] -= 1
	if count[flats[i]] == 0:
		exist -= 1
print(ans)


n = int(input())
s = input()
types = len(set(s))
d = dict()
c = 0
j = 0
ans = 10 ** 10
for i in range(n):
	if s[i] not in d:
		d[s[i]] = 0
		c += 1
	d[s[i]] += 1
	if c == types:
		while d[s[j]] > 1:
			d[s[j]] -= 1
			j += 1
		ans = min(ans, i - j + 1)
print(ans)


def pokemon():
	length = int(input())
	seq = input()
	tmp = dict()
	if length == 0:
		return 0
	for i in range(length):
		tmp[seq[i]] = None
	(max_poks, min_flats) = (len(tmp), length)
	d = dict()
	(i, j) = (0, -1)
	while j < length - 1:
		if len(d) < max_poks:
			j += 1
			d.setdefault(seq[j], 0)
			d[seq[j]] += 1
		else:
			min_flats = min(min_flats, j - i + 1)
			d[seq[i]] -= 1
			if d[seq[i]] == 0:
				del d[seq[i]]
			i += 1
	while len(d) == max_poks:
		min_flats = min(min_flats, j - i + 1)
		d[seq[i]] -= 1
		if d[seq[i]] == 0:
			del d[seq[i]]
		i += 1
	return min_flats
print(pokemon())


def check(x):
	num = {}
	d = {}
	for i in st:
		num[i] = 0
		d[i] = 1
	m = len(num.values())
	for j in range(x):
		num[st[j]] += 1
		d[st[j]] = 0
	i = x
	j = 0
	if sum(d.values()) == 0:
		return True
	while i < n:
		num[st[j]] -= 1
		if num[st[j]] <= 0:
			d[st[j]] = 1
		num[st[i]] += 1
		d[st[i]] = 0
		if sum(d.values()) == 0:
			return True
		i += 1
		j += 1
	return False

def binary(p, q):
	if p >= q:
		return p
	mid = (p + q) // 2
	if check(mid):
		return binary(p, mid - 1)
	else:
		return binary(mid + 1, q)
n = int(input())
st = input()
ans = binary(1, n)
print(ans if check(ans) else ans + 1)


n = int(input())
array = input()
spisok = dict()
maxim = len(set(array))
ans = 100002
kol = 0
ukaz1 = 0
ukaz2 = 0
for ukaz1 in range(n):
	if array[ukaz1] not in spisok:
		kol += 1
		spisok[array[ukaz1]] = 0
	spisok[array[ukaz1]] += 1
	if kol == maxim:
		while spisok[array[ukaz2]] > 1:
			spisok[array[ukaz2]] -= 1
			ukaz2 += 1
		ans = min(ans, ukaz1 - ukaz2 + 1)
print(ans)


N = int(input())
flats = input()
pokemons = {}
for i in 'qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM':
	pokemons[i] = 0
for i in flats:
	pokemons[i] += 1
idx = N - 1
while idx >= 0:
	if pokemons[flats[idx]] == 1:
		break
	pokemons[flats[idx]] -= 1
	idx -= 1
right = idx
left = 0
ans = right - left + 1
while True:
	while left < right:
		if pokemons[flats[left]] == 1:
			break
		pokemons[flats[left]] -= 1
		left += 1
	if right - left + 1 < ans:
		ans = right - left + 1
	right += 1
	if right < N:
		pokemons[flats[right]] += 1
	else:
		break
print(ans)


n = int(input())
s = input()
d = set()
p = {}
D = 0
for i in s:
	if i not in d:
		d.add(i)
		p[i] = D
		D += 1

def calc(k):
	P = [0] * D
	num = 0
	for i in range(n):
		if i >= k:
			P[p[s[i - k]]] -= 1
			if P[p[s[i - k]]] == 0:
				num -= 1
		if P[p[s[i]]] == 0:
			P[p[s[i]]] += 1
			num += 1
			if num == D:
				return True
		else:
			P[p[s[i]]] += 1
	return False
(l, r) = (0, n)
while r - l > 1:
	mid = (l + r) // 2
	if calc(mid):
		r = mid
	else:
		l = mid
print(r)


n = int(input())
s = input()
se = set()
d = dict()
k = 0
for i in s:
	if i not in se:
		se.add(i)
		k += 1
		d[i] = 0
queue = []
mi = 100000000000
cnt = 0
for i in range(n):
	if d[s[i]] == 0:
		cnt += 1
	d[s[i]] += 1
	queue.append(i)
	while cnt == k:
		temp = i - queue[0] + 1
		mi = min(mi, temp)
		x = queue.pop(0)
		d[s[x]] -= 1
		if d[s[x]] == 0:
			cnt -= 1
print(mi)


import os
import sys
from io import BytesIO, IOBase
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
import math
import bisect
mod = 998244353
from collections import Counter
import bisect
from heapq import *
from collections import defaultdict, deque

def okay(x, y):
	if x < 0 or x >= 3:
		return False
	if y < n and mat[x][y] != '.':
		return False
	if y + 1 < n and mat[x][y + 1] != '.':
		return False
	if y + 2 < n and mat[x][y + 2] != '.':
		return False
	return True
from collections import defaultdict
n = int(input())
s = input()
ans = 10 ** 9
le = len(set(s))
var = set()
l = 0
j = 0
cnt = 0
d = defaultdict(int)
while l < n and j < n:
	var.add(s[j])
	d[s[j]] += 1
	while j + 1 < n and len(var) < le:
		j += 1
		var.add(s[j])
		d[s[j]] += 1
	while l < n and d[s[l]] > 1:
		d[s[l]] -= 1
		if d[s[l]] == 0:
			var.remove(s[l])
		l += 1
	if len(var) < le:
		break
	ans = min(ans, j - l + 1)
	d[s[l]] -= 1
	if d[s[l]] == 0:
		var.remove(s[l])
	l += 1
	j += 1
print(ans)


n = int(input())
s = input()
if n == 1 or len(set(s)) == 1:
	print(1)
else:
	left = 0
	right = 1
	check = set(s)
	temp = set([s[0], s[1]])
	m = 10 ** 10
	d = {}
	d[s[0]] = 1
	if s[1] in d:
		d[s[1]] += 1
	else:
		d[s[1]] = 1
	while right > left:
		if temp == check:
			m = min(m, abs(right - left + 1))
			if d[s[left]] == 1:
				temp.remove(s[left])
			d[s[left]] -= 1
			left += 1
		else:
			if right == n - 1:
				break
			right += 1
			if s[right] not in d or d[s[right]] == 0:
				d[s[right]] = 1
				temp.add(s[right])
			else:
				d[s[right]] += 1
	print(m)


n = int(input())
s = input()

def main(n, s):
	k = set()
	for i in range(n):
		k.add(s[i])
	v = len(k)
	h = dict()
	for i in k:
		h[i] = 0
	l = 0
	r = n
	while l + 1 < r:
		m = (l + r) // 2
		f = False
		for i in h:
			h[i] = 0
		x = 0
		for i in range(m):
			h[s[i]] += 1
			if h[s[i]] == 1:
				x += 1
		if x == v:
			f = True
		else:
			for i in range(m, n):
				h[s[i - m]] -= 1
				if h[s[i - m]] == 0:
					x -= 1
				h[s[i]] += 1
				if h[s[i]] == 1:
					x += 1
				if x == v:
					f = True
					break
		if f:
			r = m
		else:
			l = m
	print(r)
main(n, s)


apartments_nr = int(input())
idx___pockemon_type = list(input())
types_nr = len(set(idx___pockemon_type))
idx___mandatory = [-1 for x in range(apartments_nr)]
type___last_met = {}
for type_ in set(idx___pockemon_type):
	type___last_met[type_] = -1
type__idx___prev_idx = {}
for idx in range(apartments_nr):
	type_ = idx___pockemon_type[idx]
	type__idx___prev_idx[type_, idx] = type___last_met[type_]
	type___last_met[type_] = idx
left_idx = 0
right_idx = 1
idx___mandatory[0] = 1
ans = apartments_nr
curr_catched = 1
while right_idx < apartments_nr:
	idx___mandatory[right_idx] = 1
	right_type = idx___pockemon_type[right_idx]
	prev_idx = type__idx___prev_idx[right_type, right_idx]
	if prev_idx != -1:
		idx___mandatory[prev_idx] = 0
	else:
		curr_catched += 1
	while idx___mandatory[left_idx] == 0:
		left_idx += 1
	right_idx += 1
	if curr_catched == types_nr:
		curr_ans = right_idx - left_idx
		ans = min(ans, curr_ans)
print(ans)


import sys
LI = lambda : list(map(int, sys.stdin.readline().split()))
MI = lambda : map(int, sys.stdin.readline().split())
SI = lambda : sys.stdin.readline().strip('\n')
II = lambda : int(sys.stdin.readline())
n = II()
s = SI()
c = set(s)
ln = [0] * n
for d in c:
	last = -1
	for (i, v) in enumerate(s):
		if v == d:
			last = i
		if last == -1:
			ln[i] = int(1000000000.0)
		else:
			ln[i] = max(ln[i], i - last + 1)
print(min(ln))


n = int(input())
s = input()
a = set(s)
N = len(a)
ans = 100000000
a = set()
b = dict()
l = 0
r = 0
while r != n:
	if len(a) == N - 1 and s[l] not in a:
		ans = min(ans, r - l + 1)
	if s[l] in a:
		l += 1
		b[s[l]] -= 1
		if b[s[l]] == 0:
			a.remove(s[l])
	else:
		r += 1
		if r != n:
			if s[r] not in b.keys():
				b[s[r]] = 1
			else:
				b[s[r]] += 1
			a.add(s[r])
else:
	if len(a) == N:
		while len(a) == N:
			a.remove(s[l])
			l += 1
		else:
			ans = min(ans, r - l)
print(ans)


def bs(l, h):
	while l < h:
		m = (l + h) // 2
		if gf(m):
			h = m
		else:
			l = m + 1
	return l

def gf(x):
	d = {}
	for i in range(x):
		if s[i] in d:
			d[s[i]] += 1
		else:
			d[s[i]] = 1
	if len(d) == len(u):
		return 1
	for i in range(x, n):
		if s[i] in d:
			d[s[i]] += 1
		else:
			d[s[i]] = 1
		d[s[i - x]] -= 1
		if not d[s[i - x]]:
			del d[s[i - x]]
		if len(d) == len(u):
			return 1
	return 0
n = int(input())
s = input()
u = set([*s])
print(bs(1, n))


n = int(input())
s = input()
basic_set = set(s)
d = dict()
for item in basic_set:
	d[item] = 0
left = 0
right = 0
l = 0
min_l = 100001
i = 0
while left < n:
	while 0 in d.values() and right < n:
		d[s[right]] += 1
		right += 1
	if 0 not in d.values():
		l = right - left
		if l < min_l:
			min_l = l
		d[s[left]] -= 1
	left += 1
print(min_l)


from collections import defaultdict
n = int(input())
s = input()
l = 0
d = defaultdict(int)
e = defaultdict(int)
se = set(list(s))
a = []
j = 0
for i in range(n):
	d[s[i]] += 1
	if s[i] not in e:
		l += 1
		e[s[i]] = 1
	if l == len(se):
		while d[s[j]] > 1:
			d[s[j]] -= 1
			j += 1
		a.append(i - j + 1)
print(min(a))


n = int(input())
l = list(input())
k = len(set(l))
count = {}
a = n
i = j = 0
while j < n:
	while len(count) < k and j < n:
		lj = l[j]
		if lj not in count:
			count[lj] = 0
		count[lj] += 1
		j += 1
	while len(count) == k:
		if a > j - i:
			a = j - i
		li = l[i]
		count[li] -= 1
		if count[li] == 0:
			del count[li]
		i += 1
print(a)


n = int(input())
s = input()
k = len(set(s))
d = {}
for i in set(s):
	d[i] = 0
d[s[0]] = 1
ans = 10 ** 5
x = 0
y = 1
b = True
m = set()
m.add(s[0])
while b:
	if d[s[x]] > 1:
		d[s[x]] -= 1
		x += 1
	elif y == n:
		b = False
	else:
		d[s[y]] += 1
		m.add(s[y])
		y += 1
	if len(m) == k:
		ans = min(y - x, ans)
print(ans)


from __future__ import print_function
from collections import Counter, OrderedDict
from itertools import permutations as perm
from fractions import Fraction
from collections import deque
from sys import stdin
from bisect import *
from heapq import *
g = lambda : stdin.readline().strip()
gl = lambda : g().split()
gil = lambda : [int(var) for var in gl()]
gfl = lambda : [float(var) for var in gl()]
gcl = lambda : list(g())
gbs = lambda : [int(var) for var in g()]
mod = int(1000000000.0) + 7
inf = float('inf')
(n,) = gil()
s = g()
ans = n
rqd = len(set(s))

def isPos(x):
	base = Counter(s[:x])
	if len(base) == rqd:
		return True
	for i in range(x, n):
		if base[s[i - x]] == 1:
			del base[s[i - x]]
		else:
			base[s[i - x]] -= 1
		base[s[i]] = base.get(s[i], 0) + 1
		if len(base) == rqd:
			return True
	return False
(l, r) = (rqd, n)
while l <= r:
	mid = (l + r) // 2
	if isPos(mid):
		r = mid - 1
		ans = mid
	else:
		l = mid + 1
print(ans)


n = int(input())
s = input()
letters = [0] * 123
dp = [0] * n
for i in range(n):
	if letters[ord(s[i])] != 0:
		continue
	last = -1
	for ind in range(n):
		if s[ind] == s[i]:
			last = ind
		dp[ind] = 100001 if last == -1 else max(dp[ind], ind - last + 1)
	letters[ord(s[i])] = 1
print(min(dp))


from math import *
from bisect import *
from collections import Counter, defaultdict, deque
I = lambda : int(input())
M = lambda : map(int, input().split())
LI = lambda : list(map(int, input().split()))
n = I()
s = input()
b = len(Counter(s))
ans = n
d = defaultdict(int)
for i in range(n):
	if d[s[i]] == 0:
		d[s[i]] = i + 1
		b -= 1
	else:
		d[s[i]] = i + 1
	if b <= 0:
		ans = min(ans, max(d.values()) + 1 - min(d.values()))
print(ans)


n = int(input())
s = input()
dd = len(set([i for i in s]))
dic = {}
j = 0
(ss, cc) = (n, 0)
for i in range(0, len(s)):
	if s[i] not in dic:
		cc += 1
		dic[s[i]] = 1
	else:
		dic[s[i]] += 1
	if cc == dd:
		while dic[s[j]] > 1:
			dic[s[j]] -= 1
			j += 1
		ss = min(ss, i - j + 1)
print(ss)


import sys, os
from io import BytesIO, IOBase
from math import floor, gcd, fabs, factorial, fmod, sqrt, inf, log
from collections import defaultdict as dd, deque
from heapq import merge, heapify, heappop, heappush, nsmallest
from bisect import bisect_left as bl, bisect_right as br, bisect
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(stdin, stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
mod = pow(10, 9) + 7
mod2 = 998244353

def inp():
	return stdin.readline().strip()

def iinp():
	return int(inp())

def out(var, end='\n'):
	stdout.write(str(var) + '\n')

def outa(*var, end='\n'):
	stdout.write(' '.join(map(str, var)) + end)

def lmp():
	return list(mp())

def mp():
	return map(int, inp().split())

def smp():
	return map(str, inp().split())

def l1d(n, val=0):
	return [val for i in range(n)]

def l2d(n, m, val=0):
	return [l1d(m, val) for j in range(n)]

def remadd(x, y):
	return 1 if x % y else 0

def ceil(a, b):
	return (a + b - 1) // b
S1 = 'abcdefghijklmnopqrstuvwxyz'
S2 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'

def isprime(x):
	if x <= 1:
		return False
	if x in (2, 3):
		return True
	if x % 2 == 0:
		return False
	for i in range(3, int(sqrt(x)) + 1, 2):
		if x % i == 0:
			return False
	return True
n = iinp()
s = inp()
types = set(s)
xl = ''.join(types)
ind = dd(int)
for i in range(len(xl)):
	ind[xl[i]] = i
cnt = l1d(len(xl))
i = 0
j = 0
mn = inf
while j < n:
	while j < n and min(cnt) == 0:
		cnt[ind[s[j]]] += 1
		j += 1
	while i < n and min(cnt) != 0:
		cnt[ind[s[i]]] -= 1
		i += 1
	mn = min(mn, j - i + 1)
print(mn)


n = int(input())
s = input()
types = set(list(s))
current_d = {}
i = j = 0
mn = len(s)
check = False
while j < n:
	while j < n and set(current_d) != types:
		current_d[s[j]] = current_d.get(s[j], 0) + 1
		j += 1
	while set(current_d) == types:
		check = True
		current_d[s[i]] -= 1
		if not current_d[s[i]]:
			del current_d[s[i]]
		i += 1
	if check:
		mn = min(j - i + 1, mn)
print(mn)


n = int(input())
s = input()
l = len(set(s))
dic = {}
c = j = 0
ans = 10 ** 6
for i in range(n):
	if s[i] not in dic:
		dic[s[i]] = 0
		c += 1
	dic[s[i]] += 1
	if c == l:
		while dic[s[j]] > 1:
			dic[s[j]] -= 1
			j += 1
		ans = min(ans, i - j + 1)
print(ans)


import sys
input = sys.stdin.readline
from collections import defaultdict

def judge(x):
	d = defaultdict(int)
	cnt = 0
	for i in range(x):
		if d[S[i]] == 0:
			cnt += 1
		d[S[i]] += 1
	if cnt == c:
		return True
	for i in range(x, n):
		if d[S[i - x]] == 1:
			cnt -= 1
		d[S[i - x]] -= 1
		if d[S[i]] == 0:
			cnt += 1
		d[S[i]] += 1
		if cnt == c:
			return True
	return False

def binary_search():
	(l, r) = (1, n)
	while l <= r:
		mid = (l + r) // 2
		if judge(mid):
			r = mid - 1
		else:
			l = mid + 1
	return l
n = int(input())
S = input()[:-1]
c = len(set(list(S)))
print(binary_search())


import sys, os, io

def rs():
	return sys.stdin.readline().rstrip()

def ri():
	return int(sys.stdin.readline())

def ria():
	return list(map(int, sys.stdin.readline().split()))

def ws(s):
	sys.stdout.write(s + '\n')

def wi(n):
	sys.stdout.write(str(n) + '\n')

def wia(a):
	sys.stdout.write(' '.join([str(x) for x in a]) + '\n')
import math, datetime, functools, itertools, operator, bisect, fractions, statistics
from collections import deque, defaultdict, OrderedDict, Counter
from fractions import Fraction
from decimal import Decimal
from sys import stdout
from heapq import heappush, heappop, heapify, _heapify_max, _heappop_max, nsmallest, nlargest
sys.setrecursionlimit(111111)
INF = 99999999999999999999999999999999

class SortedList:

	def __init__(self, iterable=[], _load=200):
		values = sorted(iterable)
		self._len = _len = len(values)
		self._load = _load
		self._lists = _lists = [values[i:i + _load] for i in range(0, _len, _load)]
		self._list_lens = [len(_list) for _list in _lists]
		self._mins = [_list[0] for _list in _lists]
		self._fen_tree = []
		self._rebuild = True

	def _fen_build(self):
		self._fen_tree[:] = self._list_lens
		_fen_tree = self._fen_tree
		for i in range(len(_fen_tree)):
			if i | i + 1 < len(_fen_tree):
				_fen_tree[i | i + 1] += _fen_tree[i]
		self._rebuild = False

	def _fen_update(self, index, value):
		if not self._rebuild:
			_fen_tree = self._fen_tree
			while index < len(_fen_tree):
				_fen_tree[index] += value
				index |= index + 1

	def _fen_query(self, end):
		if self._rebuild:
			self._fen_build()
		_fen_tree = self._fen_tree
		x = 0
		while end:
			x += _fen_tree[end - 1]
			end &= end - 1
		return x

	def _fen_findkth(self, k):
		_list_lens = self._list_lens
		if k < _list_lens[0]:
			return (0, k)
		if k >= self._len - _list_lens[-1]:
			return (len(_list_lens) - 1, k + _list_lens[-1] - self._len)
		if self._rebuild:
			self._fen_build()
		_fen_tree = self._fen_tree
		idx = -1
		for d in reversed(range(len(_fen_tree).bit_length())):
			right_idx = idx + (1 << d)
			if right_idx < len(_fen_tree) and k >= _fen_tree[right_idx]:
				idx = right_idx
				k -= _fen_tree[idx]
		return (idx + 1, k)

	def _delete(self, pos, idx):
		_lists = self._lists
		_mins = self._mins
		_list_lens = self._list_lens
		self._len -= 1
		self._fen_update(pos, -1)
		del _lists[pos][idx]
		_list_lens[pos] -= 1
		if _list_lens[pos]:
			_mins[pos] = _lists[pos][0]
		else:
			del _lists[pos]
			del _list_lens[pos]
			del _mins[pos]
			self._rebuild = True

	def _loc_left(self, value):
		if not self._len:
			return (0, 0)
		_lists = self._lists
		_mins = self._mins
		(lo, pos) = (-1, len(_lists) - 1)
		while lo + 1 < pos:
			mi = lo + pos >> 1
			if value <= _mins[mi]:
				pos = mi
			else:
				lo = mi
		if pos and value <= _lists[pos - 1][-1]:
			pos -= 1
		_list = _lists[pos]
		(lo, idx) = (-1, len(_list))
		while lo + 1 < idx:
			mi = lo + idx >> 1
			if value <= _list[mi]:
				idx = mi
			else:
				lo = mi
		return (pos, idx)

	def _loc_right(self, value):
		if not self._len:
			return (0, 0)
		_lists = self._lists
		_mins = self._mins
		(pos, hi) = (0, len(_lists))
		while pos + 1 < hi:
			mi = pos + hi >> 1
			if value < _mins[mi]:
				hi = mi
			else:
				pos = mi
		_list = _lists[pos]
		(lo, idx) = (-1, len(_list))
		while lo + 1 < idx:
			mi = lo + idx >> 1
			if value < _list[mi]:
				idx = mi
			else:
				lo = mi
		return (pos, idx)

	def add(self, value):
		_load = self._load
		_lists = self._lists
		_mins = self._mins
		_list_lens = self._list_lens
		self._len += 1
		if _lists:
			(pos, idx) = self._loc_right(value)
			self._fen_update(pos, 1)
			_list = _lists[pos]
			_list.insert(idx, value)
			_list_lens[pos] += 1
			_mins[pos] = _list[0]
			if _load + _load < len(_list):
				_lists.insert(pos + 1, _list[_load:])
				_list_lens.insert(pos + 1, len(_list) - _load)
				_mins.insert(pos + 1, _list[_load])
				_list_lens[pos] = _load
				del _list[_load:]
				self._rebuild = True
		else:
			_lists.append([value])
			_mins.append(value)
			_list_lens.append(1)
			self._rebuild = True

	def discard(self, value):
		_lists = self._lists
		if _lists:
			(pos, idx) = self._loc_right(value)
			if idx and _lists[pos][idx - 1] == value:
				self._delete(pos, idx - 1)

	def remove(self, value):
		_len = self._len
		self.discard(value)
		if _len == self._len:
			raise ValueError('{0!r} not in list'.format(value))

	def pop(self, index=-1):
		(pos, idx) = self._fen_findkth(self._len + index if index < 0 else index)
		value = self._lists[pos][idx]
		self._delete(pos, idx)
		return value

	def bisect_left(self, value):
		(pos, idx) = self._loc_left(value)
		return self._fen_query(pos) + idx

	def bisect_right(self, value):
		(pos, idx) = self._loc_right(value)
		return self._fen_query(pos) + idx

	def count(self, value):
		return self.bisect_right(value) - self.bisect_left(value)

	def __len__(self):
		return self._len

	def __getitem__(self, index):
		(pos, idx) = self._fen_findkth(self._len + index if index < 0 else index)
		return self._lists[pos][idx]

	def __delitem__(self, index):
		(pos, idx) = self._fen_findkth(self._len + index if index < 0 else index)
		self._delete(pos, idx)

	def __contains__(self, value):
		_lists = self._lists
		if _lists:
			(pos, idx) = self._loc_left(value)
			return idx < len(_lists[pos]) and _lists[pos][idx] == value
		return False

	def __iter__(self):
		return (value for _list in self._lists for value in _list)

	def __reversed__(self):
		return (value for _list in reversed(self._lists) for value in reversed(_list))

	def __repr__(self):
		return 'SortedList({0})'.format(list(self))

def main():
	mod = 1000000007
	starttime = datetime.datetime.now()
	if os.path.exists('input.txt'):
		sys.stdin = open('input.txt', 'r')
		sys.stdout = open('output.txt', 'w')
	tc = 1
	for _ in range(tc):
		n = ri()
		s = rs()
		d = {}
		for i in range(n):
			d[s[i]] = 1
		l = 0
		r = 0
		td = {}
		ans = INF
		while l <= r and r < n:
			while len(td) != len(d):
				if r == n:
					print(ans)
					exit()
				if s[r] in td:
					td[s[r]] += 1
				else:
					td[s[r]] = 1
				r += 1
			if len(td) == len(d):
				r -= 1
				ans = min(ans, r - l + 1)
			while l <= r:
				td[s[l]] -= 1
				if td[s[l]] == 0:
					del td[s[l]]
					ans = min(ans, r - l + 1)
					l += 1
					break
				l += 1
			r += 1
		wi(ans)
	endtime = datetime.datetime.now()
	time = (endtime - starttime).total_seconds() * 1000
	if os.path.exists('input.txt'):
		print('Time:', time, 'ms')

class FastReader(io.IOBase):
	newlines = 0

	def __init__(self, fd, chunk_size=1024 * 8):
		self._fd = fd
		self._chunk_size = chunk_size
		self.buffer = io.BytesIO()

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, self._chunk_size))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self, size=-1):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, self._chunk_size if size == -1 else size))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

class FastWriter(io.IOBase):

	def __init__(self, fd):
		self._fd = fd
		self.buffer = io.BytesIO()
		self.write = self.buffer.write

	def flush(self):
		os.write(self._fd, self.buffer.getvalue())
		(self.buffer.truncate(0), self.buffer.seek(0))

class FastStdin(io.IOBase):

	def __init__(self, fd=0):
		self.buffer = FastReader(fd)
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')

class FastStdout(io.IOBase):

	def __init__(self, fd=1):
		self.buffer = FastWriter(fd)
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.flush = self.buffer.flush
sys.stdin = FastStdin()
sys.stdout = FastStdout()
main()


from collections import defaultdict
n = int(input())
s = [i for i in input()]
ps = list(set(s))
d = defaultdict(list)
dist = 99999999999999999
acc = []

def search(a, t):
	l = 0
	r = len(a) - 1
	while r - l >= 0:
		mid = (l + r) // 2
		if a[mid] == t:
			return mid
		if a[mid] < t:
			l = mid + 1
		if a[mid] > t:
			r = mid - 1
	return mid
for i in range(n):
	if len(d) == len(ps):
		dist = min(dist, acc[-1] - acc[0])
		e = d[s[i]].pop(0)
		acc.pop(search(acc, e))
	elif len(d[s[i]]) > 0:
		e = d[s[i]].pop(0)
		acc.pop(search(acc, e))
	d[s[i]].append(i)
	acc.append(i)
dist = min(dist, acc[-1] - acc[0])
print(dist + 1)


def solve():
	add = sum
	length = len
	order = sorted
	n = int(input())
	arr = list(input())
	unique = order(list(set(arr)))
	left_index = 0
	right_index = len(unique)
	lowest = length(arr)
	queue = [x for x in arr[left_index:right_index]]
	letter_freq = {}
	for i in queue:
		if i not in letter_freq:
			letter_freq[i] = 1
		else:
			letter_freq[i] += 1
	current = letter_freq[queue[0]]
	while current > 1:
		letter = queue.pop(0)
		letter_freq[letter] -= 1
		current = letter_freq[queue[0]]
		left_index += 1
	while right_index < length(arr):
		if order(letter_freq.keys()) == unique and add(letter_freq.values()) < lowest:
			lowest = add(letter_freq.values())
			if lowest == length(unique):
				print(lowest)
				return
		queue.append(arr[right_index])
		if arr[right_index] not in letter_freq:
			letter_freq[queue[-1]] = 1
		else:
			letter_freq[queue[-1]] += 1
		current = letter_freq[queue[0]]
		while current > 1:
			letter = queue.pop(0)
			letter_freq[letter] -= 1
			current = letter_freq[queue[0]]
			left_index += 1
		right_index += 1
	current = letter_freq[queue[0]]
	while current > 1:
		letter = queue.pop(0)
		letter_freq[letter] -= 1
		current = letter_freq[queue[0]]
		left_index += 1
	current = letter_freq[queue[-1]]
	while current > 1:
		letter = queue.pop(length(queue) - 1)
		letter_freq[letter] -= 1
		current = letter_freq[queue[-1]]
		right_index -= 1
	if add(letter_freq.values()) < lowest:
		print(add(letter_freq.values()))
	else:
		print(lowest)
solve()


n = int(input())
pokemons = input().strip()
types = set(pokemons)
i = 0
j = 0
contained = {pokemons[j]: 1}

def add_pokemon():
	global j
	j += 1
	p = pokemons[j]
	contained.setdefault(p, 0)
	contained[p] += 1

def remove_pokemon():
	global i
	i += 1
	p = pokemons[i - 1]
	contained[p] -= 1
	if contained[p] == 0:
		del contained[p]
while len(contained) < len(types):
	add_pokemon()
while len(contained) == len(types):
	remove_pokemon()
best = (i, j)
while j < len(pokemons) - 1:
	add_pokemon()
	remove_pokemon()
	had_all = len(contained) == len(types)
	while len(contained) == len(types):
		remove_pokemon()
	if had_all and j - i < best[1] - best[0]:
		best = (i, j)
print(best[1] - best[0] + 2)


from collections import Counter
n = int(input())
s = input()
letters = Counter(s)
dist_len = len(letters)
l = 0
r = -1
win_letters = {}
res = n
while r < n:
	if len(win_letters) == dist_len:
		res = min(res, r - l + 1)
		win_letters[s[l]] -= 1
		if win_letters[s[l]] == 0:
			del win_letters[s[l]]
		l += 1
	else:
		r += 1
		if r == n:
			break
		if s[r] in win_letters:
			win_letters[s[r]] += 1
		else:
			win_letters[s[r]] = 1
print(res)


n = input()
houses = input()
houses = houses[0:int(n)]
tmp = []
tmpCount = 0
for a in houses:
	if a not in tmp:
		tmpCount = tmpCount + 1
		tmp.append(a)
ddd = {}
totalTypes = 0

def addPok(c):
	global totalTypes
	if c not in ddd:
		totalTypes = totalTypes + 1
		ddd[c] = 1
	else:
		if ddd[c] == 0:
			totalTypes = totalTypes + 1
		ddd[c] = ddd[c] + 1

def peekRemove(c):
	if c in ddd:
		if ddd[c] > 1:
			return True
		else:
			return False

def removePok(c):
	if c in ddd:
		ddd[c] = ddd[c] - 1
		if ddd[c] == 0:
			totalTypes = totalTypes - 1
h = -1
t = -1
minAns = None
t = t + 1
while t < len(houses):
	addPok(houses[t])
	if totalTypes == tmpCount:
		while h < t and peekRemove(houses[h + 1]):
			removePok(houses[h + 1])
			h = h + 1
		if minAns == None or minAns > t - h:
			minAns = t - h
	t = t + 1
print(minAns)


n = int(input())
s = input()
l = len(set(s))
dic = {}
(left, right) = (0, 0)
mini = 10 ** 9
size = 0
for left in range(n):
	while right < n and size < l:
		if s[right] not in dic:
			dic[s[right]] = 1
		else:
			dic[s[right]] += 1
		if dic[s[right]] == 1:
			size += 1
		right += 1
	if size == l:
		mini = min(mini, right - left)
	dic[s[left]] -= 1
	if dic[s[left]] == 0:
		size -= 1
print(mini)


def calc(c):
	if c >= 'a' and c <= 'z':
		return ord(c) - ord('a')
	return ord(c) - ord('A') + 26
n = int(input())
s = input()
was = [False] * 52
for i in range(n):
	was[calc(s[i])] = True
go = [[10 * n] * 52 for i in range(n)]
for i in range(n - 1, -1, -1):
	if i < n - 1:
		for j in range(52):
			go[i][j] = go[i + 1][j]
	go[i][calc(s[i])] = i
res = 10 * n
for i in range(n):
	curRight = i
	for j in range(52):
		if was[j]:
			curRight = max(curRight, go[i][j])
	res = min(res, curRight - i + 1)
print(res)


n = int(input())
h = input()
n = len(h)
if n == 1:
	print(1)
	exit()
symbols = {}
for c in h:
	if c not in symbols:
		symbols[c] = 0
	symbols[c] += 1
K = len(symbols)
symbols = symbols.fromkeys(symbols, 0)
(l, r) = (0, 0)
m = 100001
s = set()
while l < n:
	while r < n and len(s) < K:
		s.add(h[r])
		symbols[h[r]] += 1
		r += 1
	if len(s) >= K:
		m = min(m, r - l)
	if symbols[h[l]] == 1:
		s.remove(h[l])
	symbols[h[l]] -= 1
	l += 1
print(m)


from collections import defaultdict

def main():
	n = int(input())
	s = input()
	count = len(set(s))
	d = defaultdict(int)
	res = n
	i = 0
	d[s[0]] += 1
	j = 1
	while j < n:
		if len(d) == count:
			res = min(res, j - i)
			d[s[i]] -= 1
			if d[s[i]] == 0:
				del d[s[i]]
			i += 1
		else:
			d[s[j]] += 1
			j += 1
	while len(d) == count:
		res = min(res, j - i)
		d[s[i]] -= 1
		if d[s[i]] == 0:
			del d[s[i]]
		i += 1
	print(res)
main()


def calc(l1, set1):
	leftMost = 0
	dict1 = {}
	shortestInterval = float('inf')
	for right in range(len(l1)):
		if l1[right] not in dict1:
			dict1[l1[right]] = 0
		dict1[l1[right]] += 1
		while leftMost + 1 <= right and dict1[l1[leftMost]] > 1:
			dict1[l1[leftMost]] -= 1
			leftMost += 1
		if len(dict1) == len(set1):
			shortestInterval = min(shortestInterval, right - leftMost + 1)
	return shortestInterval

def main():
	n = int(input())
	l1 = input()
	set1 = set(l1)
	ans = calc(l1, set1)
	print(ans)
main()


flat_num = int(input())
flats = input()
types = set(flats)
lo = 0
hi = flat_num
valid = -1
while lo <= hi:
	mid = (lo + hi) // 2
	all_catchable = False
	curr_caught = {}
	for to_add in range(flat_num):
		if flats[to_add] not in curr_caught:
			curr_caught[flats[to_add]] = 0
		curr_caught[flats[to_add]] += 1
		if to_add >= mid:
			to_remove = flats[to_add - mid]
			curr_caught[to_remove] -= 1
			if curr_caught[to_remove] == 0:
				del curr_caught[to_remove]
		if len(curr_caught) == len(types):
			all_catchable = True
			break
	if all_catchable:
		valid = mid
		hi = mid - 1
	else:
		lo = mid + 1
print(valid)


n = int(input())
s = input()
types = len(set(list(s)))
gotTypes = 0
got = {}
(l, r, ans) = (0, 0, n)
for l in range(n):
	while r < n and gotTypes != types:
		char = s[r]
		if char in got and got[char] != 0:
			got[char] += 1
		else:
			got[char] = 1
			gotTypes += 1
		r += 1
	if gotTypes == types:
		ans = min(ans, r - l)
	got[s[l]] -= 1
	if got[s[l]] == 0:
		gotTypes -= 1
print(ans)


n = int(input(''))
row = str(input(''))
unique_letters = set(row)
frec_dict = dict()
i = 0
start_j = 0
done_j = False
done_i = False
for letter in unique_letters:
	frec_dict[letter] = 0
while 0 in [v for v in frec_dict.values()]:
	frec_dict[row[start_j]] += 1
	start_j += 1
j = start_j
result = start_j
if j == len(row):
	done_j = True
i_avanza = True
while j < len(row) or i_avanza == True:
	while i_avanza:
		removing_letter = row[i]
		if frec_dict[removing_letter] - 1 == 0:
			i_avanza = False
		else:
			frec_dict[removing_letter] -= 1
			i_avanza = True
			i += 1
		last_result = len(row[i:j])
		result = min(result, last_result)
	if j == len(row):
		done_j = True
	if done_j == False:
		letter = row[j]
		frec_dict[letter] += 1
		i_avanza = True
	if j <= len(row) - 1:
		j += 1
print(result)