import scala.collection.mutable.ArrayBuffer

object A extends App {
  import java.io._
  import java.nio.file.{Files, Path}
  import java.util.StringTokenizer
  import scala.io.Source
  import scala.io.Codec

  /* Implicit methods */
  implicit def intWithTimes(n: Int) = {
    new {
      def times(f: => Unit): Unit = 1.to(n).foreach { _ => f }
    }
  }
  /* Implicit methods */

  //  val in = new CustomScanner(Source.fromResource("input.txt").mkString)
  val in  = new CustomScanner(System.in)
  val out = new PrintWriter(System.out)

  def solve(): Unit = {
    val inputLines = in.nextInt()

    inputLines.times {
      val m = in.nextInt()
      val data = in.nextLineInt(m)
      println(data.reverse.mkString(" "))
    }
  }

  try {
    solve()
  } catch {
    case ex: Exception =>
      println(ex)
      sys.exit(9999)
  } finally {
    out.flush()
    out.close()
  }

  /**
    * Util methods
    */

  def printArr[T](in: Array[T]) = {
    in.foreach(print)
    println()
  }

  /**
    * Scala implementation of a faster java.util.Scanner
    * See: http://codeforces.com/blog/entry/7018
    */
  class CustomScanner(reader: LineNumberReader) extends Iterator[String] with AutoCloseable {

    def this(reader: BufferedReader) = this(new LineNumberReader(reader))

    def this(reader: Reader) = this(new BufferedReader(reader))

    def this(inputStream: InputStream)(implicit codec: Codec) = this(new InputStreamReader(inputStream, codec.charSet))

    def this(path: Path)(implicit codec: Codec) = this(Files.newBufferedReader(path, codec.charSet))

    def this(file: File)(implicit codec: Codec) = this(file.toPath)(codec)

    def this(str: String) = this(new StringReader(str))

    private[this] val tokenizers = {
      Iterator
        .continually(reader.readLine())
        .takeWhile(_ != null)
        .map(new StringTokenizer(_))
        .filter(_.hasMoreTokens)
    }

    private[this] var current: Option[StringTokenizer] = None

    @inline private[this] def tokenizer(): Option[StringTokenizer] =
      current.find(_.hasMoreTokens) orElse {
        current = if (tokenizers.hasNext) Some(tokenizers.next()) else None
        current
      }

    /**
      * Unlike Java's scanner which returns till end of current line, this actually returns the next line
      * @see line() if you want the Java behaviour
      */
    def nextLine(): String = {
      current = None // reset
      reader.readLine()
    }

    def lineNumber: Int = reader.getLineNumber

    def line(): String = tokenizer().get.nextToken("\n\r")

    def nextLineInt(n: Int): ArrayBuffer[Int] = {
      var data = ArrayBuffer[Int]()
      n.times({
        data += nextInt()
      })
      data
    }

    def nextString(): String = next()

    def nextChar(): Char = next().ensuring(_.length == 1).head

    def nextBoolean(): Boolean = next().toBoolean

    def nextByte(radix: Int = 10): Byte = java.lang.Byte.parseByte(next(), radix)

    def nextShort(radix: Int = 10): Short = java.lang.Short.parseShort(next(), radix)

    def nextInt(radix: Int = 10): Int = java.lang.Integer.parseInt(next(), radix)

    def nextLong(radix: Int = 10): Long = java.lang.Long.parseLong(next(), radix)

    def nextBigInt(radix: Int = 10): BigInt = BigInt(next(), radix)

    def nextFloat(): Float = next().toFloat

    def nextDouble(): Double = next().toDouble

    def nextBigDecimal(): BigDecimal = BigDecimal(next())

    override def next(): String = tokenizer().get.nextToken()

    override def hasNext: Boolean = tokenizer().nonEmpty

    override def close(): Unit = reader.close()
  }
}

object A extends App {
  import scala.io.StdIn._

  val t = readInt()

  (0 until t).foreach { _ =>
    val n  = readInt()
    val pn = readLine().split(" ").map(_.toInt)

    val ans = pn.reverse

    println(ans.mkString(" "))
  }
}

object A extends App {
  import scala.io.StdIn._

  val t = readInt()

  (0 until t).foreach { _ =>
    val n  = readInt()
    val pn = readLine().split(" ").map(_.toInt)

    val mod = pn.indexOf(1) % 2

    val ans = pn.zipWithIndex.map { case (p, i) => if (i % 2 == mod) p + 1 else p - 1 }

    println(ans.mkString(" "))
  }
}


object Main {
  import java.io.{BufferedReader, InputStream, InputStreamReader}
  import java.util.StringTokenizer
  import scala.reflect.ClassTag

  def main(args: Array[String]): Unit = {
    val out = new java.io.PrintWriter(System.out)
    new Main(out, new InputReader(System.in)).solve()
    out.flush()
  }

  private[this] val oj = System.getenv("ATCODER_DEBUG") == null
  @inline private final def DEBUG(f: => Unit): Unit = {
    if (!oj){ f }
  }
  @inline private final def debug(as: Array[Boolean]): Unit = if (!oj){ debug(as.map(x => if(x) "1" else "0").mkString) }
  @inline private final def debug(as: Array[Int]): Unit = if (!oj){ debug(as.mkString(" ")) }
  @inline private final def debug(as: Array[Long]): Unit =if (!oj){ debug(as.mkString(" ")) }
  @inline private final def debugDim(m: Array[Array[Long]]): Unit = if (!oj){
    REP(m.length) { i =>
      debug(m(i))
    }
  }
  @inline private final def debugDimFlip(m: Array[Array[Long]]): Unit = if (!oj){
    REP(m(0).length) { j =>
      REP(m.length) { i =>
        System.err.print(m(i)(j))
        System.err.print(" ")
      }
      System.err.println()
    }
  }
  @inline private final def debug(s: => String): Unit = DEBUG {
    System.err.println(s)
  }
  @inline private final def debugL(num: => Long): Unit = DEBUG {
    System.err.println(num)
  }

  class InputReader(val stream: InputStream) {
    private[this] val reader = new BufferedReader(new InputStreamReader(stream), 32768)
    private[this] var tokenizer: StringTokenizer = _

    @inline private[this] final def next(): String = {
      while (tokenizer == null || !tokenizer.hasMoreTokens)
        tokenizer = new StringTokenizer(reader.readLine)
      tokenizer.nextToken
    }

    def nextInt(): Int = Integer.parseInt(next())
    def nextLong(): Long = java.lang.Long.parseLong(next())
    def nextChar(): Char = next().charAt(0)

    def ni(): Int = nextInt()
    def nl(): Long = nextLong()
    def nc(): Char = nextChar()
    def ns(): String = next()
    def ns(n: Int): Array[Char] = ns().toCharArray
    def na(n: Int, offset: Int = 0): Array[Int] = map(n)(_ => ni() + offset)
    def na2(n: Int, offset: Int = 0): (Array[Int], Array[Int]) = {
      val A1, A2 = Array.ofDim[Int](n)
      REP(n) { i =>
        A1(i) = ni() + offset
        A2(i) = ni() + offset
      }
      (A1, A2)
    }
    def nm(n: Int, m: Int): Array[Array[Int]] = {
      val A = Array.ofDim[Int](n, m)
      REP(n) { i =>
        REP(m) { j =>
          A(i)(j) = ni()
        }
      }
      A
    }
    def nal(n: Int): Array[Long] = map(n)(_ => nl())
    def nm_c(n: Int, m: Int): Array[Array[Char]] = map(n) (_ => ns(m))
  }

  def REP(n: Int, offset: Int = 0)(f: Int => Unit): Unit = {
    var i = offset
    val N = n + offset
    while(i < N) { f(i); i += 1 }
  }
  def REP_r(n: Int, offset: Int = 0)(f: Int => Unit): Unit = {
    var i = n - 1 + offset
    while(i >= offset) { f(i); i -= 1 }
  }
  def TO(from: Int, to: Int)(f: Int => Unit): Unit = {
    var i = from
    while(i <= to) { f(i); i += 1 }
  }
  def map[@specialized A: ClassTag](n: Int, offset: Int = 0)(f: Int => A): Array[A] = {
    val res = Array.ofDim[A](n)
    REP(n)(i => res(i) = f(i + offset))
    res
  }

  def sumL(as: Array[Int]): Long = {
    var s = 0L
    REP(as.length)(i => s += as(i))
    s
  }
  def cumSum(as: Array[Int]): Array[Long] = {
    val cum = Array.ofDim[Long](as.length + 1)
    REP(as.length) { i =>
      cum(i + 1) = cum(i) + as(i)
    }
    cum
  }
}

class Main(out: java.io.PrintWriter, sc: Main.InputReader) {
  import sc._
  import Main._
  import java.util.Arrays.sort

  import scala.collection.mutable
  import math.{abs, max, min}
  import mutable.ArrayBuffer

  // toIntとか+7とかするならvalにしろ
  final private[this] val MOD = 1000000007

  def solve(): Unit = {
    val n, m = ni()
    val w = na(n)
    val (from, to) = na2(m, -1)
    val s = ni() - 1
    val g = packUGraph(n, from, to)
    val (_, p, q) = traceBfs(g, s)
    val dp = Array.ofDim[Boolean](n)
    dp(s) = true
    REP_r(n) { i =>
      val v = q(i)
      REP(g(v).length) { j =>
        val u = g(v)(j)
        if (p(u) == v) {
          dp(v) |= dp(u)
        } else if (u != p(v)) {
          dp(v) |= true
        }
      }
    }
    debug(dp)
    var ans = sumL(dp.zipWithIndex.filter(_._1).map(_._2).map(w))
    var add = 0L

    val calced = Array.ofDim[Long](n)
    REP(n) { i =>
      val v = q(i)
      if (!dp(v)) {
        calced(v) = w(v)
        if (p(v)>= 0 && !dp(p(v))) calced(v) += calced(p(v))
        add = max(add, calced(v))
      }
    }
    ans += add
    out.println(ans)
  }

  /**
    * @param n ノード数
    */
  def packUGraph(n: Int, from: Array[Int], to: Array[Int]): Array[Array[Int]] = {
    val t = new Array[Array[Int]](n)
    val p = new Array[Int](n)
    val m = from.length
    REP(m)(i => p(from(i)) += 1)
    REP(m)(i => p(to(i)) += 1)
    REP(n)(i => t(i) = new Array(p(i)))
    REP(m) { i =>
      p(from(i)) -= 1
      t(from(i))(p(from(i))) = to(i)
      p(to(i)) -= 1
      t(to(i))(p(to(i))) = from(i)
    }
    t
  }

  /**
    * @return (depth, parent, queue)
    */
  def traceBfs(g: Array[Array[Int]], rt: Int = 0): (Array[Int], Array[Int], Array[Int]) = {
    val n = g.length
    val INF = 1e9.toInt + 10
    val q, p = Array.ofDim[Int](n)
    q(0) = rt
    p(rt) = -1
    val d = Array.fill[Int](n)(INF)
    d(rt) = 0
    var cur = 0
    var last = 1
    while (cur < last) {
      val v = q(cur)
      REP(g(v).length) { i =>
        val u = g(v)(i)
        if (d(u) == INF) {
          d(u) = d(v) + 1
          p(u) = v
          q(last) = u
          last += 1
        }
      }
      cur += 1
    }
    (d, p, q)
  }
}

object Main {
  import java.io.{BufferedReader, InputStream, InputStreamReader}
  import java.util.StringTokenizer
  import scala.reflect.ClassTag

  def main(args: Array[String]): Unit = {
    val out = new java.io.PrintWriter(System.out)
    new Main(out, new InputReader(System.in)).solve()
    out.flush()
  }

  private[this] val oj = System.getenv("ATCODER_DEBUG") == null
  @inline private final def DEBUG(f: => Unit): Unit = {
    if (!oj){ f }
  }
  @inline private final def debug(as: Array[Boolean]): Unit = if (!oj){ debug(as.map(x => if(x) "1" else "0").mkString) }
  @inline private final def debug(as: Array[Int]): Unit = if (!oj){ debug(as.mkString(" ")) }
  @inline private final def debug(as: Array[Long]): Unit =if (!oj){ debug(as.mkString(" ")) }
  @inline private final def debugDim(m: Array[Array[Long]]): Unit = if (!oj){
    REP(m.length) { i =>
      debug(m(i))
    }
  }
  @inline private final def debugDimFlip(m: Array[Array[Long]]): Unit = if (!oj){
    REP(m(0).length) { j =>
      REP(m.length) { i =>
        System.err.print(m(i)(j))
        System.err.print(" ")
      }
      System.err.println()
    }
  }
  @inline private final def debug(s: => String): Unit = DEBUG {
    System.err.println(s)
  }
  @inline private final def debugL(num: => Long): Unit = DEBUG {
    System.err.println(num)
  }

  class InputReader(val stream: InputStream) {
    private[this] val reader = new BufferedReader(new InputStreamReader(stream), 32768)
    private[this] var tokenizer: StringTokenizer = _

    @inline private[this] final def next(): String = {
      while (tokenizer == null || !tokenizer.hasMoreTokens)
        tokenizer = new StringTokenizer(reader.readLine)
      tokenizer.nextToken
    }

    def nextInt(): Int = Integer.parseInt(next())
    def nextLong(): Long = java.lang.Long.parseLong(next())
    def nextChar(): Char = next().charAt(0)

