不难想到,先枚举建图然后跑最大费用最大流
也不难想到一种将每个数拆成两个点i1,i2,所有满足条件的数之间
把所有满足条件之间的数x,y连边x1--->y2,y1--->x2,流量为1,费用为(x+y)
相当于流量费用都变成了原来的2倍
最后再除一下即可
const inf=;
type node=record
point,flow,cost,next:longint;
end; var edge:array[..] of node;
v:array[..] of boolean;
q:array[..] of longint;
pre,d,cur,p:array[..] of longint;
k,ans,len,a,b,i,j,t:longint; function min(a,b:longint):longint;
begin
if a>b then exit(b) else exit(a);
end; procedure add(x,y,f,c:longint);
begin
inc(len);
edge[len].flow:=f;
edge[len].point:=y;
edge[len].cost:=c;
edge[len].next:=p[x];
p[x]:=len;
end; function gcd(x,y:longint):longint;
begin
if y= then exit(x)
else exit(gcd(y,x mod y));
end; function spfa:boolean;
var i,j,x,y,f,r:longint;
begin
for i:= to t do
d[i]:=-inf;
fillchar(v,sizeof(v),false);
d[]:=;
f:=;
r:=;
q[]:=;
while f<=r do
begin
x:=q[f];
v[x]:=false;
i:=p[x];
while i<>- do
begin
y:=edge[i].point;
if edge[i].flow> then
if d[y]<d[x]+edge[i].cost then
begin
d[y]:=d[x]+edge[i].cost;
pre[y]:=x;
cur[y]:=i;
if not v[y] then
begin
v[y]:=true;
inc(r);
q[r]:=y;
end;
end;
i:=edge[i].next;
end;
inc(f);
end;
if d[t]=-inf then exit(false) else exit(true);
end; function maxcost:longint;
var i,j:longint;
begin
maxcost:=;
while spfa do
begin
i:=t;
while i<> do
begin
j:=cur[i];
dec(edge[j].flow);
inc(edge[j xor ].flow);
i:=pre[i];
end;
ans:=ans+;
inc(maxcost,d[t]);
end;
end; begin
len:=-;
fillchar(p,sizeof(p),);
readln(a,b);
t:=b*+;
for i:=a to b do
begin
for j:=a to i- do
begin
k:=sqr(i)-sqr(j);
if (sqrt(k)=trunc(sqrt(k))) and (gcd(trunc(sqrt(k)),j)=) then
begin
add(i,j+b,,i+j);
add(j+b,i,,-i-j);
add(j,i+b,,i+j);
add(i+b,j,,-i-j);
end;
end;
add(,i,,);
add(i,,,);
add(i+b,t,,);
add(t,i+b,,);
end;
k:=maxcost;
writeln(ans div ,' ',k div );
end.