(eval-when (:compile-toplevel :load-toplevel :execute)
  (defparameter OPT
    #+swank '(optimize (speed 3) (safety 2))
    #-swank '(optimize (speed 3) (safety 0) (debug 0)))
  #+swank (progn (ql:quickload '(:cl-debug-print :fiveam))
                 (shadow :run)
                 (use-package :fiveam)))
#+swank (cl-syntax:use-syntax cl-debug-print:debug-print-syntax)

;; BEGIN_INSERTED_CONTENTS
(declaim (inline read-line-into))
(defun read-line-into (buf-str &key (in *standard-input*) (terminate-char #\Space))
  (declare (simple-base-string buf-str))
  (loop for ch of-type base-char =
           #-swank (code-char (read-byte in nil #\Newline))
           #+swank (read-char in nil #\Newline)
        for idx = 0 then (1+ idx)
        until (char= ch #\Newline)
        do (setf (schar buf-str idx) ch)
        finally (setf (schar buf-str idx) terminate-char)
                (return buf-str)))

(defstruct (union-find-tree
            (:constructor make-union-find-tree
                (size
                 &aux
                 (parents (let ((arr (make-array size :element-type '(integer 0 #.most-positive-fixnum))))
                            (dotimes (i size arr) (setf (aref arr i) i))))
                 (ranks (make-array size :element-type '(integer 0 #.most-positive-fixnum)
                                         :initial-element 0)))))
  (parents nil :type (simple-array (integer 0 #.most-positive-fixnum) (*)))
  (ranks nil :type (simple-array (integer 0 #.most-positive-fixnum) (*))))

(declaim (ftype (function * (values (integer 0 #.most-positive-fixnum) &optional)) uf-root))
(defun uf-root (index uf-tree)
  "Returns the root of INDEX."
  (declare #.OPT ((integer 0 #.most-positive-fixnum) index))
  (let ((parents (union-find-tree-parents uf-tree)))
    (if (= index (aref parents index))
        index
        (setf (aref parents index)
              (uf-root (aref parents index) uf-tree)))))

(declaim (inline uf-union!))
(defun uf-union! (index1 index2 uf-tree)
  "Unites INDEX1 and INDEX2 destructively."
  (let ((root1 (uf-root index1 uf-tree))
        (root2 (uf-root index2 uf-tree))
        (parents (union-find-tree-parents uf-tree))
        (ranks (union-find-tree-ranks uf-tree)))
    (cond ((= root1 root2) nil)
          ((< (aref ranks root1) (aref ranks root2))
           (setf (aref parents root1) root2))
          ((= (aref ranks root1) (aref ranks root2))
           (setf (aref parents root2) root1)
           (incf (aref ranks root1)))
          (t (setf (aref parents root2) root1)))))

(declaim (inline uf-same-p))
(defun uf-same-p (index1 index2 uf-tree)
  "Checks if INDEX1 and INDEX2 have the same root."
  (= (uf-root index1 uf-tree) (uf-root index2 uf-tree)))

(defmacro split-ints-and-bind (arg-lst string &body body)
  (let ((pos1 (gensym "POS"))
	(pos2 (gensym "POS"))
	(str (gensym "STR")))
    (labels ((expand (arg-lst &optional (init-pos1 t))
	       (if (null arg-lst)
		   body
		   `((let* ((,pos1 ,(if init-pos1 0 `(1+ ,pos2)))
			    (,pos2 (position #\space ,str :start ,pos1 :test #'char=))
			    (,(car arg-lst) (parse-integer ,str :start ,pos1 :end ,pos2)))
		       ,@(expand (cdr arg-lst) nil))))))
      `(let ((,str ,string))
         (declare (string ,str))
	 ,@(expand arg-lst)))))

(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 4 7 8 15 16 31 32 62 63 64)

(defmacro println (obj &optional (stream '*standard-output*))
  `(let ((*read-default-float-format* 'double-float))
     (prog1 (princ ,obj ,stream) (terpri ,stream))))

;; Hauptteil

(defun main ()
  (declare #.OPT)
  (let* ((n (read))
         (k (read))
         (l (read))
         (tree-roads (make-union-find-tree n))
         (tree-rails (make-union-find-tree n))
         (group-size-table (make-hash-table :test #'equal))
         (buf (make-string 15 :element-type 'standard-char :initial-element #\Space))
         (out (make-string-output-stream :element-type 'standard-char)))
    (declare (uint32 n k l))
    (dotimes (i k)
      (split-ints-and-bind (p q) (read-line-into buf)
        (declare (uint32 p q))
        (uf-union! (- p 1) (- q 1) tree-roads)))
    (dotimes (i l)
      (split-ints-and-bind (r s) (read-line-into buf)
        (declare (uint32 r s))
        (uf-union! (- r 1) (- s 1) tree-rails)))
    (dotimes (idx n)
      (let ((r-pair (cons (uf-root idx tree-roads) (uf-root idx tree-rails))))
        (if (gethash r-pair group-size-table)
            (incf (the uint32 (gethash r-pair group-size-table)))
            (setf (gethash r-pair group-size-table) 1))))
    (dotimes (idx (- n 1))
      (let ((r-pair (cons (uf-root idx tree-roads) (uf-root idx tree-rails))))
        (princ (gethash r-pair group-size-table) out)
        (princ #\Space out)))
    (println (gethash (cons (uf-root (- n 1) tree-roads) (uf-root (- n 1) tree-rails))
                      group-size-table)
             out)
    (write-string (get-output-stream-string out))))

#-swank(main)


Measured memory_bytes: 58472