    def ni(): Int = nextInt()
    def nl(): Long = nextLong()
    def nc(): Char = nextChar()
    def ns(): String = next()
    def ns(n: Int): Array[Char] = ns().toCharArray
    def na(n: Int, offset: Int = 0): Array[Int] = map(n)(_ => ni() + offset)
    def na2(n: Int, offset: Int = 0): (Array[Int], Array[Int]) = {
      val A1, A2 = Array.ofDim[Int](n)
      REP(n) { i =>
        A1(i) = ni() + offset
        A2(i) = ni() + offset
      }
      (A1, A2)
    }
    def nm(n: Int, m: Int): Array[Array[Int]] = {
      val A = Array.ofDim[Int](n, m)
      REP(n) { i =>
        REP(m) { j =>
          A(i)(j) = ni()
        }
      }
      A
    }
    def nal(n: Int): Array[Long] = map(n)(_ => nl())
    def nm_c(n: Int, m: Int): Array[Array[Char]] = map(n) (_ => ns(m))
  }

  def REP(n: Int, offset: Int = 0)(f: Int => Unit): Unit = {
    var i = offset
    val N = n + offset
    while(i < N) { f(i); i += 1 }
  }
  def REP_r(n: Int, offset: Int = 0)(f: Int => Unit): Unit = {
    var i = n - 1 + offset
    while(i >= offset) { f(i); i -= 1 }
  }
  def TO(from: Int, to: Int)(f: Int => Unit): Unit = {
    var i = from
    while(i <= to) { f(i); i += 1 }
  }
  def map[@specialized A: ClassTag](n: Int, offset: Int = 0)(f: Int => A): Array[A] = {
    val res = Array.ofDim[A](n)
    REP(n)(i => res(i) = f(i + offset))
    res
  }

  def sumL(as: Array[Int]): Long = {
    var s = 0L
    REP(as.length)(i => s += as(i))
    s
  }
  def cumSum(as: Array[Int]): Array[Long] = {
    val cum = Array.ofDim[Long](as.length + 1)
    REP(as.length) { i =>
      cum(i + 1) = cum(i) + as(i)
    }
    cum
  }
}

class Main(out: java.io.PrintWriter, sc: Main.InputReader) {
  import sc._
  import Main._
  import java.util.Arrays.sort

  import scala.collection.mutable
  import math.{abs, max, min}
  import mutable.ArrayBuffer

  // toIntとか+7とかするならvalにしろ
  final private[this] val MOD = 1000000007

  def solve(): Unit = {
    val n, m = ni()
    val w = na(n)
    val (from, to) = na2(m, -1)
    val s = ni() - 1
    val g = packUGraph(n, from, to)
    val (_, p, q) = traceBfs(g, s)
    val dp = Array.ofDim[Boolean](n)
    dp(s) = true
    REP_r(n) { i =>
      val v = q(i)
      REP(g(v).length) { j =>
        val u = g(v)(j)
        if (p(u) == v) {
          dp(v) |= dp(u)
        } else if (u != p(v)) {
          dp(v) |= true
        }
      }
    }
    debug(dp)
    var ans = sumL(dp.zipWithIndex.filter(_._1).map(_._2).map(w))
    var add = 0L

    val calced = Array.ofDim[Boolean](n)
    def calc(v: Int): Long = {
      var node = v
      var cnt = 0L
      while(!dp(node)) {
        calced(node) = true
        cnt += w(node)
        node = p(node)
      }
      cnt
    }

    REP_r(n) { i =>
      val v = q(i)
      if (!calced(v)) {
        add = max(add, calc(v))
      }
    }
    ans += add
    out.println(ans)
  }

  /**
    * @param n ノード数
    */
  def packUGraph(n: Int, from: Array[Int], to: Array[Int]): Array[Array[Int]] = {
    val t = new Array[Array[Int]](n)
    val p = new Array[Int](n)
    val m = from.length
    REP(m)(i => p(from(i)) += 1)
    REP(m)(i => p(to(i)) += 1)
    REP(n)(i => t(i) = new Array(p(i)))
    REP(m) { i =>
      p(from(i)) -= 1
      t(from(i))(p(from(i))) = to(i)
      p(to(i)) -= 1
      t(to(i))(p(to(i))) = from(i)
    }
    t
  }

  /**
    * @return (depth, parent, queue)
    */
  def traceBfs(g: Array[Array[Int]], rt: Int = 0): (Array[Int], Array[Int], Array[Int]) = {
    val n = g.length
    val INF = 1e9.toInt + 10
    val q, p = Array.ofDim[Int](n)
    q(0) = rt
    p(rt) = -1
    val d = Array.fill[Int](n)(INF)
    d(rt) = 0
    var cur = 0
    var last = 1
    while (cur < last) {
      val v = q(cur)
      REP(g(v).length) { i =>
        val u = g(v)(i)
        if (d(u) == INF) {
          d(u) = d(v) + 1
          p(u) = v
          q(last) = u
          last += 1
        }
      }
      cur += 1
    }
    (d, p, q)
  }
}


import java.util
import java.util.Scanner
import scala.util.control.Breaks._

import scala.io.StdIn

object Atask565 extends App {

  var line = new Scanner(StdIn.readLine())
  val n = line.nextInt()

  val q = new util.ArrayList[BigInt]()

  for (i <- 0 until n) {
    line = new Scanner(StdIn.readLine())
    q.add(line.nextBigInteger())
  }

  for (i <- 0 until n) {
    var temp: BigInt = q.get(i)
    var ops = 0
    breakable {
      while (true) {
        if (temp == 1) {
          println(ops)
          break()
        }
        if (((temp * 4) % 5) == BigInt(0)) {
          ops += 1
          temp = (temp * 4) / 5
        } else {
          if (((temp * 2) % 3) == BigInt(0)) {
            ops += 1
            temp = (temp * 2) / 3
          } else {
            if ((temp % 2) == BigInt(0)) {
              ops += 1
              temp = temp / 2
            } else {
              ops = -1
              println(ops)
              break()
            }
          }
        }
      }
    }
  }
}

object _1176A extends CodeForcesApp {
  import annotation._, collection.{mutable, Searching}, util._, control._, math.Ordering.Implicits._, Searching._, Math._

  override def apply(io: IO): io.type = {
    val nums = io.read[Seq[Long]]
    val ans = nums.map(solve(_, 0))
    io.writeAll(ans, separator = "\n")
  }

  @tailrec
  def solve(x: Long, acc: Int): Int = {
    if (x == 1) {
      acc
    } else if(x%2 == 0) {
      solve(x/2, acc + 1)
    } else if(x%3 == 0) {
      solve(2*(x/3), acc + 1)
    } else if (x%5 == 0) {
      solve(4*(x/5), acc + 1)
    } else {
      -1
    }
  }
}
/****************************[Ignore Template Below]****************************************/
trait CodeForcesApp {
  lazy val isOnlineJudge: Boolean = sys.props.get("ONLINE_JUDGE").exists(_.toBoolean)
  def debug(x: => Any): Unit = if (!isOnlineJudge) println(x)
  def apply(io: IO): io.type
  def main(args: Array[String]): Unit = this(new IO(System.in, System.out)).close()
}
/***********************************[Scala I/O]*********************************************/
import java.io._, java.util.StringTokenizer
import scala.collection.generic.CanBuild

class IO(in: BufferedReader, out: BufferedWriter) extends Iterator[String] with AutoCloseable with Flushable {
  def this(reader: Reader, writer: Writer) = this(new BufferedReader(reader), new BufferedWriter(writer))
  def this(in: InputStream, out: OutputStream) = this(new InputStreamReader(in), new OutputStreamWriter(out))

  private[this] val tokenizers = Iterator.continually(in.readLine()).takeWhile(_ != null).map(new StringTokenizer(_)).buffered
  val printer = new PrintWriter(out, true)

  @inline private[this] def tokenizer() = {
    while(tokenizers.nonEmpty && !tokenizers.head.hasMoreTokens) tokenizers.next()
    tokenizers.headOption
  }

  def read[A](implicit read: IO.Read[A]): A = read.apply(this)
  def read[C[_], A: IO.Read](n: Int)(implicit b: CanBuild[A, C[A]]): C[A] = Iterator.fill(n)(read).to[C]

  def readTill(delim: String): String = tokenizer().get.nextToken(delim)
  def readTillEndOfLine(): String = readTill("\n\r")

  def readAll[A: IO.Read]: (Int, Vector[A]) = {
    val data = read[Vector[A]]
    (data.length, data)
  }

  override def next() = tokenizer().get.nextToken()
  override def hasNext = tokenizer().nonEmpty

  def write(obj: Any): this.type = {
    printer.print(obj)
    this
  }
  def writeLine(): this.type = {
    printer.println()
    this
  }
  def writeLine(obj: Any): this.type = {
    printer.println(obj)
    this
  }
  def writeLines(obj: Traversable[Any]): this.type = writeAll(obj, separator = "\n")
  def writeAll(obj: Traversable[Any], separator: String = " "): this.type = write(obj mkString separator)
  def query[A: IO.Read](question: Any): A = writeLine(question).read

  override def flush() = printer.flush()
  def close() = {
    flush()
    in.close()
    printer.close()
  }
}
object IO {
  class Read[A](val apply: IO => A) {
    def map[B](f: A => B): Read[B] = new Read(apply andThen f)
  }

  object Read {
    implicit def collection[C[_], A: Read](implicit b: CanBuild[A, C[A]]) : Read[C[A]]         = new Read(r => r.read[C, A](r.read[Int]))
    implicit val string                                                   : Read[String]       = new Read(_.next())
    implicit val int                                                      : Read[Int]          = string.map(_.toInt)
    implicit val long                                                     : Read[Long]         = string.map(_.toLong)
    implicit val bigInt                                                   : Read[BigInt]       = string.map(BigInt(_))
    implicit val double                                                   : Read[Double]       = string.map(_.toDouble)
    implicit val bigDecimal                                               : Read[BigDecimal]   = string.map(BigDecimal(_))
    implicit def tuple2[A: Read, B: Read]                                 : Read[(A, B)]       = new Read(r => (r.read[A], r.read[B]))
    implicit def tuple3[A: Read, B: Read, C: Read]                        : Read[(A, B, C)]    = new Read(r => (r.read[A], r.read[B], r.read[C]))
    implicit def tuple4[A: Read, B: Read, C: Read, D: Read]               : Read[(A, B, C, D)] = new Read(r => (r.read[A], r.read[B], r.read[C], r.read[D]))
    implicit val boolean                                                  : Read[Boolean]      = string map {s =>
      s.toLowerCase match {
        case "yes" | "true" | "1" => true
        case "no" | "false" | "0" => false
        case _ => s.toBoolean
      }
    }
  }
}

object CF565A extends App {

  import scala.io.StdIn

  val q = StdIn.readInt
  for (_ <- 0 until q) {
    var n = StdIn.readLong
    var count = 0
    while (n > 1 && (n % 2 == 0 || n % 3 == 0 || n % 5 == 0)) {
      if (n % 2 == 0) {
        n /= 2
      } else if (n % 3 == 0) {
        n = n / 3 * 2
      } else if (n % 5 == 0) {
        n = n / 5 * 4
      }

      count += 1
    }

    if (n == 1) println(count) else println(-1)
  }
}

object Main {

  val in = new java.util.Scanner(System.in)
  def nextInt = in.next().toInt

  def divide(n: Long): Int = {
    var count = 0
    var num = n
    while (num != 1) {
      if (num % 2 == 0) num = num / 2
      else if (num % 3 == 0) num = 2 * num / 3
      else if (num % 5 == 0) num = 4 * num / 5
      else return -1
      count += 1
    }
    count
  }

  def main(args: Array[String]): Unit = {
    val taskCount = nextInt
    val results = for (test <- 1 to taskCount) yield {
      val n = in.nextLong
      divide(n)
    }

    results foreach println
  }
}


object A extends App {
  import scala.io.StdIn._

  val t = readInt()

  (0 until t).foreach { _ =>
    val Array(a, b, c) = readLine().split(" ").map(_.toLong)

    val (ans1, ans2) = a * b - c match {
      case 0          => (if (b > 1) 1 else -1, -1)
      case d if d < 0 => (b, -1)
      case d if d > 0 => (if (a < c) 1 else -1, b)
    }

    println(s"$ans1 $ans2")
  }
}

object A extends App {
  import scala.io.StdIn._

  val t = readInt()

  (0 until t).foreach { _ =>
    val Array(a, b, c) = readLine().split(" ").map(_.toLong)

    val (ans1, ans2) = (if (a < c) 1 else -1, if (a * b > c) b else -1)

    println(s"$ans1 $ans2")
  }
}

object A extends App {
  import scala.io.StdIn._

  val t = readInt()

  (0 until t).foreach { _ =>
    val Array(a, b, c) = readLine().split(" ").map(_.toInt)

    val (ans1, ans2) = a * b - c match {
      case 0          => (if (b > 1) 1 else -1, -1)
      case d if d < 0 => (b, -1)
      case d if d > 0 => (if (a <= c) 1 else -1, b)
    }

    println(s"$ans1 $ans2")
  }
}

object A extends App {
  import scala.io.StdIn._

  val t = readInt()

  (0 until t).foreach { _ =>
    val Array(a, b, c) = readLine().split(" ").map(_.toInt)

    val (ans1, ans2) = a * b - c match {
      case 0          => (if (b > 1) 1 else -1, -1)
      case d if d < 0 => (b, -1)
      case d if d > 0 => (if (a < c) 1 else -1, b)
    }

    println(s"$ans1 $ans2")
  }
}

object A extends App {
  import scala.io.StdIn._

  val t = readInt()

  (0 until t).foreach { _ =>
    val Array(a, b, c) = readLine().split(" ").map(_.toInt)

    val (ans1, ans2) = a * b - c match {
      case 0          => (if (b == 1) -1 else 1, -1)
      case d if d < 0 => (1, -1)
      case d if d > 0 => (if (a < c) 1 else -1, b)
    }

    println(s"$ans1 $ans2")
  }
}


