import Control.Arrow
import Data.List
import Data.Function
import qualified Data.ByteString.Char8 as B
import qualified Data.IntMap.Strict as M

untilFix :: Eq t => (t -> t) -> t -> t
untilFix f x = let x1 = f x in if x1 == x then x else untilFix f x1

readInt :: B.ByteString -> Int
readInt = maybe undefined fst . B.readInt

readIntPair :: [B.ByteString] -> [(Int, Int)]
readIntPair = map (pair . map readInt . B.words)

pair :: [t] -> (t, t)
pair [x, y] = (x, y)
pair _ = undefined

main = do
  [n, k, l] <- map read . words <$> getLine
  (b1, b2) <- splitAt k . B.lines <$> B.getContents
  let ps1 = readIntPair b1
  let ps2 = readIntPair b2
  putStrLn $ unwords $ map show (connectivity n ps1 ps2)

connectivity n ps1 ps2 =  $ filter ((==2) . length) $ group $ sort (n1 ++ n2)
  where
    n1 = concatMap (\g -> map (\(i,_) -> (i, map snd g)) g) $ groupBy ((==) `on` snd) $ sortOn snd $ map (id &&& rep uf1) [1 .. n]
    n2 = map (id &&& rep uf2) [1 .. n]
    uf1 = foldr (\(p,q) uf -> merge uf p q) initial ps1
    uf2 = foldr (\(r,s) uf -> merge uf r s) initial ps2


data UnionFind = UnionFind {tree :: M.IntMap Point, rk :: M.IntMap Rank}

type Point = Int  -- greater than 0
type Rank = Int

initial :: UnionFind
initial = UnionFind (M.singleton 0 0) (M.singleton 0 1)

(!?) :: UnionFind -> Point -> Point
(!?) uf p = M.findWithDefault 0 p (tree uf)

rep :: UnionFind -> Point -> Point
rep uf = untilFix (uf !?)

rank :: UnionFind -> Point -> Rank
rank uf = (rk uf M.!)

isolate :: UnionFind -> Point -> Bool
isolate uf p = rep uf p == 0

merge :: UnionFind -> Point -> Point -> UnionFind
merge uf p1 p2
  | i1 && i2 = UnionFind (M.insert p2 p1 (M.insert p1 p1 (tree uf))) (M.insert p1 2 (rk uf))
  | i1 = UnionFind (M.insert p1 rp2 (tree uf)) (M.insert rp2 (rk2 + 1) (rk uf))
  | i2 = UnionFind (M.insert p2 rp1 (tree uf)) (M.insert rp1 (rk1 + 1) (rk uf))
  | rp1 /= rp2 && rk1 > rk2 = UnionFind (M.insert p2 rp1 (M.insert rp2 rp1 (tree uf))) (M.insert rp1 (rk1 + rk2) (rk uf))
  | rp1 /= rp2 = UnionFind (M.insert p1 rp2 (M.insert rp1 rp2 (tree uf))) (M.insert rp2 (rk1 + rk2) (rk uf))
  | otherwise = uf
  where
    i1 = isolate uf p1
    i2 = isolate uf p2
    rk1 = rank uf rp1
    rk2 = rank uf rp2
    rp1 = rep uf p1
    rp2 = rep uf p2

same :: UnionFind -> Point -> Point -> Bool
same uf p1 p2
  | p1 == p2 = True
  | isolate uf p1 = False
  | otherwise = rep uf p1 == rep uf p2
