1 program j01;
2 const times=50;
3 var n:int64;
4 fac:array[0..6000]of int64;
5 num:array[0..6000]of record w,m:int64;end;
6 ans:int64;
7 i,cnt,top:longint;
8
9 procedure sort(l,r:longint);
10 var i,j:longint;x,y:int64;
11 begin
12 i:=l;j:=r;x:=fac[(i+j)div 2];
13 repeat
14 while fac[i]<x do inc(i);
15 while x<fac[j] do dec(j);
16 if i<=j then
17 begin
18 y:=fac[i];fac[i]:=fac[j];fac[j]:=y;
19 inc(i);dec(j);
20 end;
21 until i>j;
22 if i<r then sort(i,r);
23 if l<j then sort(l,j);
24 end;
25
26 function mul(a,b,mo:int64):int64;
27 begin
28 mul:=0;
29 while b>0 do
30 begin
31 if b and 1=1 then mul:=(mul+a)mod mo;
32 b:=b>>1;a:=(a+a)mod mo;
33 end;
34 end;
35
36 function pow(a,i,mo:int64):int64;
37 begin
38 pow:=1;
39 while i>0 do
40 begin
41 if i and 1=1 then pow:=mul(pow,a,mo);
42 i:=i>>1;a:=mul(a,a,mo);
43 end;
44 end;
45
46 function miller_rabin(n:int64):boolean;
47 var i,j:longint;a,x,y,m,k:int64;
48 begin
49 if n=2 then exit(true);
50 m:=n-1;k:=0;
51 while m and 1=0 do
52 begin
53 m:=m>>1;inc(k);
54 end;
55 for i:=1 to times do
56 begin
57 a:=random(n-1)+1;
58 x:=pow(a,m,n);y:=0;
59 for j:=1 to k do
60 begin
61 y:=mul(x,x,n);
62 if(y=1)and(x<>1)and(x<>n-1)then exit(false);
63 x:=y;
64 end;
65 if y<>1 then exit(false);
66 end;
67 exit(true);
68 end;
69
70 function gcd(a,b:int64):int64;
71 begin
72 if b=0 then exit(a) else exit(gcd(b,a mod b));
73 end;
74
75 function rho(n,c:int64):int64;
76 var i,k,x,y,tmp,d:int64;
77 begin
78 i:=1;k:=2;
79 x:=random(n-1)+1;y:=x;
80 while true do
81 begin
82 inc(i);
83 x:=(mul(x,x,n)+c)mod n;
84 tmp:=(y-x+n)mod n;
85 d:=gcd(tmp,n);
86 if(d>1)and(d<n)then exit(d);
87 if y=x then exit(n);
88 if i=k then
89 begin
90 k:=k+k;y:=x;
91 end;
92 end;
93 end;
94
95 procedure find(n:int64);
96 var p:int64;
97 begin
98 if n=1 then exit;
99 if miller_rabin(n) then
100 begin
101 inc(cnt);fac[cnt]:=n;exit;
102 end;
103 p:=n;
104 while p>=n do p:=rho(p,random(n-1)+1);
105 find(p);find(n div p);
106 end;
107
108 begin
109 readln(n);
110 if n=1 then begin writeln(1);halt;end;
111 find(n);
112 sort(1,cnt);
113 top:=1;num[top].w:=fac[1];num[top].m:=1;
114 for i:=2 to cnt do
115 if fac[i]=fac[i-1] then inc(num[top].m) else
116 begin
117 inc(top);num[top].w:=fac[i];num[top].m:=1;
118 end;
119 for i:=1 to top do writeln(num[i].w,' ',num[i].m);
120 end.