object Solution extends App {
  val in = io.Source.stdin.getLines()
  val n = in.next().toInt
  val houses = in.next()
  val distinct = houses.distinct
  val result = houses.indices.foldLeft(0, Map.empty[Char, Int], Int.MaxValue) {
    case ((x, map, found), el) =>
      var nX = x
      val ch = houses(el)
      var nMap = map + (ch -> (map.getOrElse(ch, 0) + 1))
      if (nMap.size == distinct.length) {
        while (nMap.size == distinct.length) {
          val nEl = houses(el - nX)
          if (nMap(nEl) == 1)
            nMap = nMap - nEl
          else
            nMap = nMap + (nEl -> (nMap(nEl) - 1))
          nX -= 1
        }
        val t = (nX + 1, nMap, Math.min(nX + 2, found))
        t
      }
      else (nX + 1, nMap, found)
  }
  println(result._3)

}

object C701 {

  import IO._
  import collection.{mutable => cu}

  val MAX = 60

  def main(args: Array[String]): Unit = {
    val Array(n) = readInts(1)
    val str = read.toCharArray
    val desiredCount = {
      val arr = Array.fill(MAX)(0)
      str.foreach { ch => arr(ch - 'A') = 1 }
      arr
    }

    if(desiredCount.sum == 1) {
      out.println(1)
    } else {
      val countTill = Array.fill(n+1)(Array.fill(MAX)(0))

      for (i <- 0 until n) {
        countTill(i).copyToArray(countTill(i+1))
        countTill(i+1)(str(i) - 'A') += 1
      }

      def checkValid(i: Int, j: Int): Boolean = {
        var x = 0
        var res = true
        while(x < MAX) {
          res &= countTill(j+1)(x) - countTill(i)(x) >= desiredCount(x)
          x += 1
        }
        res
      }

      var res = Int.MaxValue

      for (i <- 0 until n) {
        var low = i
        var high = n - 1

        while (low < high) {
          val mid = low + (high - low) / 2
//          println(low, high, mid)

          if (checkValid(i, mid))
            high = mid
          else
            low = mid + 1

//          println(low, high, mid)
        }
//        println(i, low)
        if(checkValid(i, low))
          res = math.min(res, low-i+1)
      }

      out.println(res)
    }

    out.close()
  }

  object IO {
    private val input = new java.io.BufferedReader(new java.io.InputStreamReader(System.in))
    //    private val input = new java.io.BufferedReader(new java.io.InputStreamReader(new java.io.FileInputStream("src/input")))
    val out = new java.io.PrintWriter(System.out)

    @inline def read: String = input.readLine()

    @inline def tokenizeLine = new java.util.StringTokenizer(read)

    def readInt: Int = tokenizeLine.nextToken.toInt

    def readInts(n: Int): Array[Int] = {
      val tl = tokenizeLine
      Array.fill(n)(tl.nextToken.toInt)
    }

    def readLongs(n: Int): Array[Long] = {
      val tl = tokenizeLine
      Array.fill(n)(tl.nextToken.toLong)
    }

    def readBigs(n: Int): Array[BigInt] = {
      val tl = tokenizeLine
      Array.fill(n)(BigInt(tl.nextToken))
    }
  }

}

//package c

object C extends App {

  @inline def tokenizeLine = new java.util.StringTokenizer(readLine)
  def readInts(n: Int) = { val tl = tokenizeLine; Array.fill(n)(tl.nextToken.toInt) }
  def readLongs(n: Int) = { val tl = tokenizeLine; Array.fill(n)(tl.nextToken.toLong) }
  def readBigs(n: Int) = { val tl = tokenizeLine; Array.fill(n)(BigInt(tl.nextToken)) }

  val Array(n) = readInts(1)
  val s = readLine.toCharArray

  val cs = s.distinct.zipWithIndex.toMap
  val pokemons = cs.size
  val as = s.map(cs)
  val cnts = Array.fill(pokemons)(0)

  var l, r = 0
  var res = n

  def isOk() = {
    var i = 0
    var ok = true
    while (ok && i < pokemons) {
      if (cnts(i) == 0) ok = false
      i += 1
    }
    ok
  }

  while (r < n) {
    cnts(as(r)) += 1
    r += 1
    while (isOk()) {
      res = math.min(res, r - l)
      cnts(as(l)) -= 1
      l += 1
    }
  }

  println(res)
}

import Utils._, annotation.tailrec, collection.mutable, util._, control._, math.Ordering.Implicits._

object _701C extends CodeForcesApp {
  override def apply(io: IO) = {import io.{read, write}
    val (n, houses) = read[(Int, String)]
    val all = houses.distinct.length

    def solve(l: Int, r: Int, count: mutable.Map[Char, Int]): Int = {
      if (count.keys.size == all) {
        val c = houses(l)
        count(c) = count(c) - 1
        if (count(c) <= 0) count.remove(c)
        (r - l) min solve(l+1, r, count)
      } else if (r < n) {
        val c = houses(r)
        count(c) += 1
        solve(l, r + 1, count)
      } else {
        Int.MaxValue
      }
    }

    val ans = solve(0, 0, map[Char] to 0)
    write(ans)
  }
}
/****************************[Ignore Template Below]****************************************/
trait CodeForcesApp {
  lazy val isOnlineJudge: Boolean = sys.props.get("ONLINE_JUDGE").exists(_.toBoolean)
  def debug(x: Any): Unit = if (!isOnlineJudge) println(x)
  def apply(io: IO): io.type
  def main(args: Array[String]): Unit = this(new IO(System.in, System.out)).close()
}
object Utils {
  import scala.collection.mutable, mutable.{Map => Dict}
  implicit class GenericExtensions[A](val a: A) extends AnyVal {
    def in(set: collection.Set[A]): Boolean = set(a)
    def some: Option[A] = Some(a)
    def partialMatch[B](f: PartialFunction[A, B]): Option[B] = f lift a
  }
  implicit class TraversableExtensions[A, C[X] <: Traversable[X]](val t: C[A]) extends AnyVal {
    def onlyElement: A = assuming(t.size == 1)(t.head)
    def groupByIdentifier[K](f: A => K): Map[K, A] = t.groupBy(f).mapValues(_.onlyElement)
    def duplicates(implicit b: C of A): C[A] = {
      val elems = mutable.Set.empty[A]
      (t collect {case i if !elems.add(i) => i}).to[C]
    }
    def sumWith[B](f: A => B)(implicit n: Numeric[B]): B = t.foldLeft(n.zero) {case (p, i) => n.plus(p, f(i))}
    def zipWith[B](f: A => B)(implicit b: C of (A, B)): C[(A, B)] = (t map {i => i -> f(i)}).to[C]
    def mapTo[B](f: A => B)(implicit b: C of (A, B)): Map[A, B] = zipWith(f).toUniqueMap
    def whenNonEmpty[B](f: t.type => B): Option[B] = when(t.nonEmpty)(f(t))  // e.g. grades.whenNonEmpty(_.max)
    def collectFirst[B](f: PartialFunction[A, Option[B]]): Option[B] = t.view collect f collectFirst {case Some(x) => x}
    def toMutableMultiSet: Dict[A, Int] = {
      val c = map[A] to 0
      t.foreach(i => c(i) += 1)
      c
    }
    def toMultiSet: Map[A, Int] = toMutableMultiSet.toMap withDefaultValue 0
    def X[B](s: Traversable[B]): Iterator[(A, B)] = for {a <- t.toIterator; b <- s} yield (a, b)
  }
  implicit class ArrayExtensions[A <: AnyRef](val a: Array[A]) extends AnyVal {
    def sort(from: Int, until: Int)(implicit cmp: Ordering[A]): Unit = java.util.Arrays.sort(a, from, until, cmp) //sort [from, until)
  }
  implicit class ArrayExtensions2[A](val a: Array[A]) extends AnyVal {
    def sort(from: Int, until: Int)(implicit cmp: Ordering[A]): Unit = a.view(from, until).sorted.copyToArray(a, from)
  }
  implicit class SeqExtensions[A, C[X] <: Seq[X]](val s: C[A]) extends AnyVal {
    def isRotationOf(t: Seq[A]): Boolean = s ++ s containsSlice t
  }
  implicit class PairExtensions[A, B](val p: (A, B)) extends AnyVal {
    def key = p._1
    def value = p._2
  }
  implicit class PairsExtensions[A, B, C[X] <: Traversable[X]](t: C[(A, B)]) {
    def toUniqueMap: Map[A, B] = t.groupByIdentifier(_.key).mapValues(_.value)
    def toMultiMap(implicit b: C of B): Map[A, C[B]] = t.groupBy(_.key).mapValues(_.map(_.value).to[C])
    def swap(implicit b: C of (B, A)): C[(B, A)] = t.map(_.swap).to[C]
  }
  implicit class MapExtensions[K, V, C[X, Y] <: Map[X, Y]](val m: C[K, V]) extends AnyVal {
    def lastKeyOption: Option[K] = m.lastOption.map(_.key)
    def firstKeyOption: Option[K] = m.headOption.map(_.key)
    def invert: Map[V, Set[K]] = m.toSet[(K, V)].swap.toMultiMap
    def mapKeys[K2](f: K => K2): Map[K2, V] = m map {case (k, v) => f(k) -> v}
    def toMutable: Dict[K, V] = Dict.empty[K, V] ++ m
  }
  implicit class MutableMapExtensions[K, V](val m: mutable.Map[K, V]) extends AnyVal {
    def removeLast(): Option[(K, V)] = m.lastOption.map(removeNode)
    def removeFirst(): Option[(K, V)] = m.headOption.map(removeNode)
    private def removeNode(kv: (K, V)): (K, V) = {
      m -= kv.key
      kv
    }
  }
  implicit class SetExtensions[A, C[A] <: Set[A]](val s: C[A]) extends AnyVal {
    def notContains(x: A): Boolean = !(s contains x)
    def toMutable = mutable.Set.empty[A] ++ s
  }
  implicit class IterableExtensions[A, C[A] <: Seq[A]](val s: C[A]) extends AnyVal {
    def deleteAtIndex(i: Int, howMany: Int = 1) = s.patch(i, Nil, howMany)
    def insertAtIndex(i: Int, items: Seq[A]) = s.patch(i, items, 0)
    def findWithIndex(f: A => Boolean): Option[(A, Int)] = s.zipWithIndex find {case (a, _) => f(a)}
    def foldUntil[B](z: B)(f: (B, A) => B)(c: B => Boolean): Option[(B, Int)] = s.view.scanLeft(z)(f).findWithIndex(c)
  }
  implicit class BooleanExtensions(val x: Boolean) extends AnyVal {
    def to[A](implicit n: Numeric[A]) = if(x) n.one else n.zero
    def toEnglish = if(x) "YES" else "NO"
  }
  implicit class IntExtensions(val x: Int) extends AnyVal {
    import java.lang.{Integer => JInt}
    def withHighestOneBit: Int = JInt.highestOneBit(x)
    def withLowestOneBit: Int = JInt.lowestOneBit(x)
    def numberOfLeadingZeroes: Int = JInt.numberOfLeadingZeros(x)
    def numberOfTrailingZeroes: Int = JInt.numberOfTrailingZeros(x)
    def bitCount: Int = JInt.bitCount(x)
    def setLowestBits(n: Int): Int = x | (left(n) - 1)
    def clearLowestBits(n: Int): Int = x & left(n, ~0)
    def setBit(i: Int, set: Boolean): Int = if (set) setBit(i) else clearBit(i)
    def setBit(i: Int): Int = x | left(i)
    def clearBit(i: Int): Int = x & ~left(i)
    def toggleBit(i: Int): Int = x ^ left(i)
    def testBit(i: Int): Boolean = ((x >> i) & 1) == 1
    private def left(bits: Int, num: Int = 1) = assuming(bits >= 0 && bits < JInt.SIZE)(num << bits)
    def X(y: Int): Iterator[(Int, Int)] = until(x) X until(y)
  }
  implicit class LongExtensions(val x: Long) extends AnyVal {
    import java.lang.{Long => JLong}
    def withHighestOneBitSet: Long = JLong.highestOneBit(x)
    def withLowestOneBitSet: Long = JLong.lowestOneBit(x)
    def numberOfLeadingZeroes: Int = JLong.numberOfLeadingZeros(x)
    def numberOfTrailingZeroes: Int = JLong.numberOfTrailingZeros(x)
    def bitCount: Int = JLong.bitCount(x)
    def setLowestBits(n: Int): Long = x | (left(n) - 1)
    def clearLowestBits(n: Int): Long = x & left(n, ~0L)
    def setBit(i: Int, set: Boolean): Long = if (set) setBit(i) else clearBit(i)
    def setBit(i: Int): Long = x | left(i)
    def clearBit(i: Int): Long = x & ~left(i)
    def toggleBit(i: Int): Long = x ^ left(i)
    def testBit(i: Int): Boolean = ((x >> i) & 1) == 1
    private def left(bits: Int, num: Long = 1L) = assuming(bits >= 0 && bits < JLong.SIZE)(num << bits)
  }
  implicit class NumericExtensions[A](val x: A)(implicit n: Numeric[A]) {
    import Numeric.Implicits._
    def **(i: Int): A = if (i == 0) n.one else {
      val h = x ** (i/2)
      if (i%2 == 0) h * h else h * h * x
    }
    def distance(y: A) = (x - y).abs()
    def nonNegative: Option[A] = when(n.gteq(x, n.zero))(x)
    def whenNegative(f: => A): A = nonNegative getOrElse f   //e.g. students indexOf "Greg" whenNegative Int.MaxValue
  }
  implicit class IntegralExtensions[A](val x: A)(implicit n: Integral[A]) {
    import scala.collection.immutable.NumericRange, Integral.Implicits._
    def mod(y: A): A = x - ((x / y) * y) //(x/y)*y + (x mod y) == x
    def -->(y: A): NumericRange.Inclusive[A] = NumericRange.inclusive(x, y, if (n.lteq(x, y)) n.one else -n.one)
    def ceilDiv(y: A): A = if (mod(y) == n.zero) x/y else n.one + (x/y)
  }
  implicit def toPoint[A](p: (A, A))(implicit n: Numeric[A]) = new java.awt.geom.Point2D.Double(n.toDouble(p._1), n.toDouble(p._2))
  def desc[A: Ordering]: Ordering[A] = asc[A].reverse  //e.g. students.sortBy(_.height)(desc)
  def asc[A](implicit order: Ordering[A]): Ordering[A] = order
  def map[K] = new {
    def to[V](default: => V): Dict[K, V] = using(_ => default)
    def using[V](f: K => V): Dict[K, V] = new mutable.HashMap[K, V]() {
      override def apply(key: K) = getOrElseUpdate(key, f(key))
    }
  }
  def newMultiMap[K, V] = map[K] to mutable.Set.empty[V]
  def memoize[A, B](f: A => B): A ==> B = map[A] using f
  implicit class FuzzyDouble(val x: Double) extends AnyVal {
    def  >~(y: Double) = x > y + eps
    def >=~(y: Double) = x >= y + eps
    def  ~<(y: Double) = y >=~ x
    def ~=<(y: Double) = y >~ x
    def  ~=(y: Double) = (x distance y) <= eps
  }
  def until(until: Int): Range = 0 until until
  def not[A](f: A => Boolean): A => Boolean = {x: A => !f(x)}
  def assuming[A](cond: => Boolean)(f: => A): A = {require(cond); f}
  @inline def when[A](check: Boolean)(f: => A): Option[A] = if (check) f.some else None
  def repeat[U](n: Int)(f: => U): Unit = (1 to n).foreach(_ => f)
  type of[C[_], A] = scala.collection.generic.CanBuild[A, C[A]]
  type ==>[A, B] = collection.Map[A, B]
  val mod: Int = (1e9 + 7).toInt
  val eps: Double = 1e-9
}
/***********************************[Scala I/O]*********************************************/
import Utils._, java.io._, java.util.StringTokenizer

