(eval-when (:compile-toplevel :load-toplevel :execute)
  (sb-int:defconstant-eqx opt
    #+swank '(optimize (speed 3) (safety 2))
    #-swank '(optimize (speed 3) (safety 0) (debug 0))
    #'equal)
  #+swank (ql:quickload '(:cl-debug-print :fiveam) :silent t)
  #-swank (set-dispatch-macro-character
           #\# #\> (lambda (s c p) (declare (ignore c p)) `(values ,(read s nil nil t)))))
#+swank (cl-syntax:use-syntax cl-debug-print:debug-print-syntax)
#-swank (disable-debugger) ; for CS Academy

;; BEGIN_INSERTED_CONTENTS
;;;
;;; Maximum bipartite matching (Hopcroft-Karp, O(E sqrt(V)))
;;;

;; NOTE: The number of elements in the graph must be less than 2^32-1 as we use
;; (UNSIGNED-BYTE 32) here for efficiency.

;; NOTE: Pay attention to the stack size!

(defconstant +graph-inf-distance+ #xffffffff)

(defstruct (bipartite-graph
            (:constructor make-bgraph
                (size1
                 size2
                 &aux
                 (graph1 (make-array size1 :element-type 'list :initial-element nil))
                 (levels1 (make-array size1 :element-type '(unsigned-byte 32)))
                 (levels2 (make-array size2 :element-type '(unsigned-byte 32)))
                 (matching1 (make-array size1 :element-type 'fixnum :initial-element -1))
                 (matching2 (make-array size2 :element-type 'fixnum :initial-element -1))
                 (queue (make-array (+ size1 size2) :element-type '(unsigned-byte 32)))))
            (:conc-name bgraph-))
  (size1 0 :type (unsigned-byte 32))
  (size2 0 :type (unsigned-byte 32))
  (graph1 nil :type (simple-array list (*)))
  (levels1 nil :type (simple-array (unsigned-byte 32) (*)))
  (levels2 nil :type (simple-array (unsigned-byte 32) (*)))
  (matching1 nil :type (simple-array fixnum (*)))
  (matching2 nil :type (simple-array fixnum (*)))
  (queue nil :type (simple-array (unsigned-byte 32) (*))))

(declaim (inline bgraph-add-edge!))
(defun bgraph-add-edge! (bgraph vertex1 vertex2)
  (push vertex2 (aref (bgraph-graph1 bgraph) vertex1))
  bgraph)

(defun %fill-levels (bgraph)
  "Does BFS and fills LEVELS."
  (declare (optimize (speed 3) (safety 0)))
  (let ((graph1 (bgraph-graph1 bgraph))
        (matching1 (bgraph-matching1 bgraph))
        (matching2 (bgraph-matching2 bgraph))
        (levels1 (bgraph-levels1 bgraph))
        (levels2 (bgraph-levels2 bgraph))
        (queue (bgraph-queue bgraph))
        (q-front 0)
        (q-end 0)
        (found nil))
    (declare ((integer 0 #.most-positive-fixnum) q-front q-end))
    (labels ((enqueue (obj)
               (setf (aref queue q-end) obj)
               (incf q-end))
             (dequeue ()
               (prog1 (aref queue q-front)
                 (incf q-front))))
      (declare (inline enqueue dequeue))
      (fill levels1 +graph-inf-distance+)
      (fill levels2 +graph-inf-distance+)
      (dotimes (i (bgraph-size1 bgraph))
        (when (= -1 (aref matching1 i))
          (setf (aref levels1 i) 0)
          (enqueue i)))
      (loop until (= q-front q-end)
            for vertex = (dequeue)
            do (dolist (next (aref graph1 vertex))
                 (when (= +graph-inf-distance+ (aref levels2 next))
                   (setf (aref levels2 next) (+ 1 (aref levels1 vertex)))
                   (let ((partner (aref matching2 next)))
                     (when (= -1 partner)
                       (setq found t)
                       (return))
                     (setf (aref levels1 partner) (+ 1 (aref levels2 next)))
                     (enqueue partner))))))
    found))

(defun %find-matching (bgraph src)
  "Does DFS and makes matching greedily on the residual network."
  (declare (optimize (speed 3) (safety 0))
           ((integer 0 #.most-positive-fixnum) src))
  (let ((matching1 (bgraph-matching1 bgraph))
        (matching2 (bgraph-matching2 bgraph))
        (levels1 (bgraph-levels1 bgraph))
        (levels2 (bgraph-levels2 bgraph))
        (graph1 (bgraph-graph1 bgraph)))
    (labels ((dfs (v)
               (declare ((integer 0 #.most-positive-fixnum) v))
               (dolist (next (aref graph1 v))
                 (when (= (aref levels2 next) (+ 1 (aref levels1 v)))
                   (setf (aref levels2 next) +graph-inf-distance+) ; mark visited
                   (let ((partner (aref matching2 next)))
                     (when (or (= -1 partner) (dfs partner))
                       (setf (aref matching1 v) next
                             (aref matching2 next) v
                             (aref levels1 v) +graph-inf-distance+ ; mark visited
                             )
                       (return-from dfs t)))))
               (setf (aref levels1 v) +graph-inf-distance+) ; mark visited
               nil ; not matched
               ))
      (dfs src))))

(declaim (ftype (function * (values (unsigned-byte 32) &optional)) bgraph-build-matching!))
(defun bgraph-build-matching! (bgraph)
  "Makes a maximum bipartite matching and returns two vectors: correspondence
from group 1 to group 2, and correspondence from group 2 to group 1. At an
unmatched vertex, -1 is stored."
  (declare (optimize (speed 3)))
  (let* ((size1 (bgraph-size1 bgraph))
         (matching1 (bgraph-matching1 bgraph))
         (count 0))
    (declare ((integer 0 #.most-positive-fixnum) count))
    (loop while (%fill-levels bgraph)
          do (dotimes (v size1)
               (when (and (= -1 (aref matching1 v))
                          (%find-matching bgraph v))
                 (incf count))))
    count))

;; not tested
(declaim (ftype (function * (values (simple-array (integer 0 #.most-positive-fixnum) (*))
                                    (simple-array (integer 0 #.most-positive-fixnum) (*))
                                    &optional))
                bgraph-decompose!))
(defun bgraph-decompose (bgraph)
  "Decomposes a residual network to strongly connected components by Tarjan's
algorithm. BGRAPH-BUILD-MATCHING! must be called beforehand."
  (declare (optimize (speed 3)))
  (let* ((size1 (bgraph-size1 bgraph))
         (size2 (bgraph-size2 bgraph))
         (total-size (+ size1 size2 2))
         (source (+ size1 size2))
         (sink (+ size1 size2 1))
         (graph1 (bgraph-graph1 bgraph))
         (matching1 (bgraph-matching1 bgraph))
         (matching2 (bgraph-matching2 bgraph))
         (ord 0) ; in-order
         (ords (make-array total-size :element-type 'fixnum :initial-element -1))
         (lowlinks (make-array total-size :element-type 'fixnum))
         (components (make-array total-size
                                 :element-type '(integer 0 #.most-positive-fixnum)))
         (comp-index 0) ; index number of component
         (sizes (make-array total-size
                            :element-type '(integer 0 #.most-positive-fixnum)
                            :initial-element 0))
         (stack (make-array total-size :element-type '(integer 0 #.most-positive-fixnum)))
         (end 0) ; stack pointer
         (in-stack (make-array total-size :element-type 'bit :initial-element 0)))
    (declare ((integer 0 #.most-positive-fixnum) ord end comp-index source sink total-size))
    (labels ((%push (v)
               (setf (aref stack end) v
                     (aref in-stack v) 1)
               (incf end))
             (%pop ()
               (decf end)
               (let ((v (aref stack end)))
                 (setf (aref in-stack v) 0)
                 v))
             (frob (v next)
               (cond ((= -1 (aref ords next))
                      (visit next)
                      (setf (aref lowlinks v)
                            (min (aref lowlinks v) (aref lowlinks next))))
                     ((= 1 (aref in-stack next))
                      (setf (aref lowlinks v)
                            (min (aref lowlinks v) (aref ords next))))))
             (visit (v)
               (setf (aref ords v) ord
                     (aref lowlinks v) ord)
               (incf ord)
               (%push v)
               (cond ((= v source)
                      (loop for next below size1
                            when (= -1 (aref matching1 next))
                            do (frob v next)))
                     ((= v sink)
                      (loop for next below size2
                            unless (= -1 (aref matching2 next))
                            do (frob v (+ size1 next))))
                     ((and (< v size1) (= -1 (aref matching1 v)))
                      (dolist (next (aref graph1 v))
                        (declare ((integer 0 #.most-positive-fixnum) next))
                        (frob v (+ next size1))))
                     ((and (< v size1) (/= -1 (aref matching1 v)))
                      (frob v source)
                      (dolist (next (aref graph1 v))
                        (declare ((integer 0 #.most-positive-fixnum) next))
                        (unless (= next (aref matching1 v))
                          (frob v (+ next size1)))))
                     ((= -1 (aref matching2 (- v size1)))
                      (frob v sink))
                     (t
                      ;; (assert (/= -1 (aref matching2 (- v size1))))
                      (frob v (aref matching2 (- v size1)))))
               (when (= (aref lowlinks v) (aref ords v))
                 (loop for size of-type (integer 0 #.most-positive-fixnum) from 1
                       for w = (%pop)
                       do (setf (aref components w) comp-index)
                       until (= v w)
                       finally (setf (aref sizes comp-index) size)
                               (incf comp-index)))))
      (dotimes (v total-size)
        (when (= -1 (aref ords v))
          (visit v)))
      (values (subseq components 0 size1)
              (subseq components size1 (+ size1 size2))))))

;; PAY ATTENTION TO THE STACK SIZE!
(declaim (inline bipartite-p)
         (ftype (function * (values (or null simple-bit-vector) &optional)) bipartite-p))
(defun bipartite-p (graph)
  "Checks if GRAPH is bipartite and returns the vector of colorings if so,
otherwise returns NIL.

GRAPH := vector of adjacency lists"
  (declare (vector graph))
  (let* ((n (length graph))
         (visited (make-array n :element-type 'bit :initial-element 0))
         (colors (make-array n :element-type 'bit :initial-element 0)))
    (labels ((dfs (vertex color)
               (cond ((zerop (aref visited vertex))
                      (setf (aref visited vertex) 1
                            (aref colors vertex) color)
                      (if (= color 1)
                          (dolist (neighbor (aref graph vertex))
                            (dfs neighbor 0))
                          (dolist (neighbor (aref graph vertex))
                            (dfs neighbor 1))))
                     ((/= color (aref colors vertex))
                      (return-from bipartite-p nil)))))
      (dotimes (i n colors)
        (when (zerop (aref visited i))
          (dfs i 1))))))

(declaim (ftype (function * (values fixnum &optional)) read-fixnum))
(defun read-fixnum (&optional (in *standard-input*))
  "NOTE: cannot read -2^62"
  (macrolet ((%read-byte ()
               `(the (unsigned-byte 8)
                     #+swank (char-code (read-char in nil #\Nul))
                     #-swank (sb-impl::ansi-stream-read-byte in nil #.(char-code #\Nul) nil))))
    (let* ((minus nil)
           (result (loop (let ((byte (%read-byte)))
                           (cond ((<= 48 byte 57)
                                  (return (- byte 48)))
                                 ((zerop byte) ; #\Nul
                                  (error "Read EOF or #\Nul."))
                                 ((= byte #.(char-code #\-))
                                  (setq minus t)))))))
      (declare ((integer 0 #.most-positive-fixnum) result))
      (loop
        (let* ((byte (%read-byte)))
          (if (<= 48 byte 57)
              (setq result (+ (- byte 48)
                              (* 10 (the (integer 0 #.(floor most-positive-fixnum 10))
                                         result))))
              (return (if minus (- result) result))))))))

;;;
;;; Queue with singly linked list
;;;

(defstruct (queue (:constructor make-queue
                      (&optional list &aux (tail (last list)))))
  (list nil :type list)
  (tail nil :type list))

(declaim (inline enqueue))
(defun enqueue (obj queue)
  "Pushes OBJ to the end of QUEUE."
  (symbol-macrolet ((list (queue-list queue))
                    (tail (queue-tail queue)))
    (if (null list)
        (setf tail (list obj)
              list tail)
        (setf (cdr tail) (list obj)
              tail (cdr tail))))
  queue)

(declaim (inline dequeue))
(defun dequeue (queue)
  "Removes and returns the element at the front of QUEUE. Returns NIL if QUEUE
is empty."
  (pop (queue-list queue)))

(declaim (inline queue-empty-p))
(defun queue-empty-p (queue)
  (null (queue-list queue)))

(declaim (inline queue-peek))
(defun queue-peek (queue)
  (car (queue-list queue)))

(declaim (inline enqueue-front))
(defun enqueue-front (obj queue)
  "Pushes OBJ to the front of QUEUE."
  (symbol-macrolet ((list (queue-list queue))
                    (tail (queue-tail queue)))
    (if (null list)
        (setf tail (list obj)
              list tail)
        (push obj list))
    queue))

(in-package :cl-user)

(defmacro dbg (&rest forms)
  #+swank
  (if (= (length forms) 1)
      `(format *error-output* "~A => ~A~%" ',(car forms) ,(car forms))
      `(format *error-output* "~A => ~A~%" ',forms `(,,@forms)))
  #-swank (declare (ignore forms)))

(defmacro define-int-types (&rest bits)
  `(progn
     ,@(mapcar (lambda (b) `(deftype ,(intern (format nil "UINT~A" b)) () '(unsigned-byte ,b))) bits)
     ,@(mapcar (lambda (b) `(deftype ,(intern (format nil "INT~A" b)) () '(signed-byte ,b))) bits)))
(define-int-types 2 4 7 8 15 16 31 32 62 63 64)

(declaim (inline println))
(defun println (obj &optional (stream *standard-output*))
  (let ((*read-default-float-format* 'double-float))
    (prog1 (princ obj stream) (terpri stream))))

(defconstant +mod+ 1000000007)

;;;
;;; Body
;;;

(defun main ()
  (let* ((n (read))
         (graph (make-array n :element-type 'list :initial-element nil))
         (as (make-array n :element-type 'uint31 :initial-element 0))
         (bs (make-array n :element-type 'uint31 :initial-element 0)))
    (dotimes (i (- n 1))
      (let ((a (- (read-fixnum) 1))
            (b (- (read-fixnum) 1)))
        (push a (aref graph b))
        (push b (aref graph a))
        (setf (aref as i) a
              (aref bs i) b)))
    (let ((colors (bipartite-p graph))
          (maps (make-array n :element-type 'int32 :initial-element 0))
          (size0 0)
          (size1 0))
      (dotimes (i n)
        (if (zerop (aref colors i))
            (progn (setf (aref maps i) size0)
                   (incf size0))
            (progn (setf (aref maps i) size1)
                   (incf size1))))
      (let ((bgraph (make-bgraph size0 size1)))
        (loop for a across as
              for b across bs
              when (zerop (aref colors a))
              do (bgraph-add-edge! bgraph (aref maps a) (aref maps b))
              else do (bgraph-add-edge! bgraph (aref maps b) (aref maps a)))
        (let ((res (bgraph-build-matching! bgraph)))
          (write-line
           (if (= (* res 2) n)
               "Second"
               "First")))))))

#-swank (main)

;;;
;;; Test and benchmark
;;;

#+swank
(defun io-equal (in-string out-string &key (function #'main) (test #'equal))
  "Passes IN-STRING to *STANDARD-INPUT*, executes FUNCTION, and returns true if
the string output to *STANDARD-OUTPUT* is equal to OUT-STRING."
  (labels ((ensure-last-lf (s)
             (if (eql (uiop:last-char s) #\Linefeed)
                 s
                 (uiop:strcat s uiop:+lf+))))
    (funcall test
             (ensure-last-lf out-string)
             (with-output-to-string (out)
               (let ((*standard-output* out))
                 (with-input-from-string (*standard-input* (ensure-last-lf in-string))
                   (funcall function)))))))

#+swank
(defun get-clipbrd ()
  (with-output-to-string (out)
    (run-program "powershell.exe" '("-Command" "Get-Clipboard") :output out :search t)))

#+swank (defparameter *this-pathname* (uiop:current-lisp-file-pathname))
#+swank (defparameter *dat-pathname* (uiop:merge-pathnames* "test.dat" *this-pathname*))

#+swank
(defun run (&optional thing (out *standard-output*))
  "THING := null | string | symbol | pathname

null: run #'MAIN using the text on clipboard as input.
string: run #'MAIN using the string as input.
symbol: alias of FIVEAM:RUN!.
pathname: run #'MAIN using the text file as input."
  (let ((*standard-output* out))
    (etypecase thing
      (null
       (with-input-from-string (*standard-input* (delete #\Return (get-clipbrd)))
         (main)))
      (string
       (with-input-from-string (*standard-input* (delete #\Return thing))
         (main)))
      (symbol (5am:run! thing))
      (pathname
       (with-open-file (*standard-input* thing)
         (main))))))

#+swank
(defun gen-dat ()
  (uiop:with-output-file (out *dat-pathname* :if-exists :supersede)
    (format out "")))

#+swank
(defun bench (&optional (out (make-broadcast-stream)))
  (time (run *dat-pathname* out)))

;; To run: (5am:run! :sample)
#+swank
(it.bese.fiveam:test :sample
  (it.bese.fiveam:is
   (common-lisp-user::io-equal "3
1 2
2 3
"
    "First
"))
  (it.bese.fiveam:is
   (common-lisp-user::io-equal "4
1 2
2 3
2 4
"
    "First
"))
  (it.bese.fiveam:is
   (common-lisp-user::io-equal "6
1 2
2 3
3 4
2 5
5 6
"
    "Second
")))


Measured memory_bytes: 53988