class IO(in: BufferedReader, out: BufferedWriter) extends Iterator[String] with AutoCloseable with Flushable {
  def this(reader: Reader, writer: Writer) = this(new BufferedReader(reader), new BufferedWriter(writer))
  def this(in: InputStream, out: OutputStream) = this(new InputStreamReader(in), new OutputStreamWriter(out))

  private[this] val tokenizers = Iterator.continually(in.readLine()).takeWhile(_ != null).map(new StringTokenizer(_)).buffered
  val printer = new PrintWriter(out, true)

  @inline private[this] def tokenizer() = {
    while(tokenizers.nonEmpty && !tokenizers.head.hasMoreTokens) tokenizers.next()
    when(tokenizers.nonEmpty)(tokenizers.head)
  }

  def read[A](implicit read: IO.Read[A]): A = read.apply(this)
  def read[C[_], A: IO.Read](n: Int)(implicit b: C of A): C[A] = Iterator.fill(n)(read).to[C]

  def readTill(delim: String): String = tokenizer().get.nextToken(delim)
  def readTillEndOfLine(): String = readTill("\n\r")

  override def next() = tokenizer().get.nextToken()
  override def hasNext = tokenizer().nonEmpty

  def write(obj: Any, more: Any*): this.type = {
    printer.print(obj)
    more foreach {i =>
      printer.print(' ')
      printer.print(i)
    }
    this
  }
  def writeOnNextLine(obj: Any, more: Any*): this.type = {
    printer.println()
    write(obj, more: _*)
    this
  }
  def writeAll(obj: Traversable[Any], separator: String = " "): this.type = write(obj mkString separator)

  override def flush() = printer.flush()
  def close() = {
    flush()
    in.close()
    printer.close()
  }
}
object IO {
  class Read[A](val apply: IO => A) {
    def map[B](f: A => B): Read[B] = new Read(apply andThen f)
  }
  object Read {
    implicit def collection[C[_], A: Read](implicit b: C of A): Read[C[A]]         = new Read(r => r.read[C, A](r.read[Int]))
    implicit val string                                       : Read[String]       = new Read(_.next())
    implicit val char                                         : Read[Char]         = string.map(_.toTraversable.onlyElement)
    implicit val int                                          : Read[Int]          = string.map(_.toInt)
    implicit val long                                         : Read[Long]         = string.map(_.toLong)
    implicit val bigInt                                       : Read[BigInt]       = string.map(BigInt(_))
    implicit val double                                       : Read[Double]       = string.map(_.toDouble)
    implicit val bigDecimal                                   : Read[BigDecimal]   = string.map(BigDecimal(_))
    implicit def tuple2[A: Read, B: Read]                     : Read[(A, B)]       = new Read(r => (r.read[A], r.read[B]))
    implicit def tuple3[A: Read, B: Read, C: Read]            : Read[(A, B, C)]    = new Read(r => (r.read[A], r.read[B], r.read[C]))
    implicit def tuple4[A: Read, B: Read, C: Read, D: Read]   : Read[(A, B, C, D)] = new Read(r => (r.read[A], r.read[B], r.read[C], r.read[D]))
    implicit val boolean                                      : Read[Boolean]      = string map {s =>
      s.toLowerCase match {
        case "yes" | "true" | "1" => true
        case "no" | "false" | "0" => false
        case _ => s.toBoolean
      }
    }
  }
}

import Utils._, annotation.tailrec, collection.mutable, util._, control._, math.Ordering.Implicits._

object _701C extends CodeForcesApp {
  override def apply(io: IO) = {import io.{read, write}
    val (n, houses) = read[(Int, String)]
    val all = houses.distinct.size

    def solve(l: Int, r: Int, count: mutable.Map[Char, Int]): Int = {
      debug(l, r, count)
      if (count.keys.size == all) {
        val c = houses(l)
        if(count contains c) {
          count(c) = count(c) - 1
          if (count(c) <= 0) count.remove(c)
        }
        (r - l) min solve(l+1, r, count)
      } else if (r < n) {
        val c = houses(r)
        count(c) += 1
        solve(l, r + 1, count)
      } else {
        Int.MaxValue
      }
    }

    val ans = solve(0, 0, map[Char] to 0)
    write(ans)
  }
}
/****************************[Ignore Template Below]****************************************/
trait CodeForcesApp {
  lazy val isOnlineJudge: Boolean = sys.props.get("ONLINE_JUDGE").exists(_.toBoolean)
  def debug(x: Any): Unit = if (!isOnlineJudge) println(x)
  def apply(io: IO): io.type
  def main(args: Array[String]): Unit = this(new IO(System.in, System.out)).close()
}
object Utils {
  import scala.collection.mutable, mutable.{Map => Dict}
  implicit class GenericExtensions[A](val a: A) extends AnyVal {
    def in(set: collection.Set[A]): Boolean = set(a)
    def some: Option[A] = Some(a)
    def partialMatch[B](f: PartialFunction[A, B]): Option[B] = f lift a
  }
  implicit class TraversableExtensions[A, C[X] <: Traversable[X]](val t: C[A]) extends AnyVal {
    def onlyElement: A = assuming(t.size == 1)(t.head)
    def groupByIdentifier[K](f: A => K): Map[K, A] = t.groupBy(f).mapValues(_.onlyElement)
    def duplicates(implicit b: C of A): C[A] = {
      val elems = mutable.Set.empty[A]
      (t collect {case i if !elems.add(i) => i}).to[C]
    }
    def sumWith[B](f: A => B)(implicit n: Numeric[B]): B = t.foldLeft(n.zero) {case (p, i) => n.plus(p, f(i))}
    def zipWith[B](f: A => B)(implicit b: C of (A, B)): C[(A, B)] = (t map {i => i -> f(i)}).to[C]
    def mapTo[B](f: A => B)(implicit b: C of (A, B)): Map[A, B] = zipWith(f).toUniqueMap
    def whenNonEmpty[B](f: t.type => B): Option[B] = when(t.nonEmpty)(f(t))  // e.g. grades.whenNonEmpty(_.max)
    def collectFirst[B](f: PartialFunction[A, Option[B]]): Option[B] = t.view collect f collectFirst {case Some(x) => x}
    def toMutableMultiSet: Dict[A, Int] = {
      val c = map[A] to 0
      t.foreach(i => c(i) += 1)
      c
    }
    def toMultiSet: Map[A, Int] = toMutableMultiSet.toMap withDefaultValue 0
    def X[B](s: Traversable[B]): Iterator[(A, B)] = for {a <- t.toIterator; b <- s} yield (a, b)
  }
  implicit class ArrayExtensions[A <: AnyRef](val a: Array[A]) extends AnyVal {
    def sort(from: Int, until: Int)(implicit cmp: Ordering[A]): Unit = java.util.Arrays.sort(a, from, until, cmp) //sort [from, until)
  }
  implicit class ArrayExtensions2[A](val a: Array[A]) extends AnyVal {
    def sort(from: Int, until: Int)(implicit cmp: Ordering[A]): Unit = a.view(from, until).sorted.copyToArray(a, from)
  }
  implicit class SeqExtensions[A, C[X] <: Seq[X]](val s: C[A]) extends AnyVal {
    def isRotationOf(t: Seq[A]): Boolean = s ++ s containsSlice t
  }
  implicit class PairExtensions[A, B](val p: (A, B)) extends AnyVal {
    def key = p._1
    def value = p._2
  }
  implicit class PairsExtensions[A, B, C[X] <: Traversable[X]](t: C[(A, B)]) {
    def toUniqueMap: Map[A, B] = t.groupByIdentifier(_.key).mapValues(_.value)
    def toMultiMap(implicit b: C of B): Map[A, C[B]] = t.groupBy(_.key).mapValues(_.map(_.value).to[C])
    def swap(implicit b: C of (B, A)): C[(B, A)] = t.map(_.swap).to[C]
  }
  implicit class MapExtensions[K, V, C[X, Y] <: Map[X, Y]](val m: C[K, V]) extends AnyVal {
    def lastKeyOption: Option[K] = m.lastOption.map(_.key)
    def firstKeyOption: Option[K] = m.headOption.map(_.key)
    def invert: Map[V, Set[K]] = m.toSet[(K, V)].swap.toMultiMap
    def mapKeys[K2](f: K => K2): Map[K2, V] = m map {case (k, v) => f(k) -> v}
    def toMutable: Dict[K, V] = Dict.empty[K, V] ++ m
  }
  implicit class MutableMapExtensions[K, V](val m: mutable.Map[K, V]) extends AnyVal {
    def removeLast(): Option[(K, V)] = m.lastOption.map(removeNode)
    def removeFirst(): Option[(K, V)] = m.headOption.map(removeNode)
    private def removeNode(kv: (K, V)): (K, V) = {
      m -= kv.key
      kv
    }
  }
  implicit class SetExtensions[A, C[A] <: Set[A]](val s: C[A]) extends AnyVal {
    def notContains(x: A): Boolean = !(s contains x)
    def toMutable = mutable.Set.empty[A] ++ s
  }
  implicit class IterableExtensions[A, C[A] <: Seq[A]](val s: C[A]) extends AnyVal {
    def deleteAtIndex(i: Int, howMany: Int = 1) = s.patch(i, Nil, howMany)
    def insertAtIndex(i: Int, items: Seq[A]) = s.patch(i, items, 0)
    def findWithIndex(f: A => Boolean): Option[(A, Int)] = s.zipWithIndex find {case (a, _) => f(a)}
    def foldUntil[B](z: B)(f: (B, A) => B)(c: B => Boolean): Option[(B, Int)] = s.view.scanLeft(z)(f).findWithIndex(c)
  }
  implicit class BooleanExtensions(val x: Boolean) extends AnyVal {
    def to[A](implicit n: Numeric[A]) = if(x) n.one else n.zero
    def toEnglish = if(x) "YES" else "NO"
  }
  implicit class IntExtensions(val x: Int) extends AnyVal {
    import java.lang.{Integer => JInt}
    def withHighestOneBit: Int = JInt.highestOneBit(x)
    def withLowestOneBit: Int = JInt.lowestOneBit(x)
    def numberOfLeadingZeroes: Int = JInt.numberOfLeadingZeros(x)
    def numberOfTrailingZeroes: Int = JInt.numberOfTrailingZeros(x)
    def bitCount: Int = JInt.bitCount(x)
    def setLowestBits(n: Int): Int = x | (left(n) - 1)
    def clearLowestBits(n: Int): Int = x & left(n, ~0)
    def setBit(i: Int, set: Boolean): Int = if (set) setBit(i) else clearBit(i)
    def setBit(i: Int): Int = x | left(i)
    def clearBit(i: Int): Int = x & ~left(i)
    def toggleBit(i: Int): Int = x ^ left(i)
    def testBit(i: Int): Boolean = ((x >> i) & 1) == 1
    private def left(bits: Int, num: Int = 1) = assuming(bits >= 0 && bits < JInt.SIZE)(num << bits)
    def X(y: Int): Iterator[(Int, Int)] = until(x) X until(y)
  }
  implicit class LongExtensions(val x: Long) extends AnyVal {
    import java.lang.{Long => JLong}
    def withHighestOneBitSet: Long = JLong.highestOneBit(x)
    def withLowestOneBitSet: Long = JLong.lowestOneBit(x)
    def numberOfLeadingZeroes: Int = JLong.numberOfLeadingZeros(x)
    def numberOfTrailingZeroes: Int = JLong.numberOfTrailingZeros(x)
    def bitCount: Int = JLong.bitCount(x)
    def setLowestBits(n: Int): Long = x | (left(n) - 1)
    def clearLowestBits(n: Int): Long = x & left(n, ~0L)
    def setBit(i: Int, set: Boolean): Long = if (set) setBit(i) else clearBit(i)
    def setBit(i: Int): Long = x | left(i)
    def clearBit(i: Int): Long = x & ~left(i)
    def toggleBit(i: Int): Long = x ^ left(i)
    def testBit(i: Int): Boolean = ((x >> i) & 1) == 1
    private def left(bits: Int, num: Long = 1L) = assuming(bits >= 0 && bits < JLong.SIZE)(num << bits)
  }
  implicit class NumericExtensions[A](val x: A)(implicit n: Numeric[A]) {
    import Numeric.Implicits._
    def **(i: Int): A = if (i == 0) n.one else {
      val h = x ** (i/2)
      if (i%2 == 0) h * h else h * h * x
    }
    def distance(y: A) = (x - y).abs()
    def nonNegative: Option[A] = when(n.gteq(x, n.zero))(x)
    def whenNegative(f: => A): A = nonNegative getOrElse f   //e.g. students indexOf "Greg" whenNegative Int.MaxValue
  }
  implicit class IntegralExtensions[A](val x: A)(implicit n: Integral[A]) {
    import scala.collection.immutable.NumericRange, Integral.Implicits._
    def mod(y: A): A = x - ((x / y) * y) //(x/y)*y + (x mod y) == x
    def -->(y: A): NumericRange.Inclusive[A] = NumericRange.inclusive(x, y, if (n.lteq(x, y)) n.one else -n.one)
    def ceilDiv(y: A): A = if (mod(y) == n.zero) x/y else n.one + (x/y)
  }
  implicit def toPoint[A](p: (A, A))(implicit n: Numeric[A]) = new java.awt.geom.Point2D.Double(n.toDouble(p._1), n.toDouble(p._2))
  def desc[A: Ordering]: Ordering[A] = asc[A].reverse  //e.g. students.sortBy(_.height)(desc)
  def asc[A](implicit order: Ordering[A]): Ordering[A] = order
  def map[K] = new {
    def to[V](default: => V): Dict[K, V] = using(_ => default)
    def using[V](f: K => V): Dict[K, V] = new mutable.HashMap[K, V]() {
      override def apply(key: K) = getOrElseUpdate(key, f(key))
    }
  }
  def newMultiMap[K, V] = map[K] to mutable.Set.empty[V]
  def memoize[A, B](f: A => B): A ==> B = map[A] using f
  implicit class FuzzyDouble(val x: Double) extends AnyVal {
    def  >~(y: Double) = x > y + eps
    def >=~(y: Double) = x >= y + eps
    def  ~<(y: Double) = y >=~ x
    def ~=<(y: Double) = y >~ x
    def  ~=(y: Double) = (x distance y) <= eps
  }
  def until(until: Int): Range = 0 until until
  def not[A](f: A => Boolean): A => Boolean = {x: A => !f(x)}
  def assuming[A](cond: => Boolean)(f: => A): A = {require(cond); f}
  @inline def when[A](check: Boolean)(f: => A): Option[A] = if (check) f.some else None
  def repeat[U](n: Int)(f: => U): Unit = (1 to n).foreach(_ => f)
  type of[C[_], A] = scala.collection.generic.CanBuild[A, C[A]]
  type ==>[A, B] = collection.Map[A, B]
  val mod: Int = (1e9 + 7).toInt
  val eps: Double = 1e-9
}
/***********************************[Scala I/O]*********************************************/
import Utils._, java.io._, java.util.StringTokenizer

class IO(in: BufferedReader, out: BufferedWriter) extends Iterator[String] with AutoCloseable with Flushable {
  def this(reader: Reader, writer: Writer) = this(new BufferedReader(reader), new BufferedWriter(writer))
  def this(in: InputStream, out: OutputStream) = this(new InputStreamReader(in), new OutputStreamWriter(out))

  private[this] val tokenizers = Iterator.continually(in.readLine()).takeWhile(_ != null).map(new StringTokenizer(_)).buffered
  val printer = new PrintWriter(out, true)

  @inline private[this] def tokenizer() = {
    while(tokenizers.nonEmpty && !tokenizers.head.hasMoreTokens) tokenizers.next()
    when(tokenizers.nonEmpty)(tokenizers.head)
  }

  def read[A](implicit read: IO.Read[A]): A = read.apply(this)
  def read[C[_], A: IO.Read](n: Int)(implicit b: C of A): C[A] = Iterator.fill(n)(read).to[C]

  def readTill(delim: String): String = tokenizer().get.nextToken(delim)
  def readTillEndOfLine(): String = readTill("\n\r")

  override def next() = tokenizer().get.nextToken()
  override def hasNext = tokenizer().nonEmpty

  def write(obj: Any, more: Any*): this.type = {
    printer.print(obj)
    more foreach {i =>
      printer.print(' ')
      printer.print(i)
    }
    this
  }
  def writeOnNextLine(obj: Any, more: Any*): this.type = {
    printer.println()
    write(obj, more: _*)
    this
  }
  def writeAll(obj: Traversable[Any], separator: String = " "): this.type = write(obj mkString separator)

  override def flush() = printer.flush()
  def close() = {
    flush()
    in.close()
    printer.close()
  }
}
object IO {
  class Read[A](val apply: IO => A) {
    def map[B](f: A => B): Read[B] = new Read(apply andThen f)
  }
  object Read {
    implicit def collection[C[_], A: Read](implicit b: C of A): Read[C[A]]         = new Read(r => r.read[C, A](r.read[Int]))
    implicit val string                                       : Read[String]       = new Read(_.next())
    implicit val char                                         : Read[Char]         = string.map(_.toTraversable.onlyElement)
    implicit val int                                          : Read[Int]          = string.map(_.toInt)
    implicit val long                                         : Read[Long]         = string.map(_.toLong)
    implicit val bigInt                                       : Read[BigInt]       = string.map(BigInt(_))
    implicit val double                                       : Read[Double]       = string.map(_.toDouble)
    implicit val bigDecimal                                   : Read[BigDecimal]   = string.map(BigDecimal(_))
    implicit def tuple2[A: Read, B: Read]                     : Read[(A, B)]       = new Read(r => (r.read[A], r.read[B]))
    implicit def tuple3[A: Read, B: Read, C: Read]            : Read[(A, B, C)]    = new Read(r => (r.read[A], r.read[B], r.read[C]))
    implicit def tuple4[A: Read, B: Read, C: Read, D: Read]   : Read[(A, B, C, D)] = new Read(r => (r.read[A], r.read[B], r.read[C], r.read[D]))
    implicit val boolean                                      : Read[Boolean]      = string map {s =>
      s.toLowerCase match {
        case "yes" | "true" | "1" => true
        case "no" | "false" | "0" => false
        case _ => s.toBoolean
      }
    }
  }
}

import java.util.Scanner

object Main{
  def main (args: Array[String]){
    val sc = new Scanner(System.in)
    val n = sc.nextInt()
    sc.nextLine()
    val s = sc.nextLine()

    //
    val vol = 65
    var num = 0

    val dp2 = new Array[Boolean](58)
    for(c <- s){
      if(!dp2(c.toInt - vol)){
        num += 1
        dp2(c.toInt - vol) = true
      }
    }

    var ans = n
    var l = 0
    var r = 0
    var cnt = 0

    val dp = new Array[Int](58)
    while(r < n){
      val now = s(r).toInt - vol

      if(dp(now) == 0){
        cnt += 1
        dp(now) += 1
        if(cnt == num){
          ans = Math.min(ans, r-l+1)

          // move l
          var flag = true
          while(flag){
            val tmp = s(l).toInt - vol
            dp(tmp) -= 1
            l += 1
            if(dp(tmp) == 0){
              cnt -= 1
              flag = false
            }
            else
              ans = Math.min(ans, r-l+1)
          }

        }
      }
      else{
        dp(now) += 1
      }
      r += 1
    }

    println(ans)
  }
}

object Solution extends App {
  val in = io.Source.stdin.getLines()
  val n = in.next().toInt
  val houses = in.next()
  val distinct = houses.distinct
  val result = houses.indices.foldLeft(0, Map.empty[Char, Int], Int.MaxValue) {
    case ((x, map, found), el) =>
      var nX = x
      val ch = houses(el)
      var nMap = map + (ch -> (map.getOrElse(ch, 0) + 1))
      if (nMap.size == distinct.length) {
        while (nMap.size == distinct.length) {
          val nEl = houses(el - nX)
          if (nMap(nEl) == 1)
            nMap = nMap - nEl
          else
            nMap = nMap + (nEl -> (nMap(nEl) - 1))
          nX -= 1
        }
        (nX + 2, nMap, Math.min(nX + 2, found))
      }
      else (nX + 1, nMap, found)
  }
  println(result._3)

}

import Utils._, annotation.tailrec, collection.mutable, util._, control._, math.Ordering.Implicits._

object _701C extends CodeForcesApp {
  override def apply(io: IO) = {import io.{read, write}
    val (n, houses) = read[(Int, String)]

    val first = map[Char] to Int.MaxValue
    val last = map[Char] to Int.MinValue

    houses.zipWithIndex foreach {case (c, i) =>
      first(c) = first(c) min i
      last(c) = last(c) max i
    }
    val (p1, p2, p3, p4) = (first.values.min, first.values.max, last.values.min, last.values.max)
    val ans = (p2 - p1) min (p4  - p3)
    write(ans + 1)
  }
}
/****************************[Ignore Template Below]****************************************/
trait CodeForcesApp {
  lazy val isOnlineJudge: Boolean = sys.props.get("ONLINE_JUDGE").exists(_.toBoolean)
  def debug(x: Any): Unit = if (!isOnlineJudge) println(x)
  def apply(io: IO): io.type
  def main(args: Array[String]): Unit = this(new IO(System.in, System.out)).close()
}
object Utils {
  import scala.collection.mutable, mutable.{Map => Dict}
  implicit class GenericExtensions[A](val a: A) extends AnyVal {
    def in(set: collection.Set[A]): Boolean = set(a)
    def some: Option[A] = Some(a)
    def partialMatch[B](f: PartialFunction[A, B]): Option[B] = f lift a
  }
  implicit class TraversableExtensions[A, C[X] <: Traversable[X]](val t: C[A]) extends AnyVal {
    def onlyElement: A = assuming(t.size == 1)(t.head)
    def groupByIdentifier[K](f: A => K): Map[K, A] = t.groupBy(f).mapValues(_.onlyElement)
    def duplicates(implicit b: C of A): C[A] = {
      val elems = mutable.Set.empty[A]
      (t collect {case i if !elems.add(i) => i}).to[C]
    }
    def sumWith[B](f: A => B)(implicit n: Numeric[B]): B = t.foldLeft(n.zero) {case (p, i) => n.plus(p, f(i))}
    def zipWith[B](f: A => B)(implicit b: C of (A, B)): C[(A, B)] = (t map {i => i -> f(i)}).to[C]
    def mapTo[B](f: A => B)(implicit b: C of (A, B)): Map[A, B] = zipWith(f).toUniqueMap
    def whenNonEmpty[B](f: t.type => B): Option[B] = when(t.nonEmpty)(f(t))  // e.g. grades.whenNonEmpty(_.max)
    def collectFirst[B](f: PartialFunction[A, Option[B]]): Option[B] = t.view collect f collectFirst {case Some(x) => x}
    def toMutableMultiSet: Dict[A, Int] = {
      val c = map[A] to 0
      t.foreach(i => c(i) += 1)
      c
    }
    def toMultiSet: Map[A, Int] = toMutableMultiSet.toMap withDefaultValue 0
    def X[B](s: Traversable[B]): Iterator[(A, B)] = for {a <- t.toIterator; b <- s} yield (a, b)
  }
  implicit class ArrayExtensions[A <: AnyRef](val a: Array[A]) extends AnyVal {
    def sort(from: Int, until: Int)(implicit cmp: Ordering[A]): Unit = java.util.Arrays.sort(a, from, until, cmp) //sort [from, until)
  }
  implicit class ArrayExtensions2[A](val a: Array[A]) extends AnyVal {
    def sort(from: Int, until: Int)(implicit cmp: Ordering[A]): Unit = a.view(from, until).sorted.copyToArray(a, from)
  }
  implicit class SeqExtensions[A, C[X] <: Seq[X]](val s: C[A]) extends AnyVal {
    def isRotationOf(t: Seq[A]): Boolean = s ++ s containsSlice t
  }
  implicit class PairExtensions[A, B](val p: (A, B)) extends AnyVal {
    def key = p._1
    def value = p._2
  }
  implicit class PairsExtensions[A, B, C[X] <: Traversable[X]](t: C[(A, B)]) {
    def toUniqueMap: Map[A, B] = t.groupByIdentifier(_.key).mapValues(_.value)
    def toMultiMap(implicit b: C of B): Map[A, C[B]] = t.groupBy(_.key).mapValues(_.map(_.value).to[C])
    def swap(implicit b: C of (B, A)): C[(B, A)] = t.map(_.swap).to[C]
  }
  implicit class MapExtensions[K, V, C[X, Y] <: Map[X, Y]](val m: C[K, V]) extends AnyVal {
    def lastKeyOption: Option[K] = m.lastOption.map(_.key)
    def firstKeyOption: Option[K] = m.headOption.map(_.key)
    def invert: Map[V, Set[K]] = m.toSet[(K, V)].swap.toMultiMap
    def mapKeys[K2](f: K => K2): Map[K2, V] = m map {case (k, v) => f(k) -> v}
    def toMutable: Dict[K, V] = Dict.empty[K, V] ++ m
  }
  implicit class MutableMapExtensions[K, V](val m: mutable.Map[K, V]) extends AnyVal {
    def removeLast(): Option[(K, V)] = m.lastOption.map(removeNode)
    def removeFirst(): Option[(K, V)] = m.headOption.map(removeNode)
    private def removeNode(kv: (K, V)): (K, V) = {
      m -= kv.key
      kv
    }
  }
  implicit class SetExtensions[A, C[A] <: Set[A]](val s: C[A]) extends AnyVal {
    def notContains(x: A): Boolean = !(s contains x)
    def toMutable = mutable.Set.empty[A] ++ s
  }
  implicit class IterableExtensions[A, C[A] <: Seq[A]](val s: C[A]) extends AnyVal {
    def deleteAtIndex(i: Int, howMany: Int = 1) = s.patch(i, Nil, howMany)
    def insertAtIndex(i: Int, items: Seq[A]) = s.patch(i, items, 0)
    def findWithIndex(f: A => Boolean): Option[(A, Int)] = s.zipWithIndex find {case (a, _) => f(a)}
    def foldUntil[B](z: B)(f: (B, A) => B)(c: B => Boolean): Option[(B, Int)] = s.view.scanLeft(z)(f).findWithIndex(c)
  }
  implicit class BooleanExtensions(val x: Boolean) extends AnyVal {
    def to[A](implicit n: Numeric[A]) = if(x) n.one else n.zero
    def toEnglish = if(x) "YES" else "NO"
  }
  implicit class IntExtensions(val x: Int) extends AnyVal {
    import java.lang.{Integer => JInt}
    def withHighestOneBit: Int = JInt.highestOneBit(x)
    def withLowestOneBit: Int = JInt.lowestOneBit(x)
    def numberOfLeadingZeroes: Int = JInt.numberOfLeadingZeros(x)
    def numberOfTrailingZeroes: Int = JInt.numberOfTrailingZeros(x)
    def bitCount: Int = JInt.bitCount(x)
    def setLowestBits(n: Int): Int = x | (left(n) - 1)
    def clearLowestBits(n: Int): Int = x & left(n, ~0)
    def setBit(i: Int, set: Boolean): Int = if (set) setBit(i) else clearBit(i)
    def setBit(i: Int): Int = x | left(i)
    def clearBit(i: Int): Int = x & ~left(i)
    def toggleBit(i: Int): Int = x ^ left(i)
    def testBit(i: Int): Boolean = ((x >> i) & 1) == 1
    private def left(bits: Int, num: Int = 1) = assuming(bits >= 0 && bits < JInt.SIZE)(num << bits)
    def X(y: Int): Iterator[(Int, Int)] = until(x) X until(y)
  }
  implicit class LongExtensions(val x: Long) extends AnyVal {
    import java.lang.{Long => JLong}
    def withHighestOneBitSet: Long = JLong.highestOneBit(x)
    def withLowestOneBitSet: Long = JLong.lowestOneBit(x)
    def numberOfLeadingZeroes: Int = JLong.numberOfLeadingZeros(x)
    def numberOfTrailingZeroes: Int = JLong.numberOfTrailingZeros(x)
    def bitCount: Int = JLong.bitCount(x)
    def setLowestBits(n: Int): Long = x | (left(n) - 1)
    def clearLowestBits(n: Int): Long = x & left(n, ~0L)
    def setBit(i: Int, set: Boolean): Long = if (set) setBit(i) else clearBit(i)
    def setBit(i: Int): Long = x | left(i)
    def clearBit(i: Int): Long = x & ~left(i)
    def toggleBit(i: Int): Long = x ^ left(i)
    def testBit(i: Int): Boolean = ((x >> i) & 1) == 1
    private def left(bits: Int, num: Long = 1L) = assuming(bits >= 0 && bits < JLong.SIZE)(num << bits)
  }
  implicit class NumericExtensions[A](val x: A)(implicit n: Numeric[A]) {
    import Numeric.Implicits._
    def **(i: Int): A = if (i == 0) n.one else {
      val h = x ** (i/2)
      if (i%2 == 0) h * h else h * h * x
    }
    def distance(y: A) = (x - y).abs()
    def nonNegative: Option[A] = when(n.gteq(x, n.zero))(x)
    def whenNegative(f: => A): A = nonNegative getOrElse f   //e.g. students indexOf "Greg" whenNegative Int.MaxValue
  }
  implicit class IntegralExtensions[A](val x: A)(implicit n: Integral[A]) {
    import scala.collection.immutable.NumericRange, Integral.Implicits._
    def mod(y: A): A = x - ((x / y) * y) //(x/y)*y + (x mod y) == x
    def -->(y: A): NumericRange.Inclusive[A] = NumericRange.inclusive(x, y, if (n.lteq(x, y)) n.one else -n.one)
    def ceilDiv(y: A): A = if (mod(y) == n.zero) x/y else n.one + (x/y)
  }
  implicit def toPoint[A](p: (A, A))(implicit n: Numeric[A]) = new java.awt.geom.Point2D.Double(n.toDouble(p._1), n.toDouble(p._2))
  def desc[A: Ordering]: Ordering[A] = asc[A].reverse  //e.g. students.sortBy(_.height)(desc)
  def asc[A](implicit order: Ordering[A]): Ordering[A] = order
  def map[K] = new {
    def to[V](default: => V): Dict[K, V] = using(_ => default)
    def using[V](f: K => V): Dict[K, V] = new mutable.HashMap[K, V]() {
      override def apply(key: K) = getOrElseUpdate(key, f(key))
    }
  }
  def newMultiMap[K, V] = map[K] to mutable.Set.empty[V]
  def memoize[A, B](f: A => B): A ==> B = map[A] using f
  implicit class FuzzyDouble(val x: Double) extends AnyVal {
    def  >~(y: Double) = x > y + eps
    def >=~(y: Double) = x >= y + eps
    def  ~<(y: Double) = y >=~ x
    def ~=<(y: Double) = y >~ x
    def  ~=(y: Double) = (x distance y) <= eps
  }
  def until(until: Int): Range = 0 until until
  def not[A](f: A => Boolean): A => Boolean = {x: A => !f(x)}
  def assuming[A](cond: => Boolean)(f: => A): A = {require(cond); f}
  @inline def when[A](check: Boolean)(f: => A): Option[A] = if (check) f.some else None
  def repeat[U](n: Int)(f: => U): Unit = (1 to n).foreach(_ => f)
  type of[C[_], A] = scala.collection.generic.CanBuild[A, C[A]]
  type ==>[A, B] = collection.Map[A, B]
  val mod: Int = (1e9 + 7).toInt
  val eps: Double = 1e-9
}
/***********************************[Scala I/O]*********************************************/
import Utils._, java.io._, java.util.StringTokenizer

class IO(in: BufferedReader, out: BufferedWriter) extends Iterator[String] with AutoCloseable with Flushable {
  def this(reader: Reader, writer: Writer) = this(new BufferedReader(reader), new BufferedWriter(writer))
  def this(in: InputStream, out: OutputStream) = this(new InputStreamReader(in), new OutputStreamWriter(out))

  private[this] val tokenizers = Iterator.continually(in.readLine()).takeWhile(_ != null).map(new StringTokenizer(_)).buffered
  val printer = new PrintWriter(out, true)

  @inline private[this] def tokenizer() = {
    while(tokenizers.nonEmpty && !tokenizers.head.hasMoreTokens) tokenizers.next()
    when(tokenizers.nonEmpty)(tokenizers.head)
  }

  def read[A](implicit read: IO.Read[A]): A = read.apply(this)
  def read[C[_], A: IO.Read](n: Int)(implicit b: C of A): C[A] = Iterator.fill(n)(read).to[C]

  def readTill(delim: String): String = tokenizer().get.nextToken(delim)
  def readTillEndOfLine(): String = readTill("\n\r")

  override def next() = tokenizer().get.nextToken()
  override def hasNext = tokenizer().nonEmpty

  def write(obj: Any, more: Any*): this.type = {
    printer.print(obj)
    more foreach {i =>
      printer.print(' ')
      printer.print(i)
    }
    this
  }
  def writeOnNextLine(obj: Any, more: Any*): this.type = {
    printer.println()
    write(obj, more: _*)
    this
  }
  def writeAll(obj: Traversable[Any], separator: String = " "): this.type = write(obj mkString separator)

  override def flush() = printer.flush()
  def close() = {
    flush()
    in.close()
    printer.close()
  }
}
object IO {
  class Read[A](val apply: IO => A) {
    def map[B](f: A => B): Read[B] = new Read(apply andThen f)
  }
  object Read {
    implicit def collection[C[_], A: Read](implicit b: C of A): Read[C[A]]         = new Read(r => r.read[C, A](r.read[Int]))
    implicit val string                                       : Read[String]       = new Read(_.next())
    implicit val char                                         : Read[Char]         = string.map(_.toTraversable.onlyElement)
    implicit val int                                          : Read[Int]          = string.map(_.toInt)
    implicit val long                                         : Read[Long]         = string.map(_.toLong)
    implicit val bigInt                                       : Read[BigInt]       = string.map(BigInt(_))
    implicit val double                                       : Read[Double]       = string.map(_.toDouble)
    implicit val bigDecimal                                   : Read[BigDecimal]   = string.map(BigDecimal(_))
    implicit def tuple2[A: Read, B: Read]                     : Read[(A, B)]       = new Read(r => (r.read[A], r.read[B]))
    implicit def tuple3[A: Read, B: Read, C: Read]            : Read[(A, B, C)]    = new Read(r => (r.read[A], r.read[B], r.read[C]))
    implicit def tuple4[A: Read, B: Read, C: Read, D: Read]   : Read[(A, B, C, D)] = new Read(r => (r.read[A], r.read[B], r.read[C], r.read[D]))
    implicit val boolean                                      : Read[Boolean]      = string map {s =>
      s.toLowerCase match {
        case "yes" | "true" | "1" => true
        case "no" | "false" | "0" => false
        case _ => s.toBoolean
      }
    }
  }
}

import Utils._, annotation.tailrec, collection.mutable, util._, control._, math.Ordering.Implicits._

object _701C extends CodeForcesApp {
  override def apply(io: IO) = {import io.{read, write}
    val (n, houses) = read[(Int, String)]
    val count = map[Char] to 0
    val all = houses.distinct.length

    var l, r = 0
    var ans = Int.MaxValue

    while(r < n) {
      count.size match {
        case `all` =>
          ans = ans min (r - l)
          l += 1
          if (l < n) {
            val h = houses(l)
            count(h) -= 1
            if (count(h) <= 0) count.remove(h)
          }
        case _ =>
          r += 1
          if (r < n) count(houses(r)) += 1
      }
    }

    write(ans min n)
  }
}
/****************************[Ignore Template Below]****************************************/
trait CodeForcesApp {
  lazy val isOnlineJudge: Boolean = sys.props.get("ONLINE_JUDGE").exists(_.toBoolean)
  def debug(x: Any): Unit = if (!isOnlineJudge) println(x)
  def apply(io: IO): io.type
  def main(args: Array[String]): Unit = this(new IO(System.in, System.out)).close()
}
object Utils {
  import scala.collection.mutable, mutable.{Map => Dict}
  implicit class GenericExtensions[A](val a: A) extends AnyVal {
    def in(set: collection.Set[A]): Boolean = set(a)
    def some: Option[A] = Some(a)
    def partialMatch[B](f: PartialFunction[A, B]): Option[B] = f lift a
  }
  implicit class TraversableExtensions[A, C[X] <: Traversable[X]](val t: C[A]) extends AnyVal {
    def onlyElement: A = assuming(t.size == 1)(t.head)
    def groupByIdentifier[K](f: A => K): Map[K, A] = t.groupBy(f).mapValues(_.onlyElement)
    def duplicates(implicit b: C of A): C[A] = {
      val elems = mutable.Set.empty[A]
      (t collect {case i if !elems.add(i) => i}).to[C]
    }
    def sumWith[B](f: A => B)(implicit n: Numeric[B]): B = t.foldLeft(n.zero) {case (p, i) => n.plus(p, f(i))}
    def zipWith[B](f: A => B)(implicit b: C of (A, B)): C[(A, B)] = (t map {i => i -> f(i)}).to[C]
    def mapTo[B](f: A => B)(implicit b: C of (A, B)): Map[A, B] = zipWith(f).toUniqueMap
    def whenNonEmpty[B](f: t.type => B): Option[B] = when(t.nonEmpty)(f(t))  // e.g. grades.whenNonEmpty(_.max)
    def collectFirst[B](f: PartialFunction[A, Option[B]]): Option[B] = t.view collect f collectFirst {case Some(x) => x}
    def toMutableMultiSet: Dict[A, Int] = {
      val c = map[A] to 0
      t.foreach(i => c(i) += 1)
      c
    }
    def toMultiSet: Map[A, Int] = toMutableMultiSet.toMap withDefaultValue 0
    def X[B](s: Traversable[B]): Iterator[(A, B)] = for {a <- t.toIterator; b <- s} yield (a, b)
  }
  implicit class ArrayExtensions[A <: AnyRef](val a: Array[A]) extends AnyVal {
    def sort(from: Int, until: Int)(implicit cmp: Ordering[A]): Unit = java.util.Arrays.sort(a, from, until, cmp) //sort [from, until)
  }
  implicit class ArrayExtensions2[A](val a: Array[A]) extends AnyVal {
    def sort(from: Int, until: Int)(implicit cmp: Ordering[A]): Unit = a.view(from, until).sorted.copyToArray(a, from)
  }
  implicit class SeqExtensions[A, C[X] <: Seq[X]](val s: C[A]) extends AnyVal {
    def isRotationOf(t: Seq[A]): Boolean = s ++ s containsSlice t
  }
  implicit class PairExtensions[A, B](val p: (A, B)) extends AnyVal {
    def key = p._1
    def value = p._2
  }
  implicit class PairsExtensions[A, B, C[X] <: Traversable[X]](t: C[(A, B)]) {
    def toUniqueMap: Map[A, B] = t.groupByIdentifier(_.key).mapValues(_.value)
    def toMultiMap(implicit b: C of B): Map[A, C[B]] = t.groupBy(_.key).mapValues(_.map(_.value).to[C])
    def swap(implicit b: C of (B, A)): C[(B, A)] = t.map(_.swap).to[C]
  }
  implicit class MapExtensions[K, V, C[X, Y] <: Map[X, Y]](val m: C[K, V]) extends AnyVal {
    def lastKeyOption: Option[K] = m.lastOption.map(_.key)
    def firstKeyOption: Option[K] = m.headOption.map(_.key)
    def invert: Map[V, Set[K]] = m.toSet[(K, V)].swap.toMultiMap
    def mapKeys[K2](f: K => K2): Map[K2, V] = m map {case (k, v) => f(k) -> v}
    def toMutable: Dict[K, V] = Dict.empty[K, V] ++ m
  }
  implicit class MutableMapExtensions[K, V](val m: mutable.Map[K, V]) extends AnyVal {
    def removeLast(): Option[(K, V)] = m.lastOption.map(removeNode)
    def removeFirst(): Option[(K, V)] = m.headOption.map(removeNode)
    private def removeNode(kv: (K, V)): (K, V) = {
      m -= kv.key
      kv
    }
  }
  implicit class SetExtensions[A, C[A] <: Set[A]](val s: C[A]) extends AnyVal {
    def notContains(x: A): Boolean = !(s contains x)
    def toMutable = mutable.Set.empty[A] ++ s
  }
  implicit class IterableExtensions[A, C[A] <: Seq[A]](val s: C[A]) extends AnyVal {
    def deleteAtIndex(i: Int, howMany: Int = 1) = s.patch(i, Nil, howMany)
    def insertAtIndex(i: Int, items: Seq[A]) = s.patch(i, items, 0)
    def findWithIndex(f: A => Boolean): Option[(A, Int)] = s.zipWithIndex find {case (a, _) => f(a)}
    def foldUntil[B](z: B)(f: (B, A) => B)(c: B => Boolean): Option[(B, Int)] = s.view.scanLeft(z)(f).findWithIndex(c)
  }
  implicit class BooleanExtensions(val x: Boolean) extends AnyVal {
    def to[A](implicit n: Numeric[A]) = if(x) n.one else n.zero
    def toEnglish = if(x) "YES" else "NO"
  }
  implicit class IntExtensions(val x: Int) extends AnyVal {
    import java.lang.{Integer => JInt}
    def withHighestOneBit: Int = JInt.highestOneBit(x)
    def withLowestOneBit: Int = JInt.lowestOneBit(x)
    def numberOfLeadingZeroes: Int = JInt.numberOfLeadingZeros(x)
    def numberOfTrailingZeroes: Int = JInt.numberOfTrailingZeros(x)
    def bitCount: Int = JInt.bitCount(x)
    def setLowestBits(n: Int): Int = x | (left(n) - 1)
    def clearLowestBits(n: Int): Int = x & left(n, ~0)
    def setBit(i: Int, set: Boolean): Int = if (set) setBit(i) else clearBit(i)
    def setBit(i: Int): Int = x | left(i)
    def clearBit(i: Int): Int = x & ~left(i)
    def toggleBit(i: Int): Int = x ^ left(i)
    def testBit(i: Int): Boolean = ((x >> i) & 1) == 1
    private def left(bits: Int, num: Int = 1) = assuming(bits >= 0 && bits < JInt.SIZE)(num << bits)
    def X(y: Int): Iterator[(Int, Int)] = until(x) X until(y)
  }
  implicit class LongExtensions(val x: Long) extends AnyVal {
    import java.lang.{Long => JLong}
    def withHighestOneBitSet: Long = JLong.highestOneBit(x)
    def withLowestOneBitSet: Long = JLong.lowestOneBit(x)
    def numberOfLeadingZeroes: Int = JLong.numberOfLeadingZeros(x)
    def numberOfTrailingZeroes: Int = JLong.numberOfTrailingZeros(x)
    def bitCount: Int = JLong.bitCount(x)
    def setLowestBits(n: Int): Long = x | (left(n) - 1)
    def clearLowestBits(n: Int): Long = x & left(n, ~0L)
    def setBit(i: Int, set: Boolean): Long = if (set) setBit(i) else clearBit(i)
    def setBit(i: Int): Long = x | left(i)
    def clearBit(i: Int): Long = x & ~left(i)
    def toggleBit(i: Int): Long = x ^ left(i)
    def testBit(i: Int): Boolean = ((x >> i) & 1) == 1
    private def left(bits: Int, num: Long = 1L) = assuming(bits >= 0 && bits < JLong.SIZE)(num << bits)
  }
  implicit class NumericExtensions[A](val x: A)(implicit n: Numeric[A]) {
    import Numeric.Implicits._
    def **(i: Int): A = if (i == 0) n.one else {
      val h = x ** (i/2)
      if (i%2 == 0) h * h else h * h * x
    }
    def distance(y: A) = (x - y).abs()
    def nonNegative: Option[A] = when(n.gteq(x, n.zero))(x)
    def whenNegative(f: => A): A = nonNegative getOrElse f   //e.g. students indexOf "Greg" whenNegative Int.MaxValue
  }
  implicit class IntegralExtensions[A](val x: A)(implicit n: Integral[A]) {
    import scala.collection.immutable.NumericRange, Integral.Implicits._
    def mod(y: A): A = x - ((x / y) * y) //(x/y)*y + (x mod y) == x
    def -->(y: A): NumericRange.Inclusive[A] = NumericRange.inclusive(x, y, if (n.lteq(x, y)) n.one else -n.one)
    def ceilDiv(y: A): A = if (mod(y) == n.zero) x/y else n.one + (x/y)
  }
  implicit def toPoint[A](p: (A, A))(implicit n: Numeric[A]) = new java.awt.geom.Point2D.Double(n.toDouble(p._1), n.toDouble(p._2))
  def desc[A: Ordering]: Ordering[A] = asc[A].reverse  //e.g. students.sortBy(_.height)(desc)
  def asc[A](implicit order: Ordering[A]): Ordering[A] = order
  def map[K] = new {
    def to[V](default: => V): Dict[K, V] = using(_ => default)
    def using[V](f: K => V): Dict[K, V] = new mutable.HashMap[K, V]() {
      override def apply(key: K) = getOrElseUpdate(key, f(key))
    }
  }
  def newMultiMap[K, V] = map[K] to mutable.Set.empty[V]
  def memoize[A, B](f: A => B): A ==> B = map[A] using f
  implicit class FuzzyDouble(val x: Double) extends AnyVal {
    def  >~(y: Double) = x > y + eps
    def >=~(y: Double) = x >= y + eps
    def  ~<(y: Double) = y >=~ x
    def ~=<(y: Double) = y >~ x
    def  ~=(y: Double) = (x distance y) <= eps
  }
  def until(until: Int): Range = 0 until until
  def not[A](f: A => Boolean): A => Boolean = {x: A => !f(x)}
  def assuming[A](cond: => Boolean)(f: => A): A = {require(cond); f}
  @inline def when[A](check: Boolean)(f: => A): Option[A] = if (check) f.some else None
  def repeat[U](n: Int)(f: => U): Unit = (1 to n).foreach(_ => f)
  type of[C[_], A] = scala.collection.generic.CanBuild[A, C[A]]
  type ==>[A, B] = collection.Map[A, B]
  val mod: Int = (1e9 + 7).toInt
  val eps: Double = 1e-9
}
/***********************************[Scala I/O]*********************************************/
import Utils._, java.io._, java.util.StringTokenizer

class IO(in: BufferedReader, out: BufferedWriter) extends Iterator[String] with AutoCloseable with Flushable {
  def this(reader: Reader, writer: Writer) = this(new BufferedReader(reader), new BufferedWriter(writer))
  def this(in: InputStream, out: OutputStream) = this(new InputStreamReader(in), new OutputStreamWriter(out))

  private[this] val tokenizers = Iterator.continually(in.readLine()).takeWhile(_ != null).map(new StringTokenizer(_)).buffered
  val printer = new PrintWriter(out, true)

  @inline private[this] def tokenizer() = {
    while(tokenizers.nonEmpty && !tokenizers.head.hasMoreTokens) tokenizers.next()
    when(tokenizers.nonEmpty)(tokenizers.head)
  }

  def read[A](implicit read: IO.Read[A]): A = read.apply(this)
  def read[C[_], A: IO.Read](n: Int)(implicit b: C of A): C[A] = Iterator.fill(n)(read).to[C]

  def readTill(delim: String): String = tokenizer().get.nextToken(delim)
  def readTillEndOfLine(): String = readTill("\n\r")

  override def next() = tokenizer().get.nextToken()
  override def hasNext = tokenizer().nonEmpty

  def write(obj: Any, more: Any*): this.type = {
    printer.print(obj)
    more foreach {i =>
      printer.print(' ')
      printer.print(i)
    }
    this
  }
  def writeOnNextLine(obj: Any, more: Any*): this.type = {
    printer.println()
    write(obj, more: _*)
    this
  }
  def writeAll(obj: Traversable[Any], separator: String = " "): this.type = write(obj mkString separator)

  override def flush() = printer.flush()
  def close() = {
    flush()
    in.close()
    printer.close()
  }
}
object IO {
  class Read[A](val apply: IO => A) {
    def map[B](f: A => B): Read[B] = new Read(apply andThen f)
  }
  object Read {
    implicit def collection[C[_], A: Read](implicit b: C of A): Read[C[A]]         = new Read(r => r.read[C, A](r.read[Int]))
    implicit val string                                       : Read[String]       = new Read(_.next())
    implicit val char                                         : Read[Char]         = string.map(_.toTraversable.onlyElement)
    implicit val int                                          : Read[Int]          = string.map(_.toInt)
    implicit val long                                         : Read[Long]         = string.map(_.toLong)
    implicit val bigInt                                       : Read[BigInt]       = string.map(BigInt(_))
    implicit val double                                       : Read[Double]       = string.map(_.toDouble)
    implicit val bigDecimal                                   : Read[BigDecimal]   = string.map(BigDecimal(_))
    implicit def tuple2[A: Read, B: Read]                     : Read[(A, B)]       = new Read(r => (r.read[A], r.read[B]))
    implicit def tuple3[A: Read, B: Read, C: Read]            : Read[(A, B, C)]    = new Read(r => (r.read[A], r.read[B], r.read[C]))
    implicit def tuple4[A: Read, B: Read, C: Read, D: Read]   : Read[(A, B, C, D)] = new Read(r => (r.read[A], r.read[B], r.read[C], r.read[D]))
    implicit val boolean                                      : Read[Boolean]      = string map {s =>
      s.toLowerCase match {
        case "yes" | "true" | "1" => true
        case "no" | "false" | "0" => false
        case _ => s.toBoolean
      }
    }
  }
}

import Utils._, annotation.tailrec, collection.mutable, util._, control._, math.Ordering.Implicits._

object _701C extends CodeForcesApp {
  override def apply(io: IO) = {import io.{read, write}
    val (n, houses) = read[(Int, String)]
    val count = map[Char] to 0
    val all = houses.distinct.size

    var l, r = 0
    var ans = Int.MaxValue

    while(r < n) {
      //debug(houses, l, r, count, count.size)
      if(count.size == all) {
        ans = ans min (r - l)
        if (l < n) {
          l += 1
          val h = houses(l)
          count(h) -= 1
          if (count(h) <= 0) count.remove(h)
        }
      } else {
        r += 1
        if (r < n) count(houses(r)) += 1
      }
    }

    write(ans)
  }

}
/****************************[Ignore Template Below]****************************************/
trait CodeForcesApp {
  lazy val isOnlineJudge: Boolean = sys.props.get("ONLINE_JUDGE").exists(_.toBoolean)
  def debug(x: Any): Unit = if (!isOnlineJudge) println(x)
  def apply(io: IO): io.type
  def main(args: Array[String]): Unit = this(new IO(System.in, System.out)).close()
}
object Utils {
  import scala.collection.mutable, mutable.{Map => Dict}
  implicit class GenericExtensions[A](val a: A) extends AnyVal {
    def in(set: collection.Set[A]): Boolean = set(a)
    def some: Option[A] = Some(a)
    def partialMatch[B](f: PartialFunction[A, B]): Option[B] = f lift a
  }
  implicit class TraversableExtensions[A, C[X] <: Traversable[X]](val t: C[A]) extends AnyVal {
    def onlyElement: A = assuming(t.size == 1)(t.head)
    def groupByIdentifier[K](f: A => K): Map[K, A] = t.groupBy(f).mapValues(_.onlyElement)
    def duplicates(implicit b: C of A): C[A] = {
      val elems = mutable.Set.empty[A]
      (t collect {case i if !elems.add(i) => i}).to[C]
    }
    def sumWith[B](f: A => B)(implicit n: Numeric[B]): B = t.foldLeft(n.zero) {case (p, i) => n.plus(p, f(i))}
    def zipWith[B](f: A => B)(implicit b: C of (A, B)): C[(A, B)] = (t map {i => i -> f(i)}).to[C]
    def mapTo[B](f: A => B)(implicit b: C of (A, B)): Map[A, B] = zipWith(f).toUniqueMap
    def whenNonEmpty[B](f: t.type => B): Option[B] = when(t.nonEmpty)(f(t))  // e.g. grades.whenNonEmpty(_.max)
    def collectFirst[B](f: PartialFunction[A, Option[B]]): Option[B] = t.view collect f collectFirst {case Some(x) => x}
    def toMutableMultiSet: Dict[A, Int] = {
      val c = map[A] to 0
      t.foreach(i => c(i) += 1)
      c
    }
    def toMultiSet: Map[A, Int] = toMutableMultiSet.toMap withDefaultValue 0
    def X[B](s: Traversable[B]): Iterator[(A, B)] = for {a <- t.toIterator; b <- s} yield (a, b)
  }
  implicit class ArrayExtensions[A <: AnyRef](val a: Array[A]) extends AnyVal {
    def sort(from: Int, until: Int)(implicit cmp: Ordering[A]): Unit = java.util.Arrays.sort(a, from, until, cmp) //sort [from, until)
  }
  implicit class ArrayExtensions2[A](val a: Array[A]) extends AnyVal {
    def sort(from: Int, until: Int)(implicit cmp: Ordering[A]): Unit = a.view(from, until).sorted.copyToArray(a, from)
  }
  implicit class SeqExtensions[A, C[X] <: Seq[X]](val s: C[A]) extends AnyVal {
    def isRotationOf(t: Seq[A]): Boolean = s ++ s containsSlice t
  }
  implicit class PairExtensions[A, B](val p: (A, B)) extends AnyVal {
    def key = p._1
    def value = p._2
  }
  implicit class PairsExtensions[A, B, C[X] <: Traversable[X]](t: C[(A, B)]) {
    def toUniqueMap: Map[A, B] = t.groupByIdentifier(_.key).mapValues(_.value)
    def toMultiMap(implicit b: C of B): Map[A, C[B]] = t.groupBy(_.key).mapValues(_.map(_.value).to[C])
    def swap(implicit b: C of (B, A)): C[(B, A)] = t.map(_.swap).to[C]
  }
  implicit class MapExtensions[K, V, C[X, Y] <: Map[X, Y]](val m: C[K, V]) extends AnyVal {
    def lastKeyOption: Option[K] = m.lastOption.map(_.key)
    def firstKeyOption: Option[K] = m.headOption.map(_.key)
    def invert: Map[V, Set[K]] = m.toSet[(K, V)].swap.toMultiMap
    def mapKeys[K2](f: K => K2): Map[K2, V] = m map {case (k, v) => f(k) -> v}
    def toMutable: Dict[K, V] = Dict.empty[K, V] ++ m
  }
  implicit class MutableMapExtensions[K, V](val m: mutable.Map[K, V]) extends AnyVal {
    def removeLast(): Option[(K, V)] = m.lastOption.map(removeNode)
    def removeFirst(): Option[(K, V)] = m.headOption.map(removeNode)
    private def removeNode(kv: (K, V)): (K, V) = {
      m -= kv.key
      kv
    }
  }
  implicit class SetExtensions[A, C[A] <: Set[A]](val s: C[A]) extends AnyVal {
    def notContains(x: A): Boolean = !(s contains x)
    def toMutable = mutable.Set.empty[A] ++ s
  }
  implicit class IterableExtensions[A, C[A] <: Seq[A]](val s: C[A]) extends AnyVal {
    def deleteAtIndex(i: Int, howMany: Int = 1) = s.patch(i, Nil, howMany)
    def insertAtIndex(i: Int, items: Seq[A]) = s.patch(i, items, 0)
    def findWithIndex(f: A => Boolean): Option[(A, Int)] = s.zipWithIndex find {case (a, _) => f(a)}
    def foldUntil[B](z: B)(f: (B, A) => B)(c: B => Boolean): Option[(B, Int)] = s.view.scanLeft(z)(f).findWithIndex(c)
  }
  implicit class BooleanExtensions(val x: Boolean) extends AnyVal {
    def to[A](implicit n: Numeric[A]) = if(x) n.one else n.zero
    def toEnglish = if(x) "YES" else "NO"
  }
  implicit class IntExtensions(val x: Int) extends AnyVal {
    import java.lang.{Integer => JInt}
    def withHighestOneBit: Int = JInt.highestOneBit(x)
    def withLowestOneBit: Int = JInt.lowestOneBit(x)
    def numberOfLeadingZeroes: Int = JInt.numberOfLeadingZeros(x)
    def numberOfTrailingZeroes: Int = JInt.numberOfTrailingZeros(x)
    def bitCount: Int = JInt.bitCount(x)
    def setLowestBits(n: Int): Int = x | (left(n) - 1)
    def clearLowestBits(n: Int): Int = x & left(n, ~0)
    def setBit(i: Int, set: Boolean): Int = if (set) setBit(i) else clearBit(i)
    def setBit(i: Int): Int = x | left(i)
    def clearBit(i: Int): Int = x & ~left(i)
    def toggleBit(i: Int): Int = x ^ left(i)
    def testBit(i: Int): Boolean = ((x >> i) & 1) == 1
    private def left(bits: Int, num: Int = 1) = assuming(bits >= 0 && bits < JInt.SIZE)(num << bits)
    def X(y: Int): Iterator[(Int, Int)] = until(x) X until(y)
  }
  implicit class LongExtensions(val x: Long) extends AnyVal {
    import java.lang.{Long => JLong}
    def withHighestOneBitSet: Long = JLong.highestOneBit(x)
    def withLowestOneBitSet: Long = JLong.lowestOneBit(x)
    def numberOfLeadingZeroes: Int = JLong.numberOfLeadingZeros(x)
    def numberOfTrailingZeroes: Int = JLong.numberOfTrailingZeros(x)
    def bitCount: Int = JLong.bitCount(x)
    def setLowestBits(n: Int): Long = x | (left(n) - 1)
    def clearLowestBits(n: Int): Long = x & left(n, ~0L)
    def setBit(i: Int, set: Boolean): Long = if (set) setBit(i) else clearBit(i)
    def setBit(i: Int): Long = x | left(i)
    def clearBit(i: Int): Long = x & ~left(i)
    def toggleBit(i: Int): Long = x ^ left(i)
    def testBit(i: Int): Boolean = ((x >> i) & 1) == 1
    private def left(bits: Int, num: Long = 1L) = assuming(bits >= 0 && bits < JLong.SIZE)(num << bits)
  }
  implicit class NumericExtensions[A](val x: A)(implicit n: Numeric[A]) {
    import Numeric.Implicits._
    def **(i: Int): A = if (i == 0) n.one else {
      val h = x ** (i/2)
      if (i%2 == 0) h * h else h * h * x
    }
    def distance(y: A) = (x - y).abs()
    def nonNegative: Option[A] = when(n.gteq(x, n.zero))(x)
    def whenNegative(f: => A): A = nonNegative getOrElse f   //e.g. students indexOf "Greg" whenNegative Int.MaxValue
  }
  implicit class IntegralExtensions[A](val x: A)(implicit n: Integral[A]) {
    import scala.collection.immutable.NumericRange, Integral.Implicits._
    def mod(y: A): A = x - ((x / y) * y) //(x/y)*y + (x mod y) == x
    def -->(y: A): NumericRange.Inclusive[A] = NumericRange.inclusive(x, y, if (n.lteq(x, y)) n.one else -n.one)
    def ceilDiv(y: A): A = if (mod(y) == n.zero) x/y else n.one + (x/y)
  }
  implicit def toPoint[A](p: (A, A))(implicit n: Numeric[A]) = new java.awt.geom.Point2D.Double(n.toDouble(p._1), n.toDouble(p._2))
  def desc[A: Ordering]: Ordering[A] = asc[A].reverse  //e.g. students.sortBy(_.height)(desc)
  def asc[A](implicit order: Ordering[A]): Ordering[A] = order
  def map[K] = new {
    def to[V](default: => V): Dict[K, V] = using(_ => default)
    def using[V](f: K => V): Dict[K, V] = new mutable.HashMap[K, V]() {
      override def apply(key: K) = getOrElseUpdate(key, f(key))
    }
  }
  def newMultiMap[K, V] = map[K] to mutable.Set.empty[V]
  def memoize[A, B](f: A => B): A ==> B = map[A] using f
  implicit class FuzzyDouble(val x: Double) extends AnyVal {
    def  >~(y: Double) = x > y + eps
    def >=~(y: Double) = x >= y + eps
    def  ~<(y: Double) = y >=~ x
    def ~=<(y: Double) = y >~ x
    def  ~=(y: Double) = (x distance y) <= eps
  }
  def until(until: Int): Range = 0 until until
  def not[A](f: A => Boolean): A => Boolean = {x: A => !f(x)}
  def assuming[A](cond: => Boolean)(f: => A): A = {require(cond); f}
  @inline def when[A](check: Boolean)(f: => A): Option[A] = if (check) f.some else None
  def repeat[U](n: Int)(f: => U): Unit = (1 to n).foreach(_ => f)
  type of[C[_], A] = scala.collection.generic.CanBuild[A, C[A]]
  type ==>[A, B] = collection.Map[A, B]
  val mod: Int = (1e9 + 7).toInt
  val eps: Double = 1e-9
}
/***********************************[Scala I/O]*********************************************/
import Utils._, java.io._, java.util.StringTokenizer

class IO(in: BufferedReader, out: BufferedWriter) extends Iterator[String] with AutoCloseable with Flushable {
  def this(reader: Reader, writer: Writer) = this(new BufferedReader(reader), new BufferedWriter(writer))
  def this(in: InputStream, out: OutputStream) = this(new InputStreamReader(in), new OutputStreamWriter(out))

  private[this] val tokenizers = Iterator.continually(in.readLine()).takeWhile(_ != null).map(new StringTokenizer(_)).buffered
  val printer = new PrintWriter(out, true)

  @inline private[this] def tokenizer() = {
    while(tokenizers.nonEmpty && !tokenizers.head.hasMoreTokens) tokenizers.next()
    when(tokenizers.nonEmpty)(tokenizers.head)
  }

  def read[A](implicit read: IO.Read[A]): A = read.apply(this)
  def read[C[_], A: IO.Read](n: Int)(implicit b: C of A): C[A] = Iterator.fill(n)(read).to[C]

  def readTill(delim: String): String = tokenizer().get.nextToken(delim)
  def readTillEndOfLine(): String = readTill("\n\r")

  override def next() = tokenizer().get.nextToken()
  override def hasNext = tokenizer().nonEmpty

  def write(obj: Any, more: Any*): this.type = {
    printer.print(obj)
    more foreach {i =>
      printer.print(' ')
      printer.print(i)
    }
    this
  }
  def writeOnNextLine(obj: Any, more: Any*): this.type = {
    printer.println()
    write(obj, more: _*)
    this
  }
  def writeAll(obj: Traversable[Any], separator: String = " "): this.type = write(obj mkString separator)

  override def flush() = printer.flush()
  def close() = {
    flush()
    in.close()
    printer.close()
  }
}
object IO {
  class Read[A](val apply: IO => A) {
    def map[B](f: A => B): Read[B] = new Read(apply andThen f)
  }
  object Read {
    implicit def collection[C[_], A: Read](implicit b: C of A): Read[C[A]]         = new Read(r => r.read[C, A](r.read[Int]))
    implicit val string                                       : Read[String]       = new Read(_.next())
    implicit val char                                         : Read[Char]         = string.map(_.toTraversable.onlyElement)
    implicit val int                                          : Read[Int]          = string.map(_.toInt)
    implicit val long                                         : Read[Long]         = string.map(_.toLong)
    implicit val bigInt                                       : Read[BigInt]       = string.map(BigInt(_))
    implicit val double                                       : Read[Double]       = string.map(_.toDouble)
    implicit val bigDecimal                                   : Read[BigDecimal]   = string.map(BigDecimal(_))
    implicit def tuple2[A: Read, B: Read]                     : Read[(A, B)]       = new Read(r => (r.read[A], r.read[B]))
    implicit def tuple3[A: Read, B: Read, C: Read]            : Read[(A, B, C)]    = new Read(r => (r.read[A], r.read[B], r.read[C]))
    implicit def tuple4[A: Read, B: Read, C: Read, D: Read]   : Read[(A, B, C, D)] = new Read(r => (r.read[A], r.read[B], r.read[C], r.read[D]))
    implicit val boolean                                      : Read[Boolean]      = string map {s =>
      s.toLowerCase match {
        case "yes" | "true" | "1" => true
        case "no" | "false" | "0" => false
        case _ => s.toBoolean
      }
    }
  }
}

import java.util.Scanner

object Main{
  def main (args: Array[String]){
    val sc = new Scanner(System.in)
    val n = sc.nextInt()
    sc.nextLine()
    val s = sc.nextLine()

    //
    val dp = new Array[Int](58)
    val vol = 65
    var cnt = 0

    for(c <- s){
      if(dp(c.toInt - vol) == 0)
        cnt += 1

      dp(c.toInt - vol) += 1
    }

    var ans = 0
    var flag1 = false  // start
    var flag2 = false  // end

    for(c <- s){
      if(!flag2){
        val now = c.toInt - vol

        if(flag1){
          ans += 1
          if(dp(now) != 0){
            dp(now) = 0
            cnt -= 1
            if(cnt == 0)
              flag2 = true
          }
        }
        else{
          if(dp(now) == 1){
            cnt -= 1
            ans += 1
            flag1 = true
            dp(now) = 0
          }
          else
            dp(now) -= 1
        }
      }
    }

    println(ans)
  }
}